浅谈基于FormsAuthentication的认证

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

View Code

这里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();

View Code

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>

View Code

当我们在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         }

View Code

在需要,验证的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         }

View Code

注: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中的比较好。

(0)

相关推荐

  • 单点登录简介

    单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录. 当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对 ...

  • 【优秀成果】浅谈基于地理核心素养视角下的研学旅行——以哈尔滨市为例

    摘要:地理核心素养作为地理课程教育的核心目标,从多个方面对地理教学工作提出了具体的标准和要求,为地理教学工作提供了更加清晰的指导和方向.研学旅行作为课堂的拓展与延伸,通过让师生实地观察,应用实践,参与 ...

  • 浅谈基于模型的系统工程(MBSE)技术

    MBSE 概念‍ 国际系统工程学会(INCOSE)在<系统工程2020年愿景>中,给出MBSE技术的定义:基于模型的系统工程是对系统工程活动中建模方法应用的正式认同,以使建模方法支持系统要 ...

  • 干货 | 浅谈基于模型的工艺评审

    摘要 市场激烈竞争不但要求企业提供物美价廉的产品,而且要不断提高质量.降低成本.竞争能力的本质是技术能力和管理水平的竞争.现代产品的构造和功能越来越复杂,在保证产品性能.质量要求的前提下,如何降低制造 ...

  • 浅谈基于发展学生核心素养的校本课程中传统文化的合理传承

    摘 要:国家课程.地方课程.校本课程的三级课程管理方式为传统文化进课堂提供了可能,优秀传统文化在发展学生核心素养方面的有着积极的作用.传统文化校本课程的开展是需要经历精心选材.科学实施的. 关键词:德 ...

  • 浅谈基于IaaS公有云的中小型企业基础安全建设

    背景 互联网数据中心(IDC)属于互联网基础设施范畴的一个细分领域.为企业.金融机构等提供一个存放服务器的空间场所,随着科技技术的发展,IDC也经历了一个又一个的里程碑,如下图是:摘自<美国数据 ...

  • 基于胡希恕经方医学浅谈三二四三辨证法则与应用

    引言: 我19岁就开始念伤寒,我今年差不多80多了,那我也不知道有多少个改变,就读这个东西,你要不是这个整个看问题,那没个明白---胡希恕先生 这个辩证法的宇宙观,主要地就是教导人们要善于去观察和分析 ...

  • 基于综合服务平台浅谈Sass应用

    一.       前言 CSS不是一种编程语言,只是单纯的一行行的描述,没有逻辑没有变量,因此写CSS对于习惯于运用逻辑思维编码的程序员来说是一件很头疼的事.于是勤奋的程序员就开始运转他们敏捷的大脑, ...

  • 浅谈乡村治理模式发生了哪些变化?

    随着乡村现代化的发展,越来越多的乡村走上了建设数字乡村的道路,从传统的乡村治理到使用互联网数字化治理的模式,乡村的风貌和农民的生活也发生了巨大的变化,接下来就让我们一起来了解一下乡村治理模式到底发生了 ...

  • 汽车是怎么开发出来的?浅谈汽车开发流程

    许良  汽车话题下的优秀答主你知道汽车是怎么开发出来的吗?你的脑海中很可能浮现出来这样一个画面:一个非常有艺术气息的设计师,在草图上帅气的描绘着看起来非常犀利的线条.对,但不全对.对于汽车工程师的我而 ...