假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似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. public class MyAsyncAuthorizeFilter : IAsyncAuthorizationFilter
  9. {
  10. public Task OnAuthorizationAsync(AuthorizationFilterContext context)
  11. {
  12. //do someting... }
  13. }
  1. 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 something
  14. }
  15. }

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

又及:

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

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

[C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性的更多相关文章

  1. ASP.NET Core中使用自定义MVC过滤器属性的依赖注入

    除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...

  2. asp.net core系列 48 Identity 身份模型自定义

    一.概述 ASP.NET Core Identity提供了一个框架,用于管理和存储在 ASP.NET Core 应用中的用户帐户. Identity添加到项目时单个用户帐户选择作为身份验证机制. 默认 ...

  3. Spring Boot环境下自定义shiro过滤器会过滤所有的url的问题

    在配置shiro过滤器时增加了自定义的过滤器,主要是用来处理未登录状态下返回一些信息 //自定义过滤器 Map<String, Filter> filtersMap = new Linke ...

  4. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  5. ASP.NET Core 项目简单实现身份验证及鉴权

    ASP.NET Core 身份验证及鉴权 目录 项目准备 身份验证 定义基本类型和接口 编写验证处理器 实现用户身份验证 权限鉴定 思路 编写过滤器类及相关接口 实现属性注入 实现用户权限鉴定 测试 ...

  6. Asp.Net Core 进阶(四)—— 过滤器 Filters

    一.介绍 Asp.Net Core Filter 使得可以在请求处理管道的特定阶段的前后执行代码,我们可以创建自定义的 filter 用于处理横切关注点. 横切关注点的示例包括错误处理.缓存.配置.授 ...

  7. 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...

  8. webservice安全性之 SoapHeader自定义身份验证

    相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了. 首先我们来介绍webservic ...

  9. MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...

随机推荐

  1. Qt 信号如何自动连接槽函数?

    on_objectName_signal [static] void QMetaObject::connectSlotsByName(QObject *object) void on_<obje ...

  2. windows NLB实现MSSQL读写分离--从数据库集群读负载均衡

    主从模式,几乎大部分出名的数据库都支持的一种集群模式. 当Web站点的访问量上去之后,很多站点,选择读写分离,减轻主数据库的的压力.当然,一主多从也可以作用多个功能,比如备份.这里主要演示如何实现从数 ...

  3. MSQL的基准测试

    Mysql基准测试 基准测试 直接.简单.易于比较,用于评估服务器的处理能力 压力测试 对真实的月数据进行测试,获得真是系统所能承受的压力 基准测试的目的 1.建立MySQL服务器的性能基准线 2.模 ...

  4. spring中自定义Event事件的使用和浅析

    在我目前接触的项目中,用到了许多spring相关的技术,框架层面的spring.spring mvc就不说了,细节上的功能也用了不少,如schedule定时任务.Filter过滤器. intercep ...

  5. Android中Java和JavaScript交互

    Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本.本文将介绍如何实现Java代码和Javascript代码的相互调用. 如 ...

  6. 航空客户价值分析特色LRFMC模型——RFM升级

    本文转载自微信公众号TIpDM. 每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 我们说RFM ...

  7. FusionCharts 2D帕累托图

    1.了解帕累托图的特性以及和其他图的共性 2.设计帕累托图页面中引入图的类型以及怎么引入到页面 Pareto2D.html: <!DOCTYPE HTML PUBLIC "-//W3C ...

  8. Linux显示服务器完整的状态信息

    Linux显示服务器完整的状态信息 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ apachectl [fullstatus] Usage: /usr/sbi ...

  9. org.hibernate.MappingException

    1.错误描述 org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'sessio ...

  10. Python与Memcached交互

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...