日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

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

發布時間:2023/12/4 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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")

  • 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 中的代碼:

  • [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 配置:

  • 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

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

    總結

    以上是生活随笔為你收集整理的asp.net core 自定义 Policy 替换 AllowAnonymous 的行为的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。