[C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性
假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似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属性的更多相关文章
- ASP.NET Core中使用自定义MVC过滤器属性的依赖注入
除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...
- asp.net core系列 48 Identity 身份模型自定义
一.概述 ASP.NET Core Identity提供了一个框架,用于管理和存储在 ASP.NET Core 应用中的用户帐户. Identity添加到项目时单个用户帐户选择作为身份验证机制. 默认 ...
- Spring Boot环境下自定义shiro过滤器会过滤所有的url的问题
在配置shiro过滤器时增加了自定义的过滤器,主要是用来处理未登录状态下返回一些信息 //自定义过滤器 Map<String, Filter> filtersMap = new Linke ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- ASP.NET Core 项目简单实现身份验证及鉴权
ASP.NET Core 身份验证及鉴权 目录 项目准备 身份验证 定义基本类型和接口 编写验证处理器 实现用户身份验证 权限鉴定 思路 编写过滤器类及相关接口 实现属性注入 实现用户权限鉴定 测试 ...
- Asp.Net Core 进阶(四)—— 过滤器 Filters
一.介绍 Asp.Net Core Filter 使得可以在请求处理管道的特定阶段的前后执行代码,我们可以创建自定义的 filter 用于处理横切关注点. 横切关注点的示例包括错误处理.缓存.配置.授 ...
- 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...
- webservice安全性之 SoapHeader自定义身份验证
相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了. 首先我们来介绍webservic ...
- MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...
随机推荐
- 深度学习中batch normalization
目录 1 Batch Normalization笔记 1.1 引包 1.2 构建模型: 1.3 构建训练函数 1.4 结论 Batch Normalization笔记 我们将会用MNIST数 ...
- 算法提高 拿糖果 线性DP
题目链接:拿糖果 思路:首先给小于根号n的素数打表.d(i)表示当前剩余i颗糖,最多可以拿到多少糖. 转移方程:d(i) = max(d(i), k + d(i - 2 * k)),此处k表示 ...
- scrapy回调函数传递参数
scrapy.Request 的callback传参的两种方式 1.使用 lambda方式传递参数 def parse(self, response): for sel in response.xpa ...
- 看eShopOnContainers学一个EventBus
最近在看微软eShopOnContainers 项目,看到EventBus觉得不错,和大家分享一下 看完此文你将获得什么? eShop中是如何设计事件总线的 实现一个InMemory事件总线eShop ...
- Array.reduce()学习
昨天遇到的一道题:1234567890 => 1,234,567,890 要求其实就是使用逗号做千分位将数字进行分隔. 当时没想到任何方法,但是以前看到过,印象很深刻,今天就找了一下. 看到其实 ...
- 编译、裁剪、安装、删除 Ubuntu内核和模块管理
一.下载最新内核文件 地址:http://www.kernel.org,一般下载Full Source版本. 下载完毕后,放到任意文件夹中,使用命令: tar jxvf linux-x.x.x.tar ...
- 单片机:STC89C52的最小单元
STC89C52RC是STC公司生产的一种低功耗.高性能CMOS8位微控制器,具有 8K字节系统可编程Flash存储器.STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51 ...
- CPLD/FPGA厂商概述 .
随着可编程逻辑器件应用的日益广泛,许多IC制造厂家涉足PLD/FPGA领域.目前世界上有十几家生产CPLD/FPGA的公司,最大的三家是:ALTERA,XILINX,Lattice,其中ALTERA和 ...
- 过滤Java中特殊字符
过滤Java中特殊字符 /** * @Title:FilterString.java * @Package:com.you.model * @Description:过滤Java中特殊字符 * @Au ...
- 一种在BIOS中嵌入应用程序的方法及实现
本文针对Award公司开发的计算机系统BIOS提出了一种嵌入应用程序的方法,其基本原理对别的品牌的BIOS也一样适用,仅需稍加修改.文中作者给出并讨论一个完整的例子程序,该程序已经通过实验验证. 正 ...