ASP.NET MVC5(五):身份验证、授权

摘要:
使用Authorize特性进行身份验证通常情况下,应用程序都是要求用户登录系统之后才能访问某些特定的部分。在ASP.NETMVC中,可以通过使用Authorize特性来实现,甚至可以对整个应用程序全局使用Authorize特性。Authorize的用法本节以一个添加产品的示例来说明Authorize的使用方法。★Authorize特性不仅可以用在Action上,同样可以使用在Controller上全局授权过滤器对于大部分网站而言,基本上整个应用程序都需要身份验证,当然我们不可能在每个控制器上添加Authorize特性。此时,把AuthorizeAttribute配置为全局

使用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,添加如下产品。

ASP.NET MVC5(五):身份验证、授权第1张

此时收到用户需求,必须是已经登录的用户才可以添加产品,如匿名用户请求访问产品创建页面,则直接定位到登录界面。修改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(五):身份验证、授权》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PHP 命名空间Unity编辑器扩展下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

从网页监听Android设备的返回键

最近搞Android项目的时候,遇到一个比较蛋疼的需求,需要从Client App调用系统浏览器打开一个页面,进行杂七杂八的一些交互之后,返回到App。如何打开浏览器和如何返回App这里就不说了,有兴趣的童鞋可私下交流。 之所以说这个需求蛋疼,是因为Android有个物理返回键啊……返回键啊……键啊……啊…… 用户按下返回键后,预期应该跟点击页面上的返回键...

win10快捷键大全 win10常用快捷键

win10快捷键大全大家可以来了解一下,今天小编带来了win10常用快捷键,很多朋友喜欢使用快捷键来操作电脑,那么Windows10系统有哪些新的快捷键呢• 贴靠窗口:Win +左/右> Win +上/下>窗口可以变为1/4大小放置在屏幕4个角落 • 切换窗口:Alt + Tab(不是新的,但任务切换界面改进) • 任务视图:Win + Tab...

极光推送 JPush 简介 集成 MD

Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com 目录 目录JPush产品简介消息形式推送目标集成步骤FAQ简洁版自定义消息推送DemoActivityReceiver消息处理类B...

Guideline 5.2.1

      最近在上架公司公司项目的时候遇到这个问题什么5.2.1 然后去了解发现最近不少人都遇到了这个问题.先说一下 我上架的APP是一个医疗的APP然后说需要什么医疗资质,估计是账号的公司资质不够吧。后面和苹果电话,对方要求提供医院相关的医疗资质,公司都没和医院合作当然无法提供医疗资质了,然后和苹果交流,告诉对方我们的APP只提供健康咨询,健康问诊,不...

jmeter之认识元器件及功能 大杂烩

一、线程组 线程组是一个测试计划的开始点。在一个测试计划中的所有元件都必须在某个线程组下; 1.1 基础线程组Thread Group Ramp_up Periond值是预期Jmeter用于启动所有线程的时间;若是线程数过多,则会>该值启动完所有线程; 如下图,预期5s 启动200个线程;可以通过"用表格查看结果"查看每个线程的启动时间; 1.2...

解决mac iOS 上拉 下拉出现白色空白、白边

表现 pc端:mac鼠标滚动或触屏滚动时,头部、底部会多出一块白色区域 移动端: 手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。 产生原因 在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。 解决方案 监听事件...