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

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

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

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

例如

     public class MyAuthorizeFilter : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
//do something... }
} public class MyAsyncAuthorizeFilter : IAsyncAuthorizationFilter
{
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
//do someting... }
}
MyAuthorizeFilter

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

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

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

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

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

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

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

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

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

 public class MyAuthorizeFilter : AuthorizeFilter
{ private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { }); public MyAuthorizeFilter() : base(_policy_) { } public override async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
await base.OnAuthorizationAsync(context);
Console.WriteLine("权限检测");
}
}

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

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

这是为啥?

继续调试。

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

修改代码,最终成了这样

     public class MyAuthorizeFilter : AuthorizeFilter
{ private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { }); public MyAuthorizeFilter() : base(_policy_) { } public override async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
await base.OnAuthorizationAsync(context);
if (!context.HttpContext.User.Identity.IsAuthenticated ||
context.Filters.Any(item => item is IAllowAnonymousFilter)) return;
//do something
}
}

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

又及:

在某篇博客中见过一个问题,大概就是说 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. 删除Windows中隐藏的物理网卡和网络虚拟化失败后的虚拟网卡

    Windows环境下,在更换硬件服务器主板和网卡等硬件.恢复操作系统或者网络虚拟化失败后,可能会出现网卡方面的问题.例如,设备管理器中多了不应该存在的网卡:因命名冲突无法重命名当前网络连接:IP地址冲 ...

  2. 我的DbHelper数据操作类

    其实,微软的企业库中有一个非常不错的数据操作类了.但是,不少公司(起码我遇到的几个...),对一些"封装"了些什么的东西不太敢用,虽然我推荐过微软的企业库框架了...但是还是要&q ...

  3. html5头部说明

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --><html lang="zh-cmn-Hans"> ...

  4. Hierarchical cluster算法介绍

    突然想记录几个聚类算法,由于实力有限就先介绍一下层次聚类算法(Hierarchical cluster algorithm),这个聚类算法思想简单,但实现起来感觉复杂度挺大:以前看过<集体智慧编 ...

  5. Lua Table转C# Dictionary

    因为在游戏公司做web后台开发,经常会涉及到取游戏服务器的数据库里面读写各种操作. 昨天下午,服务器那边让我读一个配置显示到后台,让运营大佬们可以在web后台配置游戏参数. 本来以为很简单个事情,结果 ...

  6. 为什么要用 Docker

    作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势. 首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多. 其次,Docker 对系统资源的利用率很 ...

  7. linux 文本编辑 软件管理

    gerp 命令 : grep是强大的文本搜索工具,它对文本文件逐行查看,如果找到匹配的模式,就会打印出包含此模式的所有行,并且grep支持正则表达式 1  grep 选项 模式 被查找文件 : gre ...

  8. JS的forEach和map方法的区别

    一.前言 forEach()和map()两个方法都是ECMA5中Array引进的新方法,主要作用是对数组的每个元素执行一次提供的函数,但是它们之间还是有区别的.jQuery也有一个方法$.each() ...

  9. js之数组操作

    js之数组操作 前言 本文主要从应用来讲数组api的一些操作,如一行代码扁平化n维数组.数组去重.求数组最大值.数组求和.排序.对象和数组的转化等.(文章摘自:https://segmentfault ...

  10. windows下彻底删除jenkins

    1.在控制面板中选择卸载jenkins 2.重启电脑 3.找到“.jenkins”(在C盘寻找) 4.删除“.jenkins” 5.是否要删除环境变量?(目前没删除) 6.jenkins再安装使用的是 ...