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

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

  为此,我看了很多关于微软提供的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<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if ((this._rolesSplit.Length > 0) && !this._rolesSplit.Any<string>(new Func<string, bool>(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方法来判断用户的请求是否通过验证和授权。 

    (明天继续补充)

2017年3月14日-----------乱码新手自学.net 之Authorize特性与Forms身份验证(登陆验证、授权小实例)的更多相关文章

  1. 2017年2月22日-----------乱码新手自学.net 之Entity Framework 增删改

    由于我是自学的,没有人教,在网上查资料也查不到个所以然.问大神们也是爱理不理的. 所以这篇随笔纯粹源自于我自己的认识.是否真正正确我也没有把握. 如果有什么错误,请大神们给予指正 ========== ...

  2. 2017年2月16日-----------乱码新手自学.net 之MVC模型

    第二篇博文,最近学习的内容还是回到了正题:ASP.NET MVC5之上.虽然EF学了个一知半解,但是用这点知识,看MVC5的MODEL部分应该还是够了.尽管周末还要恶补一下EF才行. (一)MVC简述 ...

  3. 2017年2月28日-----------乱码新手自学.net 之特性与验证

    现在看asp.net MVC5自学已经到了第六章:数据注解与验证. 话得从以前看MVC music store(音乐商店项目)的源码说起, 最初看music store源码完全就是一脸懵逼,整个程序, ...

  4. Android Studio最新稳定版下载 - 百度网盘(更新于2017年7月14日)

    Android Studio是一个为Android平台开发程序的集成开发环境,其包含用于构建Android应用所需的所有工具.Android Studio 2.3.3为最新稳定版(截止到2017年7月 ...

  5. 读C#开发实战1200例子记录-2017年8月14日11:20:38获取汉字编码值

    try { char chr = textBox1.Text[0]; byte[] gb2312_bt = Encoding.GetEncoding("gb2312").GetBy ...

  6. 读C#开发实战1200例子记录-2017年8月14日10:03:55

    C# 语言基础应用,注释 "///"标记不仅仅可以为代码段添加说明,它还有一项更重要的工作,就是用于生成自动文档.自动文档一般用于描述项目,是项目更加清晰直观.在VisualStu ...

  7. 【http学习杂记】2017年7月14日

    1. 连接超时 连接超时是tcp协议层次, 此时服务器还没有处理请求数据,也就是说服务器的逻辑开没有执行 2. 请求超时 请求超时属于服务器已经连接成功并开始处理,但是时间比较长,大于你设置的请求超时 ...

  8. 2017年12月14日 LinQ高级查&&Asp.net WebForm Asp.net MVC

    LinQ的高级查询用法 开头:StartsWith()结尾:EndsWith()模糊:Contains() 个数:Count最大值:Max(r => r.price)最小值:Min(r => ...

  9. spring@Autowired注入为null的问题,2017年9月14日21点41分记录

    这个小问题纠结了三个小时..发出来留个纪念 这是启动项目的时候 这是请求控制器的时候   图1注入的时候是null,图2请求控制器的时候是有的,这是因为图1debug的地方是构造器..autowire ...

随机推荐

  1. IE滚动条

    之前一直没留意过IE下面的滚动条样式,今天碰到一个优化需求,需要去掉横向的滚动条,只保留竖的滚动条. 实现方式很简单,设置宽度,overflow-x:hiddle:overflow-y:scroll ...

  2. Mysql常用命令行大全(二)

    #登录数据库mysql -hlocalhost -uroot -p;#修改密码mysqladmin -uroot -pold password new; #显示数据库show databases;#显 ...

  3. 浅析C语言中strtol()函数与strtoul()函数的用法

    转自:http://www.jb51.net/article/71463.htm C语言strtol()函数:将字符串转换成long(长整型数) 头文件: ? 1 #include <stdli ...

  4. 【转】python的复制,深拷贝和浅拷贝的区别

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...

  5. git pull 冲突

    1. 问题描述 error: Your local changes to the following files would be overwritten by merge: xxx/xxx/xxx ...

  6. linux查询内存真是利用率

    使用top工具查看到Suse Linux的内存占用率很大,可能97%以上,我知道这是Linux的内存使用机制,先将内存整个管理起来,需要的时候在分配给单个进程.但是如果我需要查看系统真实的内存占用率应 ...

  7. NLB

    http://www.cnblogs.com/allegro/archive/2011/02/11/1951171.html

  8. POI 中的CellType类型以及值的对应关系

    操作使用POI接口,了解CellType的类型和值的对应关系. CellType 类型 值 CELL_TYPE_NUMERIC 数值型 0 CELL_TYPE_STRING 字符串型 1 CELL_T ...

  9. CQL查Cassandra条目数中的小问题

    用查询语句:SELECT count(*) FROM tablename 返回类型是ResultSet,得到tablename中所有条目数 ResultSet类型可以直接用index访问:Result ...

  10. Unity T4M 中文讲解

    http://blog.csdn.net/tianmao111/article/details/46482963 现在在u3d圈里流行了一种地形转换器(或者叫编辑器吧),但是经查阅之后,似乎还没有中文 ...