- 首先登陆的时候验证用户名、密码,如果登陆成功,则将用户名、密码按照一定的规则生成加密的票据信息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](申明该方法运行匿名访问)