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

    <authentication mode="Forms">
<forms loginUrl="~/Login/Index" timeout="2880" />
</authentication>
<roleManager enabled="true" defaultProvider="CustomRoleProvid">
<providers>
<clear/>
<add name="CustomRoleProvid" type="MvcApp.Helper.CustomRoleProvider"/>
</providers>
</roleManager>

当我们在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中的比较好。

基于FormsAuthentication的用户、角色身份认证(转)的更多相关文章

  1. 基于token的多平台身份认证架构设计

    基于token的多平台身份认证架构设计 1   概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格 ...

  2. 基于FormsAuthentication的用户、角色身份认证

    一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到 Session中存储的用户基本信息,查看比较他有没有登录和能否 ...

  3. WebApi 基于token的多平台身份认证架构设计

    1   概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格局 . 不同的客户端产生了不同的用户使用 ...

  4. 基于Token的多平台身份认证价格设计

    1   概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格局 . 不同的客户端产生了不同的用户使用 ...

  5. 基于ASP.MVC票据FormsAuthenticationTicket身份认证

    做一个最基础的业务需求用户登录,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访 ...

  6. 基于session和token的身份认证方案

    一.基于session的身份认证方案 1.方案图示 2.比较通用的鉴权流程实现如下: 在整个流程中有两个拦截器. 第一个拦截器AuthInteceptor是为了每一次的请求的时候都先去session中 ...

  7. 无状态http协议上用户的身份认证

    1.注册时可以使用手机短信验证码进行身份认证 2.用户每次请求不能每次都发送验证码,这时需要服务器给客户端颁发一个身份凭证(一般为一个唯一的随机数),用户每次请求时都携带身份凭证, 服务器会记录该身份 ...

  8. 基于前后端分离的身份认证方式——JWT

    什么是JWT JWT--Json web token 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态.分布式的Web应用授权. 现在一般都用redis来出来token做 ...

  9. 【mongodb用户和身份认证管理】

    admin系统库用户管理 #移除 #查看 特定的数据库用户管理 #添加 #修改密码

随机推荐

  1. 算法(Algorithms)第4版 练习 1.3.2

    was best times of the was the it (1 left on stack)

  2. python中字符串使用需要注意的地方

    1. r''的使用 'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子 2. u''的使用 引号之前加上字母u时,python会将 ...

  3. linux 压缩和归档

    在linux下有几种压缩方式:gzip.bzip2.xz.zip gzip 压缩文件以.gz结尾, 只能压缩文件,不能压缩目录 用法: gzip:/path/to/somefile   用来压缩,完成 ...

  4. Thinkphp跨模块调用视图文件

    当需要跨模块调用视图文件时,需要使用被包含文件的完整路径,如: <include file="./App/Home/View/Store/header.html"/> ...

  5. request.post(2种格式)

  6. 仿联想商城laravel实战---1、仿联想商城需求和数据库设计(lavarel如何搭建项目)

    仿联想商城laravel实战---1.仿联想商城需求和数据库设计(lavarel如何搭建项目) 一.总结 一句话总结: composer引入lavarel.配置域名.配置apache 1.项目名 le ...

  7. Delphi中TList类应用

    在DELPHI中指针最常见的就是和类TLIST结合起来使用.下面是一个很简单的例子,希望对这个例子的分析能让大家对使用TLIST类有一个简单的认识. 代码的功能是使用指针和Tlist来生成一个牌串,并 ...

  8. appium-环境搭建(一)

    adb命令 adb的全称为Android Debug Bridge,就是起到调试桥的作用.借助adb工具,我们可以管理设备或者手机模拟器的状态.还可以进行很多手机操作,如安装软件\系统升级\运行she ...

  9. PHP使用http_build_query()构造URL字符串的方法

    http_build_query http_build_query -- 生成 url-encoded 之后的请求字符串描述string http_build_query ( array formda ...

  10. 【leetcode刷题笔记】ZigZag Conversion

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...