博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2017年3月14日-----------乱码新手自学.net 之Authorize特性与Forms身份验证(登陆验证、授权小实例)...
阅读量:6323 次
发布时间:2019-06-22

本文共 4478 字,大约阅读时间需要 14 分钟。

  有段时间没写博客了,最近工作比较忙,能敲代码的时间也不多。

  我一直有一个想法,想给单位免费做点小软件,一切思路都想好了,但是卡在一个非常基础的问题上:登陆与授权。

  为此,我看了很多关于微软提供的Identity、MemberShip的资料。

  但我发现,这两种方式都是默认代码优先(不知道为啥就是那么讨厌CODE FIRST),配置如此复杂恶心。实在很不爽,所以,我要想想其他的办法。

  直到我发现了Authorize特性,以此开始,找到了一个利用Authorize特性+Forms身份验证 做 验证与授权 的解决方案  

  ( 也许这套解决方案不是很好,也欢迎各位大神指点一二)

 

一、Authorize特性

  Authorize特性是微软提供的一个用于身份验证和授权的特性,一般提倡于用在MVC中。

    它的用法也很简单

[Authorize]  //不加任何惨呼标示,必须要登陆才能访问控制器        public ActionResult Index()        {            return View();        }            [Authorize(Users="张三")]  //加一个Users参数,表示限制用户名为“张三”的人才能访问        public ActionResult About()        {            return View();        }        [Authorize(Roles="admin")]//限制权限为“admin”的人才能访问        public ActionResult Test()        {            return View();        }//当然,Users和Roles两个参数可以一起使用

 

  第一次使用这个特性,总感觉好神奇。我们有必要反编译一下这个Authorize看它到底如何。首先我们看看这个特性里面有哪些成员

 

 

    我猜大部分初学者看元数据都会一脸懵逼,因为找不到切入点,楼主不才,现在总结了一个小窍门:凡是实现了接口的类,首先看看它的接口成员有什么,接口里很有可能是切入点。在这里我们就看IAuthorizationFilter

     这个接口实现了OnAuthorization()方法,我们就从这里入手。

public virtual void OnAuthorization(AuthorizationContext filterContext)        {            if (filterContext == null)            {                throw new ArgumentNullException("filterContext");            }            if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))            {                throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);            }            if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))            {                if (this.AuthorizeCore(filterContext.HttpContext)) //这里调用它的验证内核进行验证。                {                    HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;                    cache.SetProxyMaxAge(new TimeSpan(0L));                    cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);                }                else                {                    this.HandleUnauthorizedRequest(filterContext);                }            }        }        protected virtual bool AuthorizeCore(HttpContextBase httpContext)  //这里做具体的验证        {            if (httpContext == null)            {                throw new ArgumentNullException("httpContext");            }            IPrincipal user = httpContext.User;            if (!user.Identity.IsAuthenticated)            {                return false;            }            if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains
(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { return false; } if ((this._rolesSplit.Length > 0) && !this._rolesSplit.Any
(new Func
(user.IsInRole))) { return false; } return true; }

      OnAuthorization()方法中调用AuthorizeCore()方法,在它里面进行具体的验证。

      这里面有个 HttpContextBase,是不是很熟悉?(不熟悉的话,HttpContext总该熟悉了吧,你可以看看它们之间的继承关系)

      AuthorizeCore()做具体验证的方式就是比对HttpContext里面的User属性,无论是校验是否登陆、还是校验用户名字、还是校验用户角色(权限),都是用这个对象来做的。

   那么这个HttpContext.User到底是怎么回事呢?它又是怎么来的呢?

二、IPrincipal接口与HttpContext.User对象

   HttpContext.User对象我们转到定义一看,它其实就是一个IPrincipal接口。

     IPrincipal接口很简单,就一个标示身份的IIdentity接口的属性,一个是否授权方法。IIdentity接口也不复杂,就是一个用户名、是否授权、一个授权类型。

// 摘要:     //     定义用户对象的基本功能。    [ComVisible(true)]    public interface IPrincipal    {        // 摘要:         //     获取当前用户的标识。        //        // 返回结果:         //     与当前用户关联的 System.Security.Principal.IIdentity 对象。        IIdentity Identity { get; }        // 摘要:         //     确定当前用户是否属于指定的角色。        //        // 参数:         //   role:        //     要检查其成员资格的角色的名称。        //        // 返回结果:         //     如果当前用户是指定角色的成员,则为 true;否则为 false。        bool IsInRole(string role);    }

// 摘要:

// 定义标识对象的基本功能。
[ComVisible(true)]
public interface IIdentity
{
// 摘要:
// 获取所使用的身份验证的类型。
//
// 返回结果:
// 用于标识用户的身份验证的类型。
string AuthenticationType { get; }
//
// 摘要:
// 获取一个值,该值指示是否验证了用户。
//
// 返回结果:
// 如果用户已经过验证,则为 true;否则为 false。
bool IsAuthenticated { get; }
//
// 摘要:
// 获取当前用户的名称。
//
// 返回结果:
// 用户名,代码当前即以该用户的名义运行。
string Name { get; }
}

    当我们的请求在进入HTTP处理管道之后,某个位置只要给我们的HttpContext.User实例化出一个对象,我们的Authorize特性就能成功地使用了。因为这个特性的验证方法里,会调User对象的Identity.IsAuthenticated,和IsInRole方法来判断用户的请求是否通过验证和授权。 

    (明天继续补充)

转载于:https://www.cnblogs.com/bibibibi/p/6551597.html

你可能感兴趣的文章
C语言:使用realloc函数对malloc或者calloc动态分配的内存大小进行扩展
查看>>
深入Xamarin.Forms
查看>>
UML--关系
查看>>
程序员技术练级攻略
查看>>
Objective-C中的hasPrefix
查看>>
一个从四秒到10毫秒,花了1年的算法问题?
查看>>
哇!板球 源代码分析四
查看>>
Android 程式开发:(十三)特殊碎片 —— 13.2 DialogFragment
查看>>
已经解决django生成po文件时出现的xgettext的错误
查看>>
Unity中的Path对应各平台中的Path
查看>>
分享个好玩的算法游戏
查看>>
自学Java-数据类型
查看>>
ActiveReports 报表应用教程 (4)---分栏报表
查看>>
cisco认证追踪,认证查询
查看>>
如何格式化日期显示
查看>>
thinkphp控制器获取参数
查看>>
cloudera-manager和CDH5.6.1升级到5.13.0
查看>>
CDH集群重亲启动报错,相同主机名出现两个
查看>>
javascript中的继承二 call()和apply()
查看>>
WebView用法
查看>>