Web API 身份认证解决方案:Basic基础认证

  • 首先登陆的时候验证用户名、密码,如果登陆成功,则将用户名、密码按照一定的规则生成加密的票据信息Ticket,将票据信息返回到前端,(Web API是默认不开启Session的,需要进配置)
 1 [HttpGet]
 2 public object Login(string strUser, string strPwd){
 3     if (!ValidateUser(strUser, strPwd)){//校验用户名密码(正式环境中应该是数据库校验)
 4         return new { bRes = false };
 5     }
 6     FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, strUser, DateTime.Now,DateTime.Now.AddHours(1), true, 
 7                             string.Format("{0}&{1}", strUser, strPwd),FormsAuthentication.FormsCookiePath);
 8     //返回登录结果、用户信息、用户验证票据信息
 9     var oUser = new UserInfo { bRes = true, UserName = strUser, Password = strPwd, Ticket = FormsAuthentication.Encrypt(ticket) };
10     HttpContext.Current.Session[strUser] = oUser;//将身份信息保存在session中,验证当前请求是否是有效请求
11     return oUser;
12 }
13 public class UserInfo{
14     public bool bRes { get; set; }
15     public string UserName { get; set; }
16     public string Password { get; set; }
17     public string Ticket { get; set; }
18 }

 

  • 发送AngularJS请求的时候将票据信息加入到请求的Head里面,将票据信息随着请求一起发送到服务端去
1 $http.get("/GetAllChargingData", { headers: { 'Authorization': 'BasicAuth ' + $scope.Ticket } }).then(res => { }, () => {})

 

  • 在WebApi服务里面定义一个类,继承AuthorizeAttribute类,然后重写父类的OnAuthorization方法,在OnAuthorization方法里面取到当前http请求的Head,从Head里面取到我们前端传过来的票据信息
  • 解密票据信息,从解密的信息里面得到用户名和密码,然后验证用户名和密码是否正确;如果正确,表示验证通过,否则返回未验证的请求401
 1 public class RequestAuthorizeAttribute: AuthorizeAttribute{
 2     public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext){
 3         //从http请求的头里面获取身份验证信息,验证是否是请求发起方的ticket
 4         var authorization = actionContext.Request.Headers.Authorization;
 5         if ((authorization != null) && (authorization.Parameter != null)){
 6             //解密用户ticket,并校验用户名密码是否匹配
 7             var encryptTicket = authorization.Parameter;
 8             if (ValidateTicket(encryptTicket)){//校验用户名密码(正式环境中应该是数据库校验)
 9                 base.IsAuthorized(actionContext);
10             }else{
11                 HandleUnauthorizedRequest(actionContext);
12             }
13         }else{
14             //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
15             var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
16             bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
17             if (isAnonymous) base.OnAuthorization(actionContext);
18             else HandleUnauthorizedRequest(actionContext);
19         }
20 }
21 private bool ValidateTicket(string encryptTicket){
22     var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;//解密Ticket
23     var index = strTicket.IndexOf("&");//从Ticket里面获取用户名和密码
24     string strUser = strTicket.Substring(0, index);
25     string strPwd = strTicket.Substring(index + 1);
26     if (strUser == "admin" && strPwd == "123456"){
27         return true;
28     }
29     return false;
30
  • 在具体的Api接口或者控制器上增加自定义类的特性[RequestAuthorize]
  • 如果某些方法不想使用验证,使得它可以让匿名用户访问,可以在方法的上面加特性标注[AllowAnonymous](申明该方法运行匿名访问)
 
 
posted @ 2020-08-15 17:51  陨落的星尘  阅读(383)  评论(0编辑  收藏  举报