ASP.NET MVC5(五):身份验证、授权
使用Authorize特性进行身份验证
通常情况下,应用程序都是要求用户登录系统之后才能访问某些特定的部分。在ASP.NET MVC中,可以通过使用Authorize特性来实现,甚至可以对整个应用程序全局使用Authorize特性。
Authorize的用法
本节以一个添加产品的示例来说明Authorize的使用方法。首先,创建Product类、添加属性(如下所示)并创建ProductsController(MVC5 Controller with views,using Entity Framework)。
public class Product
{
//产品编号
public int Id { get; set; }
//产品名称
public string ProductName { get; set; }
//产品描述
public string Description { get; set; }
//产品价格
public decimal Price { get; set; }
}
运行程序,将Url定位到/Products/Create,添加如下产品。

此时收到用户需求,必须是已经登录的用户才可以添加产品,如匿名用户请求访问产品创建页面,则直接定位到登录界面。修改ProdutsController,只需要在Create动作上添加Authorize特性。
[Authorize]
public ActionResult Create()
{
return View();
}
这时,我们在未登录状态下请求访问产品创建页面时,系统自动跳转到登录页面。下面,我们来看一看Authorize特性的的工作原理。当用户请求一个Action时,会调用OnAuthorization方法:
public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
{
// If a child action cache block is active, we need to fail immediately, even if authorization
// would have succeeded. The reason is that there's no way to hook a callback to rerun
// authorization before the fragment is served from the cache, so we can't guarantee that this
// filter will be re-run on subsequent requests.
throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
}
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);
if (skipAuthorization)
{
return;
}
if (AuthorizeCore(filterContext.HttpContext))
{
// ** IMPORTANT **
// Since we're performing authorization at the action level, the authorization code runs
// after the output caching module. In the worst case this could allow an authorized user
// to cause the page to be cached, then an unauthorized user would later be served the
// cached page. We work around this by telling proxies not to cache the sensitive page,
// then we hook our custom authorization code into the caching mechanism so that we have
// the final say on whether a page should be served from the cache.
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else
{
HandleUnauthorizedRequest(filterContext);
}
}
skipAuthorization代表是否跳过验证,如果Action或Controller定义了AllowAnonymous特性,则跳过验证。若不跳过验证,则会判断AuthorizeCore方法的执行结果,再来看看AuthorizeCore方法的源码:
protected virtual bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
}
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
{
return false;
}
return true;
}
如果用户没有登录,则返回False;如果用户组长度大于0且不包括当前用户,则返回False;如果授权角色长度大于0且不包含当前用户,返回False;否则返回True 。
★Authorize特性不仅可以用在Action上,同样可以使用在Controller上
全局授权过滤器
对于大部分网站而言,基本上整个应用程序都需要身份验证,当然我们不可能在每个控制器上添加Authorize特性。此时,把AuthorizeAttribute配置为全局过滤器,并使用AllowAnonymous特性来允许匿名访问某些控制器或方法。修改App_Start/FilterConfig.cs文件中的RegisterGlobalFilters方法:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizeAttribute());
filters.Add(new HandleErrorAttribute());
}
注意,在AccountController中的Login方法,系统已经帮我们添加了AllowAnonymous特性,不然是无法正常登陆的。
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
##授权
使用Authorize特性限定用户或角色的访问
目前为止,已经介绍了使用Authorize特性禁止匿名用户访问控制器或方法。同样的,我们也可以使用Authorize特性来限定特定用户或角色的访问。上一节中的示例,新增只有Administrator角色用户才能够编辑产品的功能。
[Authorize(Roles ="Administrator")]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
当然,我们也可以通过指定用户的方式来限定访问:
[Authorize(Users = "Jack,Mike,July")]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
ASP.NET MVC5(五):身份验证、授权的更多相关文章
- 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
原文:使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)--第1部分 原文链接:https://www.codeproject.com/Articles/5160941/ASP- ...
- 也谈Asp.net 中的身份验证
钱李峰 的这篇博文<Asp.net中的认证与授权>已对Asp.net 中的身份验证进行了不错实践.而我这篇博文,是从初学者的角度补充了一些基础的概念,以便能有个清晰的认识. 一.配置安全身 ...
- asp.net的forms身份验证 单用户身份验证
asp.net的forms身份验证 单用户身份验证 首先要配置Web.config文件 <system.web> <authentication mode="Forms& ...
- 采用Asp.Net的Forms身份验证时,持久Cookie的过期时间会自动扩展
原文:http://www.cnblogs.com/sanshi/archive/2012/06/22/2558476.html 若是持久Cookie,Cookie的有效期Expiration属性有当 ...
- 采用Asp.Net的Forms身份验证时,非持久Cookie的过期时间会自动扩展
问题描述 之前没有使用Forms身份验证时,如果在登陆过程中把HttpOnly的Cookie过期时间设为半个小时,总会收到很多用户的抱怨,说登陆一会就过期了. 所以总是会把Cookie过期时间设的长一 ...
- ASP.NET WEBAPI 的身份验证和授权
定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...
- ASP.NET Web API身份验证和授权
英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-a ...
- 坎坷路:ASP.NET 5 Identity 身份验证(上集)
之所以为上集,是因为我并没有解决这个问题,写这篇博文的目的是纪录一下我所遇到的问题,以免自己忘记,其实已经忘了差不多了,写的过程也是自己回顾的过程,并且之前收集有关 ASP.NET 5 身份验证的书签 ...
- asp.net 简单的身份验证
1 通常我们希望已经通过身份验证的才能够登录到网站的后台管理界面,对于asp.net 介绍一种简单的身份验证方式 首先在webconfig文件中添加如下的代码 <!--身份验证--> &l ...
- 利用.net的内部机制在asp.net中实现身份验证
知识点: 在ASP.NET中,任何页面都是继承于System.Web.UI.Page,他提供了Response,Request,Session,Application的操作.在使用Visual Stu ...
随机推荐
- 让Unity的Inspector面板支持字符限制(restrict)功能
今天在优化红点组件,笔者打算将红点id由10进制改为16进制处理,就打算将红点id字段由uint类型改成string类型,用于填写16进制的字符(因为在Inspector面板里,uint/int类型字 ...
- JS中this到底指向谁?
关于this的指向,是一个令人很头疼的问题.但是,你运气好,碰到了我.老夫这儿有本祖传秘籍,看懂这个,妈妈再也不用担心你的this指向不对啦! 归根结底,this指向就一句话:谁最终调用函数,this ...
- JS执行事件
先贴出几个名词: 同步任务: 在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务 异步任务: 不进入主线程,而进入"任务队列"的任务,只有任务队列通知主线程, ...
- Mysql 忘记root密码后修改root密码
1.修改my.cnf: 在mysqld进程配置文件中添加skip-grant-tables,添加完成后记住保存. 2.重新启动MYSQL数据库: service mysqld restart 2.修改 ...
- kotlin 语言入门指南(二)--代码风格
语言风格 这里整理了 kotlin 惯用的代码风格,如果你有喜爱的代码风格,可以在 github 上给 kotlin 提 pull request . 创建DTOs(POJSs/POCOs) 文件: ...
- C#中string,char[],byte[]互相转换
string 转换成 Char[] string ss = "我爱你,中国"; char[] cc = ss.ToCharArray(); Char[] 转换成string str ...
- 第 4 章 MySQL 安全管理
前言 对于任何一个企业来说,其数据库系统中所保存数据的安全性无疑是非常重要的,尤其是公司的有些商业数据,可能数据就是公司的根本,失去了数据的安全性,可能就是失去了公司的一切.本章将针对 MySQL 的 ...
- 最近用django做了个在线数据分析小网站
用最近做的理赔申请人测试数据集做了个在线分析小网站. 数据结构,算法等设置都保存在json文件里.将来对这个小破站扩充算法,只修改一下json文件就行. 当然,结果分析还是要加代码的.页面代码不贴了, ...
- MySQL目录结构和简单指令
1.MySQL目录结构 了解每个软件的安装目录下,每个文件夹下文件的类型和功能是有必要的,这可以方便我们直接进行软件配置和某些参数的修改. 2.简单指令 进入cmd后可以直接操作的命令 1)启动MyS ...
- 一天搞定CSS:字体font--04
1.字体体系 2.字体各属性取值 说明: 每一个属性后面的分支是属性值,以及对属性值的说明. 比如font-weight- - - -有两个取值:bold,normal 3.演示代码 <!DOC ...