WebApi中的Basic认证
一.步骤
1.通过用户登录获取票据信息Ticket
2.访问WebApi时带上Ticket进行票据信息验证
二.验证过程及代码
1.通过用户登录获取票据信息
根据用户名和密码等一些其它的信息取得生成票据信息,得到Ticket
前端登录部分代码:
var ticket = "";
//登录一次获取Ticket
$("#btnLogin").on("click", function () {
$.ajax({
url: "/userapi/users/Login", type: "GET", data: { "Name": $("#txtName").val(), "Password": $("#txtPassword").val() }, success: function (data) {
var result = JSON.parse(data);
if (result.Result) {
ticket = result.Ticket;//得到Ticket的值
}
else {
alert("failed");
}
}, datatype: "json"
});
});
WebApi后端部分登录获取票据信息代码:
[AllowAnonymous]//不需要验证票据信息,相当于通行证
[HttpGet]
public string Login(string name, string password)
{
if (name.Equals("Admin") && password.Equals("123456"))
{
FormsAuthenticationTicket ticketObject = new FormsAuthenticationTicket(0, name, DateTime.Now,
DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", name, password),
FormsAuthentication.FormsCookiePath);//根据用户信息得到一个Ticket
var result = new { Result = true, Ticket = FormsAuthentication.Encrypt(ticketObject) };//对生成的Ticket进行加密
return JsonConvert.SerializeObject(result);
}
else
{
var result = new { Result = false };
return JsonConvert.SerializeObject(result);
}
}
2.访问WebApi时带上Ticket进行票据信息验证
访问api前端部分代码:
$("#btnGet").on("click", function () {
$.ajax({
url: "/userapi/users/GetUserByName", type: "get", data: { "username": "Superman" },
beforeSend: function (XHR) { //XHR:XML Http Request
//发送ajax请求之前向http的head头里面带上Ticket信息
XHR.setRequestHeader('Authorization', 'BasicAuth ' + ticket);//这里有个坑:Authorization中有两个属性:1.Parameter参数 2.Scheme组合名称 要这两个都不为空,则Scheme名称+空格+Parameter参数才行,不加空格则默认为Scheme组合名称,parameter则为null
},
success: function (data) {
alert(data);
}, datatype: "json"
});
});
在这里我们需要对自带的AuthorizeAttribute特性进行扩展,根据自己的WebApi项目设计在合适的位置添加一个BasicAuthorizeAttribute类(名称随意,规范就行),需要继承AuthorizeAttribute,下面用代码展示:
public class BasicAuthorizeAttribute : AuthorizeAttribute//继承自带的特性验证
{
/// <summary>
/// 访问api前进来完成验证
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var authorization = actionContext.Request.Headers.Authorization;//获取在head中设置的Authorization信息
//检查方法和控制器上是否有AllowAnonymousAttribute这个特性,有的话直接可以访问,不需要验证
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0
|| actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0)
{
base.OnAuthorization(actionContext);//有AllowAnonymousAttribute特性才能正确的访问方法
}
else if (authorization != null && authorization.Parameter != null)
{
//用户验证逻辑
if (ValidateTicket(authorization.Parameter))
{
base.IsAuthorized(actionContext);//正确的访问方法
}
else
{
this.HandleUnauthorizedRequest(actionContext);//没有权限,返回一个Unauthorized状态码,没有授权
}
}
else
{
this.HandleUnauthorizedRequest(actionContext);//没有权限
}
}
/// <summary>
/// 没有访问权限的信息返回
/// </summary>
/// <param name="actionContext"></param>
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);//告诉浏览器需要授权验证:401 Unauthorized
//challengeMessage.Headers.Add("WWW-Authenticate", "Basic");//权限信息放在basic
base.HandleUnauthorizedRequest(actionContext);//返回没有授权的信息
}
/// <summary>
/// 权限验证
/// </summary>
/// <param name="encryptTicket">加密后的Ticket信息</param>
/// <returns></returns>
private bool ValidateTicket(string encryptTicket)
{
var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;//解密Ticket
return string.Equals(strTicket, string.Format("{0}&{1}", "Admin", "123456"));
//应该分拆后去数据库验证
//过期还没有验证
}
}
接下来我们把需要验证的控制器或者方法上加上BasicAuthorizeAttribute特性即可验证,在需要放行的方法加上AllowAnonymousAttribute即可不验证
天行健,君子以自强不息。

浙公网安备 33010602011771号