使用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(五):身份验证、授权的更多相关文章

  1. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分

    原文:使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)--第1部分 原文链接:https://www.codeproject.com/Articles/5160941/ASP- ...

  2. 也谈Asp.net 中的身份验证

    钱李峰 的这篇博文<Asp.net中的认证与授权>已对Asp.net 中的身份验证进行了不错实践.而我这篇博文,是从初学者的角度补充了一些基础的概念,以便能有个清晰的认识. 一.配置安全身 ...

  3. asp.net的forms身份验证 单用户身份验证

    asp.net的forms身份验证  单用户身份验证 首先要配置Web.config文件 <system.web> <authentication mode="Forms& ...

  4. 采用Asp.Net的Forms身份验证时,持久Cookie的过期时间会自动扩展

    原文:http://www.cnblogs.com/sanshi/archive/2012/06/22/2558476.html 若是持久Cookie,Cookie的有效期Expiration属性有当 ...

  5. 采用Asp.Net的Forms身份验证时,非持久Cookie的过期时间会自动扩展

    问题描述 之前没有使用Forms身份验证时,如果在登陆过程中把HttpOnly的Cookie过期时间设为半个小时,总会收到很多用户的抱怨,说登陆一会就过期了. 所以总是会把Cookie过期时间设的长一 ...

  6. ASP.NET WEBAPI 的身份验证和授权

    定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...

  7. ASP.NET Web API身份验证和授权

    英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-a ...

  8. 坎坷路:ASP.NET 5 Identity 身份验证(上集)

    之所以为上集,是因为我并没有解决这个问题,写这篇博文的目的是纪录一下我所遇到的问题,以免自己忘记,其实已经忘了差不多了,写的过程也是自己回顾的过程,并且之前收集有关 ASP.NET 5 身份验证的书签 ...

  9. asp.net 简单的身份验证

    1 通常我们希望已经通过身份验证的才能够登录到网站的后台管理界面,对于asp.net 介绍一种简单的身份验证方式 首先在webconfig文件中添加如下的代码 <!--身份验证--> &l ...

  10. 利用.net的内部机制在asp.net中实现身份验证

    知识点: 在ASP.NET中,任何页面都是继承于System.Web.UI.Page,他提供了Response,Request,Session,Application的操作.在使用Visual Stu ...

随机推荐

  1. python3 selenium 切换窗口的几种方法

    第一种方法: 使用场景: 打开多个窗口,需要定位到新打开的窗口 使用方法: # 获取打开的多个窗口句柄windows = driver.window_handles# 切换到当前最新打开的窗口driv ...

  2. Linux 定时任务详解

    原文地址:http://edu.codepub.com/2011/0104/28518.php   crond分为系统级定时和用户级定时,系统级定时主要编辑/etc/crontab,用户级定时主要利用 ...

  3. maven命令更新子父项目的pom版本

    Q:一个maven项目,有多个子module,在顶级父pom.xml里设置<version>1.0.0-SHAPSHOT</version>,在子pom.xml里都用了 < ...

  4. hdu3709 Balanced Number 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题目大意就是求给定区间内的平衡数的个数 要明白一点:对于一个给定的数,假设其位数为n,那么可以有 ...

  5. codeforce 149D Coloring Brackets 区间DP

    题目链接:http://codeforces.com/problemset/problem/149/D 继续区间DP啊.... 思路: 定义dp[l][r][c1][c2]表示对于区间(l,r)来说, ...

  6. eclipse C 开发 Stm32

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.下载eclipse需要的运行环境,JDK/JRE. 在http://wiki.eclipse.org/Eclipse/Installation ...

  7. Linux services, runlevels, and rc.d scripts

    Reference: [1] https://www.linux.com/news/introduction-services-runlevels-and-rcd-scripts A Linux se ...

  8. 无锁atomicInteger

    AtomicInteger可以保证硬件上的原子操作 1.主要原理 CAS操作 在进行数据更新的时候,会进行与内存中的地址进行比较,若预期值与内存中的值相同,则进行数据上的更新,若值不同,则更新失败,  ...

  9. springcloud(七):配置中心svn示例和refresh

    上一篇springcloud(六):配置中心git示例留了一个小问题,当重新修改配置文件提交后,客户端获取的仍然是修改前的信息,这个问题我们先放下,待会再讲.国内很多公司都使用的svn来做代码的版本控 ...

  10. 通过Percona Xtrabackup实现数据的备份与恢复

    Xtrabackup简介 Percona XtraBackup是一个开源.免费的MySQL热备份软件,能够为InnoDB和XtraDB数据库执行非阻塞备份,特点如下: 1.快速.可靠的完成备份 2.备 ...