码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2019-11-21 13:50:22      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:core   art   形式   自己   arc   一个   enc   params   schema   

原文: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")

Copy
public class AllowAnonymousPolicyTransformer : IApplicationModelConvention { private readonly string _policyName; public AllowAnonymousPolicyTransformer() : this("anonymous") { } public AllowAnonymousPolicyTransformer(string policyName) => _policyName = policyName; public void Apply(ApplicationModel application) { foreach (var controllerModel in application.Controllers) { if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AuthorizeFilter))) { foreach (var actionModel in controllerModel.Actions) { if (actionModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter))) { var allowAnonymousFilter = actionModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter)); actionModel.Filters.Remove(allowAnonymousFilter); actionModel.Filters.Add(new AuthorizeFilter(_policyName)); } } } else { if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter))) { var allowAnonymousFilter = controllerModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter)); controllerModel.Filters.Remove(allowAnonymousFilter); } controllerModel.Filters.Add(new AuthorizeFilter(_policyName)); } } } } public static class MvcBuilderExtensions { public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder) { builder.Services.Configure<MvcOptions>(options => { options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer()); }); return builder; } public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder, string policyName) { builder.Services.Configure<MvcOptions>(options => { options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer(policyName)); }); return builder; } }

controller 中的代码:

Copy
[Route("api/[controller]")] public class ValuesController : Controller { private readonly ILogger _logger; public ValuesController(ILogger<ValuesController> logger) { _logger = logger; } // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { var msg = $"IsAuthenticated: {User.Identity.IsAuthenticated} ,UserName: {User.Identity.Name}"; _logger.LogInformation(msg); return new string[] { msg }; } // GET api/values/5 [Authorize] [HttpGet("{id:int}")] public ActionResult<string> Get(int id) { return "value"; } // ... }

Startup 中 ConfigureServices 配置:

Copy
var anonymousPolicyName = "anonymous"; services.AddAuthorization(options => { options.AddPolicy(anonymousPolicyName, builder => builder.RequireAssertion(context => context.User.Identity.IsAuthenticated)); options.DefaultPolicy = new AuthorizationPolicyBuilder(HeaderAuthenticationDefaults.AuthenticationSchema) .RequireAuthenticatedUser() .RequireAssertion(context => context.User.GetUserId<int>() > 0) .Build(); }); services.AddMvc(options => { options.Conventions.Add(new ApiControllerVersionConvention()); }) .AddAnonymousPolicyTransformer(anonymousPolicyName) ;

实现效果#

访问原来的匿名接口

技术图片

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

技术图片

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

技术图片

userId 为0访问需要登录的接口
技术图片

userId 大于0访问需要登录的接口
技术图片

More#

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

Reference#

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

标签:core   art   形式   自己   arc   一个   enc   params   schema   

原文地址:https://www.cnblogs.com/lonelyxmas/p/11904996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!