.net MVC使用IPrincipal进行Form登录即权限验证(3)

.net MVC使用IPrincipal进行Form登录即权限验证,供大家参考,具体内容如下

1.在MVC项目中添加用户类,可以根据实际项目需求添加必要属性

public class UserData
 {
 /// <summary>
 /// ID
 /// </summary>
 public int UserId { get; set; }

 /// <summary>
 /// 用户名
 /// </summary>
 public string UserName { get; set; }

 /// <summary>
 /// 角色ID列表
 /// </summary>
 public List<int> Roles { get; set; }
 }

2.添加类Principal实现IPrincipal接口

public class Principal : IPrincipal
 {
 public IIdentity Identity { get; private set;}

 public UserData Account { get; set; }

 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="ticket"></param>
 /// <param name="account"></param>
 public Principal(FormsAuthenticationTicket ticket, UserData account)
 {
  if (ticket == null)
  throw new ArgumentNullException("ticket");
  if (account == null)
  throw new ArgumentNullException("UserData");

  this.Identity = new FormsIdentity(ticket);
  this.Account = account;
 }

 public bool IsInRole(string role)
 {
  if (string.IsNullOrEmpty(role))
  return true;
  if (this.Account == null || this.Account.Roles == null)
  return false;
  return role.Split(',').Any(q => Account.Roles.Contains(int.Parse(q)));
 }
 }

IPrincipal接口有对象Identity已经需要实现验证角色方法IsInRole()。在我们的实现类中添加了"用户信息(UserData)"属性Account。

构造函数中进行了初始化,第一个对象为Form验证的票据对象,下面ticket会携带用户信息一起保存进cookie中。

3.创建存储cookie和读取cookie的类

/// <summary>
 /// 写入cookie和读取cookie
 /// </summary>
 public class HttpFormsAuthentication
 {
 //将用户信息通过ticket加密保存到cookie
 public static void SetAuthenticationCoolie(UserData account, int rememberDay = 0)
 {
  if (account == null)
  throw new ArgumentNullException("account");

  //序列化account对象
  string accountJson = JsonConvert.SerializeObject(account);
  //创建用户票据
  var ticket = new FormsAuthenticationTicket(1, account.UserName, DateTime.Now, DateTime.Now.AddDays(rememberDay), false, accountJson);
  //加密
  string encryptAccount = FormsAuthentication.Encrypt(ticket);

  //创建cookie
  var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptAccount)
  {
  HttpOnly = true,
  Secure = FormsAuthentication.RequireSSL,
  Domain = FormsAuthentication.CookieDomain,
  Path = FormsAuthentication.FormsCookiePath
  };

  if (rememberDay > 0)
  cookie.Expires = DateTime.Now.AddDays(rememberDay);

  //写入Cookie
  HttpContext.Current.Response.Cookies.Remove(cookie.Name);
  HttpContext.Current.Response.Cookies.Add(cookie);
 }

 //获取cookie并解析出用户信息
 public static Principal TryParsePrincipal(HttpContext context)
 {
  if (context == null)
  throw new ArgumentNullException("context");
  HttpRequest request = context.Request;
  HttpCookie cookie = request.Cookies[FormsAuthentication.FormsCookieName];
  if (cookie == null || string.IsNullOrEmpty(cookie.Value))
  {
  return null;
  }
  //解密coolie值
  FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

  UserData account = JsonConvert.DeserializeObject<UserData>(ticket.UserData);
  return new Principal(ticket, account);
 }

 }

存储cookie时将用户信息序列化后的字符串accountJson由ticket其携带加密后保存入cookie中,具体的accountJson被赋值给FormsAuthenticationTicket的UserData属性。

可看到解析时将ticket.UserData反序列化后得到了原始的用户信息对象,然后生成Principal对象。

解析cookie得到Principal对象的方法TryParsePrincipal,下面会在发起请求时用到,而返回的Principal对象被赋值给HttpContext.User。

4.在Global.asax中注册Application_PostAuthenticateRequest事件,保证权限验证前将cookie中的用户信息取出赋值给User

protected void Application_PostAuthenticateRequest(object sender, System.EventArgs e)
 {
  HttpContext.Current.User =
  HttpFormsAuthentication.TryParsePrincipal(HttpContext.Current);
 }

5.集成AuthorizeAttribute特性类并重写AuthorizeCore,HandleUnauthorizedRequest方法

public class FormAuthorizeAttribute : AuthorizeAttribute
 {
 /// <summary>
 /// 先进入此方法,此方法中会调用 AuthorizeCore 验证逻辑,验证不通过会调用 HandleUnauthorizedRequest 方法
 /// </summary>
 /// <param name="filterContext"></param>
 public override void OnAuthorization(AuthorizationContext filterContext)
 {
  base.OnAuthorization(filterContext);
 }

 /// <summary>
 /// 权限验证
 /// </summary>
 /// <param name="httpContext"></param>
 /// <returns></returns>
 protected override bool AuthorizeCore(HttpContextBase httpContext)
 {
  var user = httpContext.User as Principal;
  if (user != null)
  return user.IsInRole(base.Roles);
  return false;
 }

 protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
 {
  //验证不通过,直接跳转到相应页面,注意:如果不是哟娜那个以下跳转,则会继续执行Action方法
  filterContext.Result = new RedirectResult("~/Login/Index");
 }
 }

AuthorizeCore与HandleUnauthorizedRequest方法均是在方法OnAuthorization中调用,AuthorizeCore验证不通过才会调用HandleUnauthorizedRequest方法。

将验证代码在AuthorizeCore中实现,验证不通过的逻辑在HandleUnauthorizedRequest方法中实现。

6.添加LoginController实现登录逻辑

namespace MVCAuthorizeTest.Controllers
{
 public class LoginController : Controller
 {
 [AllowAnonymous]
 // GET: Login
 public ActionResult Index(string returnUrl)
 {
  ViewBag.ReturnUrl = returnUrl;
  return View();
 }

 [HttpPost]
 [AllowAnonymous]
 public ActionResult Index(string name, string password, bool rememberMe, string returnUrl)
 {
  var account = new UserData()
  {
  UserName = name,
  UserId = 110,
  Roles = new List<int>() { 1, 2, 3 }
  };
  HttpFormsAuthentication.SetAuthenticationCoolie(account, rememberMe ? 7 : 0);
  if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
  {
  return Redirect(returnUrl);
  }
  else
  {
  return RedirectToAction("Index", "Home");
  }
 }

 // POST: /Account/LogOff
 [HttpPost]
 public ActionResult LogOff()
 {
  System.Web.Security.FormsAuthentication.SignOut();
  return RedirectToAction("Index", "Home");
 }
 }
}

7.对需要验证的controller或action添加特性标签

 [FormAuthorize(Roles = "1,2")]
 public class HomeController : Controller
 {
 [FormAuthorize]
 public ActionResult Index()
 {
  return View();
 }
 }

如图

8.在添加FilterConfig中添加全局注册filter,减少每个action分别设置。如果有不需要验证的页面,添加[AllowAnonymous]特性即可

public class FilterConfig
 {
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
 filters.Add(new HandleErrorAttribute());
 //全局注册filter
 filters.Add(new FormAuthorizeAttribute());
 }
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统之前端页面框架构建源码分享
  • asp.net CommunityServer中的wwwStatus
  • .Net Core简单使用Mvc内置的Ioc(续)
  • .Net Core简单使用Mvc内置的Ioc
  • Spring.Net控制反转IoC入门使用
  • ASP.NET Core应用中与第三方IoC/DI框架的整合
  • MVC使用Spring.Net应用IOC(依赖倒置)学习笔记3
  • .net MVC使用Session验证用户登录(4)
  • .NET Unity IOC框架使用实例详解
(0)

相关推荐

  • .Net Core简单使用Mvc内置的Ioc(续)

    本文基于 .NET Core 2.0. 上一章<[.Net Core] 简单使用 Mvc 内置的 Ioc>已经对日常 Mvc 中的 Ioc 的简单用法进行了说明,此外还有一些需要补充的内容. 接下来会围绕着这些疑问进行回答:AOP 中 Filter 和 Ioc 的结合使用是啥样子的呢? 怎样直接获取 Ioc 中的实例对象,而不是以构造函数的方式进行获取呢? 目录 场景一:Ioc 结合过滤器 Filter 使用 场景二:直接获取 Ioc 管理的对象 场景一:Ioc 结合过滤器 Filter 使用

  • asp.net CommunityServer中的wwwStatus

    wwwStatus (default = Remove) Three supported values: Require, Remove, Ignore Require validates the current Url uses www. (ie, http://www.communityserver.org) Remove validates the current Url does not contain www. Ignore does not validate the request

  • ASP.NET Core应用中与第三方IoC/DI框架的整合

    一.ConfigureServices方法返回的ServiceProvider没有用! 我们可以通过一个简单的实例来说明这个问题.我们先定义了如下这个一个MyServiceProvider,它实际上是对另一个ServiceProvider的封装.简单起见,我们利用一个字典来保存服务接口与实现类型的映射关系,这个关系可以通过调用Registe方法来注册.在提供服务实例的GetService方法中,如果提供的服务类型已经被注册,我们会创建并返回对应的实例对象,否则我们将利用封装的这个ServiceP

  • .NET Unity IOC框架使用实例详解

    .NET Unity IOC框架的使用实例,具体内容如下 1.IOC简介 IOC(Inversion of Control), 控制反转 DI (Dependency Injection),依赖注入 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. 2.Unity引入 3.创建单例模式容器类 using Microsoft.Practices.Unity; using Microsoft

  • ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统之前端页面框架构建源码分享

    开始,我们有了一系列的解决方案,我们将动手搭建新系统吧. 用户的体验已经需要越来越注重,这次我们是左右分栏,左边是系统菜单,右边是一个以tabs页组成的页面集合,每一个tab都可以单独刷新和关闭,因为他们会是一个iframe 工欲善其事必先利其器.需要用到以下工具. Visual Studio 2012 您可以安装MVC4 for vs2010用VS2010来开发,但是貌似你将不能使用EF5.0将会是EF4.4版本,但这没有多大的关系. MVC4将挂载在.NET Framework4.5上. 好

  • MVC使用Spring.Net应用IOC(依赖倒置)学习笔记3

    到现在,我们已经基本搭建起了项目的框架,但是项目中还存在一个问题,就是尽管层与层之间使用了接口进行隔离,但实例化接口的时候,还是引入了接口实现类的依赖,如下面的代码: private IUserService _userService; private IUserService UserService { get { return _userService ?? (_userService = new UserService()); } set { _userService = value; }

  • Spring.Net控制反转IoC入门使用

    Spring.Net包括控制反转(IoC) 和面向切面(AOP),这篇文章主要说下IoC方面的入门. 一.首先建立一个MVC项目名称叫SpringDemo,然后用NuGet下载spring(我用的是Spring.Net NHibernate 4 support) 二.类设计,在Models文件夹下面建立类,主要IUserInfo,UserInfo,Order 三个类代码如下: public interface IUserInfo { string ShowMeg(); } public clas

  • .Net Core简单使用Mvc内置的Ioc

    本文基于 .NET Core 2.0. 鉴于网上的文章理论较多,鄙人不才,想整理一份 Hello World(Demo)版的文章. 目录 场景一:简单类的使用 场景二:包含接口类的使用 场景三:涉及引用类库的使用 场景一:简单类的使用 类 DemoService.cs: public class DemoService { public string Test() { return Guid.NewGuid().ToString(); } } 控制器 DemoController.cs: pub

  • .net MVC使用Session验证用户登录(4)

    用最简单的Session方式记录用户登录状态 1.添加DefaultController控制器,重写OnActionExecuting方法,每次访问控制器前触发 public class DefaultController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); va

  • .net MVC使用IPrincipal进行Form登录即权限验证(3)

    .net MVC使用IPrincipal进行Form登录即权限验证,供大家参考,具体内容如下 1.在MVC项目中添加用户类,可以根据实际项目需求添加必要属性 public class UserData { /// <summary> /// ID /// </summary> public int UserId { get; set; } /// <summary> /// 用户名 /// </summary> public string UserName

  • SpringBoot基于SpringSecurity表单登录和权限验证的示例

    一.简介 上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的拦截器过滤器换成了基于SpringSecurity来做,其中遇到了很多坑,总结下,大家有遇到类似问题的话就当是为大家闭坑吧. 二.项目实现功能和成果展示 首先来看下登录界面:这是我输入的一个正确的信息,点击登录后SpringSecurity会根据你输入的用户名和密码去验证是否正确,如果正确的话就去你定义的页面,我这里定义的是查询教师信息页面.来看下代码吧. 三.准备工作(前台页面.实体类) 实体类Teac

  • vue登录以及权限验证相关的实现

    关键词:前后端分离.jwt.登录.权限验证 最近在做一个小应用,需要用到vue实现登录,以及给不同路由设置权限.在网上看了很多文章,讲的是乱七八糟.感叹国内技术类文章实在是差劲,抄来抄去.这篇文章就说说我最后是如何实现的. 前后端分离项目中,后端提供api接口给前端,使用jwt发放权限. 首先前端提供用户名和密码请求登录接口,后端验证之后返回给前端一个token,之后前端在请求需要权限的接口时携带这个token就可以了. 两个问题 现在面临两个问题, 首先vue中不同的路由有不同的权限,比如我要

  • Vue+Express实现登录状态权限验证的示例代码

    前提 对Vue全家桶有基本的认知. 用有node环境 了解express 另外本篇只是介绍登录状态的权限验证,以及登录,注销的前后端交互.具体流程(例如:前端布局,后端密码验证等).以后有时间再对这些边边角角进行补充 一丶业务分析 1.什么情况下进行权限验证? 访问敏感接口 前端向后端敏感接口发送ajax 后端进行session验证,并返回信息 前端axios拦截返回信息,根据返回信息进行操作 进行页面切换 页面切换,触发vue-router的路由守卫 路由守卫根据跳转地址进行验证,如需权限,则

  • Asp.Mvc 2.0实现用户登录与注销功能实例讲解(2)

    这一节讲解下ASP.MVC 2.0的用户登录与注销功能,先讲登录,后说注销.我们这个系列讲的用户登录方式都是FORM表单验证方式.在讲之前先给大家说下<%:%>的功能,<%:%>与<%=%>功能一样,用来动态输出内容. 一.登录 1. 建立MODEL 登录的时候,我们一般只要验证用户名和密码,还有是否保存登录COOKIE,所以我们建立一个MODEL登录类,只需包括3个字段就可以. /// <summary> /// 用户登录MODEL /// </su

  • jsp+dao+bean+servlet(MVC模式)实现简单用户登录和注册页面

    功能介绍 本项目通过使用jsp和servlet实现简单的用户登录.主要逻辑为: 如果用户不存在,则首先进行注册(注册信息同步到数据库中). 进行注册后,可进入登录页面对账号进行登录. 如果账号存在,则正确跳转到欢迎界面,否则提示用户账号信息输入错误. 用户进行登录页面时需要填写验证码同时可勾选是否两周内免登陆. 用户进入欢迎界面,则会显示这是用户第几次登录,如果不是第一次登录则会显示上次登录时间. 如果用户直接进入welcome,(没有进行登录,直接打开welcome.jsp)则会跳转到登录页面

  • ASP.NET在MVC控制器中获取Form表单值的方法

    本文实例讲述了ASP.NET在MVC控制器中获取Form表单值的方法.分享给大家供大家参考,具体如下: 在MVC控制器中,如果我们想直接获取表单中某个标签元素的值,可以使用MVC中提供的FormCollection类,具体用法如下所示: 视图部分: @using (Html.BeginForm()) { <text>您输入的值是:</text><span>@ViewBag.FormValue</span> <input type="text&

  • 详解使用Spring3 实现用户登录以及权限认证

    使用Spring3 实现用户登录以及权限认证 这里我就简单介绍一下,我在实现的时候处理的一些主要的实现. 1.用户登录 <form action="loginAction.do" method="post"> <div class="header"> <h2 class="logo png"></h2> </div> <ul> <li><

  • Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码

    1.用户登录 验证用户是否登录成功步骤直接忽略,用户登录成功后怎么保存当前用户登录信息(session,cookie),本文介绍的是身份验证(其实就是基于cookie)的,下面看看代码. 引入命名空间 using System.Web.Security; 复制代码 代码如下: Users ModelUser = new Users() { ID = 10000, Name = UserName, UserName = UserName, PassWord = PassWord, Roles =

  • jquery登录的异步验证操作示例

    本文实例讲述了jquery登录的异步验证操作.分享给大家供大家参考,具体如下: //定义一个json var validate = { username : false, pwd : false, pwded : false, verify : false, loginUsername : false, loginPwd :false } //存储错误信息 var $msg = ""; //验证注册表单 $(function(){ //获取表单对象 var register = $('

随机推荐