博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于FormsAuthentication的用户、角色身份认证
阅读量:6913 次
发布时间:2019-06-27

本文共 3536 字,大约阅读时间需要 11 分钟。

       一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在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如下:

public ActionResult Login(string uname)         {            if (!string.IsNullOrEmpty(uname))             {                //FormsAuthentication.SetAuthCookie(uname,true);                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket                    (   1,                        uname,                        DateTime.Now,                        DateTime.Now.AddMinutes(20),                        true,                        "7,1,8",                        "/"                    );                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,FormsAuthentication.Encrypt(ticket));                cookie.HttpOnly = true;                HttpContext.Response.Cookies.Add(cookie);                return RedirectToAction("UserPage");            }            return RedirectToAction("Index");        }

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

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

 

2、获取认证信息

登录后,在内容页,我们可以通过,当前请求的User.Identity.Name 获取到uname信息,也可以通过读取Request 中的Cookie 解密,获取到Ticket,再从其中获取uname 和 userData (也就是之前存储的角色ID信息)。

ViewData["user"]=User.Identity.Name;                       var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];            var ticket = FormsAuthentication.Decrypt(cookie.Value);            string role = ticket.UserData;            ViewData["role"] = role;            return View();

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

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

当我们在Controller 、Action添加注解属性时候,设置的Role是从哪里得到的呢?因为没有使用基于Membership的那一套authentication,这里我们还要创建一个自定义的RoleProvider 。名称为CustomRoleProvider ,继承自 RoleProvider。这里是在MVCApp下面的Helper文件夹中创建了自己的CustomRoleProvider.cs文件。

RoleProvider中有很多abstract 方法,我们具体只实现其中的GetRolesForUser 方法用于获取用户角色。这里的用户角色,我们可以根据拿到的用户Id从数据库查询,或者拿取Session中存储了的、或是Cookie中存储了的。这里我前面已经把Role存储在Ticket的userData中了,那就从Ticket中获取吧。

    public override string[] GetRolesForUser(string username)        {            var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];            var ticket = FormsAuthentication.Decrypt(cookie.Value);            string role = ticket.UserData;            return role.Split(',');        }

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

[Authorize(Roles="1,2,3")]        public ActionResult Role()         {            ViewData["user"] = User.Identity.Name;            return View();           }

 

P.S.  :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中的比较好。

 

 

 

 

 
分类: 
标签: 

 

 

转载地址:http://usicl.baihongyu.com/

你可能感兴趣的文章
REST接口
查看>>
Dockerfile文件详解
查看>>
使用睿云智合开源 Breeze 工具部署 Kubernetes v1.12.3 高可用集群
查看>>
C++中 int main(int argc, char **argv) 命令行传递参数
查看>>
ORACLE导入、导出所有数据到文件的SQL语句
查看>>
{section}
查看>>
16进制 <--转换--> 10进制(RGB)
查看>>
图的存储结构(邻接矩阵)
查看>>
OD使用教程14(山外有山) - 调试篇14
查看>>
逻辑运算符
查看>>
PE格式详细讲解6(下)- 系统篇06|解密系列
查看>>
POJ-3278-Catch That Cow(BFS)
查看>>
模板:cin.getline用法
查看>>
表单插件——form
查看>>
Oracle 服务命名(别名)的配置及原理,plsql连接用
查看>>
【转】JavaScript 中值得注意的 for 循环
查看>>
【哈佛商评】好编辑成就内容营销
查看>>
【视频】真实的北漂程序员生活记录
查看>>
HTML 获取屏幕、浏览器、页面的高度宽度
查看>>
近日经验总结
查看>>