当前位置: 移动技术网 > IT编程>软件设计>架构 > 浅谈基于FormsAuthentication的认证

浅谈基于FormsAuthentication的认证

2019年04月05日  | 移动技术网IT编程  | 我要评论
一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到 Session中存储的用户基本信息,查看比较他有没有登录和能否访问当前页面。 Session的原理,也就是在服务器端生成一个SessionID对应了存储的用户数据 ...

一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在session中,以后用户每次请求页面或接口数据的时候,拿到

session中存储的用户基本信息,查看比较他有没有登录和能否访问当前页面。

       session的原理,也就是在服务器端生成一个sessionid对应了存储的用户数据,而sessionid存储在cookie中,客户端以后每次请求都会带上这个

cookie,服务器端根据cookie中的sessionid找到存储在服务器端的对应当前用户的数据。

       formsauthentication是微软提供给我们开发人员使用,做身份认证使用的。通过该认证,我们可以把用户name 和部分用户数据存储在cookie中,

通过基本的条件设置可以,很简单的实现基本的身份角色认证。

       这里要实现的效果是:在不使用membership的情况下,使用系统提供的authorize 实现基于角色的访问控制。

1、创建认证信息 ticket 

  在用户登录以后,把用户的id和对应的角色(多个角色用,分隔),存储在ticket中。

  使用formsauthentication.encrypt 加密票据。

  把加密后的ticket 存储在response cookie中(客户端js不需要读取到这个cookie,所以最好设置httponly=true,防止浏览器攻击窃取、伪造cookie)。这样下次可以从request cookie中读取了。

  一个简单的demo如下:

 1 public actionresult login(string uname) 
 2         {
 3             if (!string.isnullorempty(uname)) 
 4             {
 5                 //formsauthentication.setauthcookie(uname,true);
 6                 formsauthenticationticket ticket = new formsauthenticationticket
 7                     (   1,
 8                         uname,
 9                         datetime.now,
10                         datetime.now.addminutes(20),
11                         true,
12                         "7,1,8",
13                         "/"
14                     );
15                 var cookie = new httpcookie(formsauthentication.formscookiename,formsauthentication.encrypt(ticket));
16                 cookie.httponly = true;
17                 httpcontext.response.cookies.add(cookie);
18 
19                 return redirecttoaction("userpage");
20             }
21             return redirecttoaction("index");
22         }

这里formsauthenticationticket 第六个参数存储的是string 类型的userdata ,这里就存放当前用户的角色id,以英文逗号分隔。

当使用用户名 “测试” 登录后,客户端就会出现这样一条记录cookie

 

2、获取认证信息

登录后,在内容页,我们可以通过,当前请求的user.identity.name 获取到uname信息,也可以通过读取request 中的cookie 解密,获取到ticket,再从其中获取uname 和 userdata (也就是之前存储的角色id信息)。

1 viewdata["user"]=user.identity.name;
2            
3             var cookie = request.cookies[formsauthentication.formscookiename];
4             var ticket = formsauthentication.decrypt(cookie.value);
5             string role = ticket.userdata;
6 
7             viewdata["role"] = role;
8             return view();

3、通过注解属性,实现权限访问控制

在web.config中配置启用form认证 和 角色管理

1 <authentication mode="forms">
2       <forms loginurl="~/login/index" timeout="2880" />
3     </authentication>
4     <rolemanager enabled="true" defaultprovider="customroleprovid">
5       <providers>
6         <clear/>
7         <add name="customroleprovid" type="mvcapp.helper.customroleprovider"/>
8       </providers>
9     </rolemanager>

当我们在controller 、action添加注解属性时候,设置的role是从哪里得到的呢?因为没有使用基于membership的那一套authentication,这里我们还要创建一个自定义的roleprovider 。名称为customroleprovider ,继承自 roleprovider。这里是在mvcapp下面的helper文件夹中创建了自己的customroleprovider.cs文件。

roleprovider中有很多abstract 方法,我们具体只实现其中的getrolesforuser 方法用于获取用户角色。这里的用户角色,我们可以根据拿到的用户id从数据库查询,或者拿取session中存储了的、或是cookie中存储了的。这里我前面已经把role存储在ticket的userdata中了,那就从ticket中获取吧。

1 public override string[] getrolesforuser(string username)
2         {
3             var cookie = httpcontext.current.request.cookies[formsauthentication.formscookiename];
4             var ticket = formsauthentication.decrypt(cookie.value);
5             string role = ticket.userdata;
6             return role.split(',');
7         }

在需要,验证的controller、action上面添加注解属性,比如这个action 只允许roleid 为包含1或2或3的访问,而当前用户roleid为(7、1、8)就是用户有权访问了。

1  [authorize(roles="1,2,3")]
2         public actionresult role() 
3         {
4             viewdata["user"] = user.identity.name;
5             return view();   
6         }

注:1、ticket存储在在cookie过期时间,和关闭浏览器是否在记住当前票据,在formsauthenticationticket实例化时候可以设置参数,

  2、role 的获取可以不要存储在ticket 的userdata中,可以直接从数据库读取,userdata可以存储其他信息。

  3、要想灵活配置controller 和action的 允许访问的role 可以自定义authorizeattribute  override里面的onauthorization方法,在该方法中

      读取当前页面允许访问的角色id,根据当前用户的roleid,进行检查。这样也就实现了,role的灵活配置。

       4、ticket中的信息,最终还是存储在cookie中,安全性方面还是自己斟酌吧,个人觉得还是把userid和roleid存储在session中的比较好。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网