博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性
阅读量:6992 次
发布时间:2019-06-27

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

假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似AO系统那样,登陆了才能用)。

那在每个控制器上加一个 [Authorize] 是能解决问题,反正正我是觉得麻烦。

而且Core自带的权限认证机制不满足于复杂的身份权限认证,打算像在Framework中一样注册一个全局过滤器,然后用 [AllowAnonymous] 来放行可以匿名的控制器或者方法。

 

按照官方文档,自定义身份过滤器推荐实现 IAuthorizationFilter 或者 IAsyncAuthorizationFilter 接口,再顺便给他们定义为中间件更好。

例如

1     public class MyAuthorizeFilter : IAuthorizationFilter 2     { 3         public void OnAuthorization(AuthorizationFilterContext context) 4         { 5             //do something... 6         } 7     } 8  9     public class MyAsyncAuthorizeFilter : IAsyncAuthorizationFilter10     {11         public Task OnAuthorizationAsync(AuthorizationFilterContext context)12         {13             //do someting...14         }15     }
MyAuthorizeFilter

然后在Startup.cs中注册全局过滤器

1         public void ConfigureServices(IServiceCollection services)2         {3             services.AddMvc(option => { option.Filters.Add(typeof(MyAuthorizeFilter)); });4         }

 

可是运行时发现,自定义的过滤器无法阻止那些没有授权的请求!这是为什么?

在控制器上加上  [Authorize] 调试

发现实际上我的过滤器已经被加到了过滤器列队里,但是本身并没有执行任何动作。

其实这里也是我自己犯傻了,人家就是一个接口而已,肯定没有任何操作,单纯继承接口以后指望人家能做什么呢。

 

那我们既要实现原生的权限认证机制(毕竟像未登录跳转等功能不用自己实现了),还要增加自定义的认证机制。

后来发现 [Authorize] 属性会被注册为AuthorizeFliter过滤器。那就妥了,继承然后重写其实现就好。

我的过滤器就变成了这样。

1 public class MyAuthorizeFilter : AuthorizeFilter 2     { 3  4         private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { }); 5  6         public MyAuthorizeFilter() : base(_policy_) { } 7  8         public override async Task OnAuthorizationAsync(AuthorizationFilterContext context) 9         {10             await base.OnAuthorizationAsync(context);11             Console.WriteLine("权限检测");12         }13     }

 

说明一下实现AuthorizeFilter基类,必须有一个过滤策略,也就是,这里我采用的是最基础的DenyAnonymousAuthorizationRequirement(阻止匿名身份的请求)

 

运行,过滤器可以正常过滤没有授权的请求了,但是无论授权与否,或者是否可匿名访问,均会执行“权限检测”那里。

这是为啥?

继续调试。

发现 [AllowAnonymous] 也被注册成了过滤器。

 

修改代码,最终成了这样

1     public class MyAuthorizeFilter : AuthorizeFilter 2     { 3  4         private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { }); 5  6         public MyAuthorizeFilter() : base(_policy_) { } 7  8         public override async Task OnAuthorizationAsync(AuthorizationFilterContext context) 9         {10             await base.OnAuthorizationAsync(context);11             if (!context.HttpContext.User.Identity.IsAuthenticated ||12                 context.Filters.Any(item => item is IAllowAnonymousFilter)) return;13             //do something14         }15     }

 

仅作为一个简单的学习笔记。如果有更好的方法欢迎指教。

 

又及:

在某篇博客中见过一个问题,大概就是说 context.HttpContext.User.Identity.IsAuthenticate 的值恒定false,后来采用了一大堆不啦不啦的方法自己实现了获取认证状态的方法。这篇博客我找不到了。

我也遇到了类似的问题,后来发现是在startup的Configure中没有启用身份认证 app.UseAuthentication() ,根据自己的方法自行选择,例如我后来用IdentityServer4,就变成了 app.UseIdentityServer(); 

 

转载于:https://www.cnblogs.com/kasimlz/p/7845574.html

你可能感兴趣的文章
QTP简单框架(4)之项目结构图
查看>>
hudson default directory for deb ubuntu version
查看>>
vs2005下配置OGRE
查看>>
London2012同步时间新语
查看>>
Android如何获取多媒体文件信息
查看>>
端口列表详解
查看>>
ecshop 用户中心
查看>>
浅谈MySql的存储引擎(表类型)
查看>>
第三方控件DevExpress中ASPxNavBar1用法
查看>>
Spring.net、NHibernate相关文章导航
查看>>
Android中Application设置全局变量以及传值
查看>>
每日英语:The Rise Of The Female Investor
查看>>
黑马程序员-JAVA基础-基本数据类型对象包装类
查看>>
Gzip Zlib PNG 压缩算法,源码详解 - swo2006 - C++博客
查看>>
Console-算法[foreach,if]-一输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数...
查看>>
[原][问题解决]Openstck云平台虚拟机无法连接问题解决
查看>>
状态控件ios 中滑块、开关、分段控件、操作表和警告的常用函数
查看>>
分享非常漂亮的WPF界面框架源码及其实现原理
查看>>
如何获取ResultSet的行数和列数(转)
查看>>
绑定列ORA-24816: 在实际的 LONG 或 LOB 列之后提供了扩展的非 LONG 绑定数据
查看>>