asp.net core 自定义 Policy 替换 AllowAnonymous 的行为

asp.net core 自定义 Policy 替换 AllowAnonymous 的行为

Intro

最近对我们的服务进行了改造,原本内部服务在内部可以匿名调用,现在增加了限制,通过 identity server 来管理 api 和 client,网关和需要访问api的客户端或api服务相互调用通过 client_credencial 的方式来调用,这样一来我们可以清晰知道哪些 api 服务会被哪些 api/client 所调用,而且安全性来说更好。为了保持后端服务的代码更好的兼容性,希望能够实现相同的代码通过在 Startup 里不同的配置实现不同的 Authorization 逻辑,原来我们的服务的 Authorize 都是以 Authorize("policyName") 的形式来写的,这样一来我们只需要修改这个 Policy 的授权配置就可以了。对于 AllowAnonymous 就希望可以通过一种类似的方式来实现,通过自定义一个 Policy 来实现自己的逻辑

实现方式

将 action 上的 AllowAnonymous 替换为 Authorize("policyName"),在没有设置 Authorize 的 controller 上增加 Authorize("policyName")

  1. public class AllowAnonymousPolicyTransformer : IApplicationModelConvention

  2. {

  3. private readonly string _policyName;

  4. public AllowAnonymousPolicyTransformer() : this("anonymous")

  5. {

  6. }

  7. public AllowAnonymousPolicyTransformer(string policyName) => _policyName = policyName;

  8. public void Apply(ApplicationModel application)

  9. {

  10. foreach (var controllerModel in application.Controllers)

  11. {

  12. if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AuthorizeFilter)))

  13. {

  14. foreach (var actionModel in controllerModel.Actions)

  15. {

  16. if (actionModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter)))

  17. {

  18. var allowAnonymousFilter = actionModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter));

  19. actionModel.Filters.Remove(allowAnonymousFilter);

  20. actionModel.Filters.Add(new AuthorizeFilter(_policyName));

  21. }

  22. }

  23. }

  24. else

  25. {

  26. if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter)))

  27. {

  28. var allowAnonymousFilter = controllerModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter));

  29. controllerModel.Filters.Remove(allowAnonymousFilter);

  30. }

  31. controllerModel.Filters.Add(new AuthorizeFilter(_policyName));

  32. }

  33. }

  34. }

  35. }

  36. public static class MvcBuilderExtensions

  37. {

  38. public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder)

  39. {

  40. builder.Services.Configure<MvcOptions>(options =>

  41. {

  42. options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer());

  43. });

  44. return builder;

  45. }

  46. public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder, string policyName)

  47. {

  48. builder.Services.Configure<MvcOptions>(options =>

  49. {

  50. options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer(policyName));

  51. });

  52. return builder;

  53. }

  54. }

controller 中的代码:

  1. [Route("api/[controller]")]

  2. public class ValuesController : Controller

  3. {

  4. private readonly ILogger _logger;

  5. public ValuesController(ILogger<ValuesController> logger)

  6. {

  7. _logger = logger;

  8. }

  9. // GET api/values

  10. [HttpGet]

  11. public ActionResult<IEnumerable<string>> Get()

  12. {

  13. var msg = $"IsAuthenticated: {User.Identity.IsAuthenticated} ,UserName: {User.Identity.Name}";

  14. _logger.LogInformation(msg);

  15. return new string[] { msg };

  16. }

  17. // GET api/values/5

  18. [Authorize]

  19. [HttpGet("{id:int}")]

  20. public ActionResult<string> Get(int id)

  21. {

  22. return "value";

  23. }

  24. // ...

  25. }

Startup 中 ConfigureServices 配置:

  1. var anonymousPolicyName = "anonymous";

  2. services.AddAuthorization(options =>

  3. {

  4. options.AddPolicy(anonymousPolicyName, builder => builder.RequireAssertion(context => context.User.Identity.IsAuthenticated));

  5. options.DefaultPolicy = new AuthorizationPolicyBuilder(HeaderAuthenticationDefaults.AuthenticationSchema)

  6. .RequireAuthenticatedUser()

  7. .RequireAssertion(context => context.User.GetUserId<int>() > 0)

  8. .Build();

  9. });

  10. services.AddMvc(options =>

  11. {

  12. options.Conventions.Add(new ApiControllerVersionConvention());

  13. })

  14. .AddAnonymousPolicyTransformer(anonymousPolicyName)

  15. ;

实现效果

访问原来的匿名接口

userId 为0访问原来的匿名接口

userId 大于0访问原来的匿名接口

userId 为0访问需要登录的接口

userId 大于0访问需要登录的接口

More

注:按照上面的做法已经可以做到自定义 policy 代替 AllowAnonymous 的行为,但是原来返回的401,现在可能返回到就是 403 了

Reference

  • https://github.com/WeihanLi/AspNetCorePlayground/blob/master/TestWebApplication

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端小白在asp.net core mvc中使用ECharts

对于在浏览器中绘制图形图表&#xff0c;目前有较多的js类库可以使用&#xff0c;如&#xff1a;ChartJS&#xff0c;Flot&#xff0c;canvasjs等&#xff0c;但是今天介绍的主角为国产图表库&#xff0c;并在apache孵化&#xff0c;就是大名鼎鼎的echarts。前方高能【官方介绍…

超过1w的Github Star大佬和他们的公众号,太强了!

不少同学担忧的情况——“晋升无望、收入见顶、生活开支飙升、财务危机如影随形”&#xff0c;小编精心挑选了几个优质原创技术号&#xff0c;推荐给大家化解成长的烦恼。他们都是我平时关注的优秀号主&#xff0c;分享给大家&#xff0c;助大家学习路上披荆斩棘~Python爱好者社…

Java和C++区别

Java和C的区别有很多&#xff0c;主要集中在如下几个方面&#xff1a; 运行机制 Java&#xff1a; 编写&#xff1a;是指在Java开发环境&#xff08;Eclipse、Sublime等&#xff09;中进行程序代码的输入&#xff0c;最终形成后缀名为.java的Java源文件。 编译&#xff1a;是指…

未雨绸缪 | 一文简介 Azure Front Door

点击上方蓝字关注“汪宇杰博客”导语昨天早晨微软服务器发生了核爆&#xff0c;Office 365&#xff0c;Bing&#xff0c;Azure DevOps全线完蛋。人类文明危在旦夕之际&#xff0c;微软美国的死士凌晨2点爬起来收福报&#xff0c;修好了服务器&#xff0c;拯救了全人类&#xff…

左手专注,右手时间

大家好&#xff0c;我是Z哥。今天带来的是一篇有感而发的随笔&#xff0c;敬请品尝&#xff5e;前两天最火的事情莫过于WPS上市了。这个平时默默无闻、低调的可怕的产品一下子被捧上了天。我第一次接触到WPS还比较晚&#xff0c;大约在2014年的样子&#xff0c;当时由于某些特殊…

说说开源那些事儿

“ 阅读本文大概需要 9 分钟。 ”前段时间我们遇到了一个情况&#xff0c;课程推送发出来之后有位同学在群里提到&#xff0c;机构提供的项目就是他同学导师的开源项目。之后这位导师在文章评论里联系了我&#xff0c;表示该机构课程涉嫌开源侵权他的 GitHub 开源项目。我们后台…

Linux下Tomcat安装和配置

1、前提&#xff08;JDK环境&#xff09;Tomcat的安装需要JDK环境&#xff0c;如何配置JDK环境见我的文章Linux下Java环境配置&#xff0c;所以在安装Tomcat之前需要先检测JDK环境是否配置好。 进入命令行界面&#xff0c;输入java -version命令来查看JDK环境是否配置成功&…

ASP.NET Core快速入门(第1章:介绍与引入)--学习笔记

点击蓝字关注我们课程链接&#xff1a;http://video.jessetalk.cn/course/explore良心课程&#xff0c;大家一起来学习哈&#xff01;任务1&#xff1a;课程介绍1、介绍与引入2、配置管理3、依赖注入4、ASP.NET Core HTTP介绍5、认证与授权6、ASP.NET Core MVC任务2&#xff1a…

Eclipse下Tomcat服务器配置和使用

在安装完Tomcat之后&#xff0c;在没有进行相关配置时&#xff0c;我们需要到终端下面去启动Tomcat。如果我们在使用Eclipse进行Java开发时&#xff0c;如果能够直接启动Tomcat服务器那将是极为方便&#xff0c;本篇就来讲述Eclipse下Tomcat服务器如何配置以及如何使用。 1、配…

Facebook押注VS Code

Facebook 近日宣布默认采用 VS Code 作为内部开发环境。去年 Facebook 宣布停止维护其开源的 Nuclide/Atom-IDE&#xff0c;以及相关的一些库。Nuclide/Atom-IDE 是 Atom 编辑器的功能包&#xff0c;其通过语言服务器协议与自定义语言服务器交互&#xff0c;为 Atom 提供一系列…

Linux下软件安装和卸载

在Windows下&#xff0c;我们安装软件基本上是先到网上下载软件的安装包&#xff0c;通常是以.exe和.msi为后缀的文件&#xff0c;然后双击安装包&#xff0c;之后就可以按照软件安装向导一步步进行安装了&#xff0c;但在Linux下&#xff0c;软件的安装方式截然不同。总的来说…

为WPF, UWP 及 Xamarin实现一个简单的消息组件

友情提示&#xff1a;阅读本文大概需要8分钟。欢迎大家点击上方公众号链接关注我&#xff0c;了解新西兰码农生活本文目录&#xff1a;1. 介绍2. Message - 消息3. Subscription - 订阅4. MessageHub - 消息总线4.1 Subscribe - 订阅4.2 Unsubscribe - 取消订阅4.3 Publish - 发…

Mac(OS X)安装、配置并使用MySQL数据库

1、MySQL安装包下载 MySQL Community Server下载地址&#xff1a;http://dev.mysql.com/downloads/mysql/&#xff0c;下载完毕之后安装文件如下所示&#xff1a; 2、MySQL安装 双击安装文件进行安装&#xff0c;出现如下界面&#xff1a; 双击窗体中的“mysql-5.7.10-osx10.9-…

用ASP.NETCore构建可检测的高可用服务

一、前言2019 中国 .NET 开发者峰会&#xff08;.NET Conf China 2019&#xff09;于2019年11月10日完美谢幕&#xff0c;校宝在线作为星牌赞助给予了峰会大力支持&#xff0c;我和项斌等一行十位同事以讲师、志愿者的身份公司参与到峰会的支持工作中&#xff0c;我自己很荣幸能…

Mac(OS X)使用brew安装软件

在Linux下&#xff0c;常用的软件包管理工具有RedHat系的yum和Debian系的apk-get&#xff0c;对于Mac的OS X系统来说&#xff0c;同样有这样的形式的软件包管理工具&#xff0c;即&#xff1a;brew。 brew 又叫Homebrew&#xff0c;是Mac OSX上的软件包管理工具&#xff0c;能…

SonarQube系列二、分析dotnet core/C#代码

来源&#xff1a;https://www.cnblogs.com/7tiny/p/11342902.html【前言】本系列主要讲述sonarqube的安装部署以及如何集成jenkins自动化分析.netcore项目。目录如下&#xff1a;SonarQube系列一、Linux安装与部署SonarQube系列二、分析dotnet core/C#代码SonarQube系列三、如何…

Eclipse使用Maven插件创建Web项目时出错:Could not resolve archetype org.apache.maven.archetypes

问题描述&#xff1a; 在Eclipse下&#xff0c;使用Maven插件创建Web项目时出错&#xff0c;错误提示如下&#xff1a; 错误信息&#xff1a; Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp:1.0 from any of the configured repositories. …

ASP.NET Core快速入门(第2章:配置管理)--学习笔记

点击蓝字关注我们课程链接&#xff1a;http://video.jessetalk.cn/course/explore良心课程&#xff0c;大家一起来学习哈&#xff01;任务9&#xff1a;配置介绍命令行配置Json文件配置从配置文件文本到c#对象实例的映射 - Options 与 Bind配置文件热更新框架设计&#xff1a;C…

怎么写技术简历?

作者&#xff1a;zollty&#xff0c;资深程序员和架构师&#xff0c;私底下是个爱折腾的技术极客&#xff0c;架构师社区合伙人&#xff01;纯手打&#xff0c;个人多年经验总结。&#xff08;本人的简历&#xff0c;历年来效果都不错&#xff0c;从校招到高端技术岗位、大厂技…

C# 代码中调用 Javascript 代码段以提高应用程序的配置灵活性(使用 Javascript .NET 与 Jint)...

一般来说&#xff0c;我们需要在开发应用软件的配置文件中&#xff0c;添加一些参数&#xff0c;用于后续用户根据实际情况&#xff0c;自行调整。配置参数&#xff0c;可以放在配置文件中、环境变量中、或数据库表中(如果使用了数据库的话)。通常&#xff0c;配置数据&#xf…