表单验证(Forms验证)是一个基于票据(ticket-based)[也称为基于令牌(token-based)]的系统。这意味着当用户登录系统以后,他们得到一个包含基于用户信息的票据(ticket)。这些信息被存放在加密过的cookie里面,这些cookie和响应绑定在一起,因此每一次后续请求都会被自动提交到服务器。
当用户请求匿名用户无法访问的ASP.NET页面时,ASP.NET运行时验证这个表单验证票据是否有效。如果无效,ASP.NET自动将用户转到登录页面。这时就该由你来操作了。你必须创建这个登录页面并且验证由登录页面提交的凭证。如果用户验证成功,你只需要告诉ASP.NET架构验证成功(通过调用FormsAuthentication类的一个方法),运行库会自动设置验证cookie(实际上包含了票据)并将用户转到原先请求的页面。通过这个请求,运行库检测到验证cookie中包含一个有效票据,然后赋给用户对这个页面的访问权限。
下面,就是具体的实现。我们先写一个生成用户票据的方法:
//生成Token并保存到Cookies中
private void CreateToken(Models.User user)
{
string json = JsonConvert.SerializeObject(user);
FormsAuthentication.SetAuthCookie(user.UserName.Trim(), true, FormsAuthentication.FormsCookiePath);
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, user.UserName, DateTime.Now, DateTime.Now.AddHours(12), false, json);
Biz126.Cache.SetCookies.AddCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket));
}
其中Biz126.Cache.SetCookies.AddCookie是我自己封装的保存Cookie方法。
生成Token并保存到Cookie中的方法我们已经写好了,只要在登录成功之后直接调用这个方法就可以了。
下面是验证票据,验证票据,我们放在过滤器中进行验证。
新建AuthenticationAttribute类,继承ActionFilterAttribute,重写OnActionExecuting方法:
/// <summary>
/// 检查用户是否有该Action执行的操作权限
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(HttpActionContext filterContext)
{
Models.ResultModel<object> result = new Models.ResultModel<object>();
result.code = -401;
result.message = "请登录后进行操作";
result.status = false;
//如果存在身份信息
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized, result, "application/json");
}
else
{
BLL.IManager manager = new BLL.Manage.Manager();
result = manager.Detail(); //取当前登录的用户信息,进行其他的操作,比如判断有没有权限等,这里省略
//。。。省略掉其他的操作
if (!result.status)
{
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized, result, "application/json");
//filterContext.Result = redirect;
}
}
}
之后,在要在需要用户登录的Action上面,加上[Authentication]就可以了,也可以新加一个控制器,如BaseWebApiController,在这个控制器上加上[Authentication],其他的控制器都继承BaseWebApiController,在不需要验证的Action上加上[AllowAnonymous]就可以了。
下面是通过票据取得用户信息:
if (HttpContext.Current.Request.IsAuthenticated)//是否通过身份验证
{
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];//获取cookie
FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(authCookie.Value);//解密
string json = Ticket.UserData;//反序列化
Models.Models.User user = new Models.User();
try
{
user = JsonConvert.DeserializeObject<Models.User>(json);
result.data = user;
result.message = "success";
result.status = true;
}
catch
{
}
}
还需要在web.config中增加配置:
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Users/Login" timeout="2880" />
</authentication>
</system.web>
到这里,其本上都已经完成了,但是你会发现,在IE上,会有很多用户登录的时候验证不通过的情况,如果记录日志,会发现HttpContext.Current.Request.IsAuthenticated==false
HttpContext.Current.Request.User为空
而且这种情况只有在IE下才会出现,其他的现代浏览器比如Chrome、Firefox等都很正常。
通过网络搜索,大部分都没给出答案来。其他把配置按下面的方法修改,就可以解决这个问题:
<system.web>
<authentication mode="Forms">
<forms cookieless="UseCookies" loginUrl="~/Users/Login" timeout="2880" />
</authentication>
<authorization>
<allow users="*" />
</authorization>
</system.web>
或者是打开服务器的IIS,按下面的步骤修改:
1.打开IIS,选择自己的站点,之后双击IIS中的“身份验证”功能
2.选中Forms身份验证,点击右侧操作区的“编辑”菜单,如果没有启用请先点击“启用”
3.这是Forms身份验证的默认设置,我们需要改动一下
4.按这里修改一下,就可以了。
以上。
本文作者:老徐
本文链接:https://bigger.ee/archives/437.html
转载时须注明出处及本声明