成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊在 .Net 5.0 中自定義授權響應

開發 后端
從 .NET 5.0 開始,您現在可以通過實現IAuthorizationMiddlewareResultHandler接口來自定義 HTTP 響應;當授權失敗時,授權框架會自動調用中間件。

[[416103]]

本文轉載自微信公眾號「DotNET技術圈」,作者Ben Foster 。轉載本文請聯系DotNET技術圈公眾號。

在 .NET 5.0 中自定義授權響應

ASP.NET Core 授權框架中經常要求的[1]一項功能是能夠在授權失敗時自定義 HTTP 響應。

以前,唯一的方法是IAuthorizationService直接在您的控制器中(或通過過濾器)調用授權服務 ,類似于基于資源的授權方法[2]或實現您自己的授權過濾器[3]。

從 .NET 5.0 開始,您現在可以通過實現IAuthorizationMiddlewareResultHandler接口來自定義 HTTP 響應;當授權失敗時,授權框架會自動調用中間件。

這是 記錄[4]在微軟文檔的網站,但根據我的具體使用情況我花了不少時間才找到。

問題

我一直在采取措施將舊的 ASP.NET Web API 應用程序移植到 .NET Core 5.0。此 API 具有分層 URI 結構,因此大多數端點將位于“站點”資源下,例如:

  • /sites
  • /sites/{siteId}
  • /sites/{siteId}/blog

為了驗證用戶是否有權訪問指定站點,該應用程序以前使用自定義操作過濾器來提取siteId路由參數并根據用戶的聲明對其進行驗證。遷移到 .NET 5.0 我想利用授權框架來實現這種基于資源的授權,但同樣不想在每個控制器中復制這個邏輯。

我的解決方案是實現一個執行類似操作的授權處理程序,獲取siteId參數并驗證用戶的訪問權限:

  1. public class SiteAccessAuthorizationHandler : AuthorizationHandler<SiteAccessRequirement> 
  2.     private const string SiteIdRouteParameter = "siteId"
  3.     private readonly ILogger<SiteAccessAuthorizationHandler> _logger; 
  4.  
  5.     public SiteAccessAuthorizationHandler(ILogger<SiteAccessAuthorizationHandler> logger) 
  6.     { 
  7.         _logger = logger.NotNull(nameof(logger)); 
  8.     } 
  9.  
  10.     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SiteAccessRequirement requirement) 
  11.     { 
  12.         context.NotNull(nameof(context)); 
  13.         requirement.NotNull(nameof(requirement)); 
  14.  
  15.         if (context.Resource is HttpContext httpContext 
  16.             && httpContext.GetRouteData().Values.TryGetValue(SiteIdRouteParameter, out object? routeValue) 
  17.             && routeValue is string siteId) 
  18.         { 
  19.             string qualifiedId = $"sites/{siteId}"
  20.             AccountPrincipal account = context.User.ToAccount(); 
  21.  
  22.             _logger.LogDebug("Validating access to Site {SiteId} from User {UserId}.", qualifiedId, account.GetAuthIdentifier()); 
  23.  
  24.             if (account.CanAccessSite(qualifiedId)) 
  25.             { 
  26.                 context.Succeed(requirement); 
  27.             } 
  28.             else 
  29.             { 
  30.                 _logger.LogWarning("Site validation failed. User {UserId} is not permitted to access {SiteId}.", account.GetAuthIdentifier(), qualifiedId); 
  31.             } 
  32.         } 
  33.  
  34.         return Task.CompletedTask; 
  35.     } 

然后將其注冊為授權策略的一部分:

  1. services.AddAuthorization(options => 
  2. {                 
  3.     options.FallbackPolicy = Policies.FallbackPolicy; 
  4.     options.AddPolicy("SiteAccess", Policies.SiteAccessPolicy); 
  5. }) 
  6.  
  7. public static AuthorizationPolicy SiteAccessPolicy => 
  8.     ConfigureDefaults(new AuthorizationPolicyBuilder()) 
  9.         .AddRequirements(new SiteAccessRequirement()) 
  10.         .Build(); 
  11.  
  12. private static AuthorizationPolicyBuilder ConfigureDefaults(AuthorizationPolicyBuilder builder) 
  13.     => builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) 
  14.         .RequireAuthenticatedUser() 
  15.         .RequireClaim(JwtClaimTypes.ClientId); 

并應用于控制器和/或動作:

  1. [Authorize(Policy = "SiteAccess")] 
  2. [HttpGet("{siteId}"Name = RouteNames.SiteRoute)] 
  3. public async Task<IActionResult> GetSiteAsync(string siteId, CancellationToken cancellationToken) 
  4.     var site = await _session.LoadAsync<CMS.Domain.Site>($"sites/{siteId}", cancellationToken); 
  5.     return site is null ? NotFound() : Ok(Enrich(_mapper.Map<Site>(site), true)); 

當我嘗試訪問未映射到當前用戶的站點時,我會收到HTTP 403 - Forbidden響應。

這樣雖然達到了保護站點資源的目的,但也存在泄露用戶無權訪問的站點信息的弊端。因此最好返回一個HTTP 404 - Not Found響應。考慮到該站點不存在于用戶的站點資源集合中,這在語義上也是有意義的。

如果您想知道為什么我不只是將用戶過濾器作為查詢的一部分,那是因為用戶/帳戶與內容域是分開的,并且由于數據模型的設計以及我使用的事實鍵值存儲,驗證訪問的責任轉移到應用層。

解決方案

為了實現上述目標,我們可以使用 newIAuthorizationMiddlewareResultHandler并創建一個處理程序,當由于我的站點訪問要求未得到滿足而導致授權失敗時,該處理程序會轉換 HTTP 響應:

  1. public class AuthorizationResultTransformer : IAuthorizationMiddlewareResultHandler 
  2.     private readonly IAuthorizationMiddlewareResultHandler _handler; 
  3.  
  4.     public AuthorizationResultTransformer() 
  5.     { 
  6.         _handler = new AuthorizationMiddlewareResultHandler(); 
  7.     } 
  8.  
  9.     public async Task HandleAsync( 
  10.         RequestDelegate requestDelegate, 
  11.         HttpContext httpContext, 
  12.         AuthorizationPolicy authorizationPolicy, 
  13.         PolicyAuthorizationResult policyAuthorizationResult) 
  14.     { 
  15.         if (policyAuthorizationResult.Forbidden && policyAuthorizationResult.AuthorizationFailure != null
  16.         { 
  17.             if (policyAuthorizationResult.AuthorizationFailure.FailedRequirements.Any(requirement => requirement is SiteAccessRequirement)) 
  18.             { 
  19.                 httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; 
  20.                 return
  21.             } 
  22.  
  23.             // Other transformations here 
  24.         } 
  25.  
  26.         await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, policyAuthorizationResult); 
  27.     } 

在上面的代碼中,我檢查授權失敗(結果是禁止)和失敗的要求,相應地更改HTTP狀態代碼;否則我們通過調用內置的AuthorizationMiddlewareResultHandler.

為了連接自定義處理程序,它在啟動時注冊:

  1. services.AddAuthorization(options => 
  2. {                 
  3.     options.FallbackPolicy = Policies.FallbackPolicy; 
  4.     options.AddPolicy("SiteAccess", Policies.SiteAccessPolicy); 
  5. }) 
  6. .AddSingleton<IAuthorizationMiddlewareResultHandler, AuthorizationResultTransformer>(); 

References

[1] 經常要求的: https://github.com/dotnet/aspnetcore/issues/4670

[2] 基于資源的授權方法: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/resourcebased?view=aspnetcore-5.0

[3] 實現您自己的授權過濾器: https://ignas.me/tech/custom-unauthorized-response-body/

[4] 記錄: https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/customizingauthorizationmiddlewareresponse?view=aspnetcore-5.0

 

責任編輯:武曉燕 來源: DotNET技術圈
相關推薦

2021-07-11 17:17:08

.NET 授權自定義

2011-06-15 09:24:36

Qt Widget Model

2023-01-03 07:40:27

自定義滑塊組件

2024-08-09 09:02:56

2011-06-20 16:54:40

Qt Widget model

2024-06-03 10:00:51

Vue 3語法插槽

2009-09-03 13:34:03

.NET自定義控件

2021-11-23 15:06:42

Kubernetes 運維開源

2009-07-06 13:49:29

2024-04-02 09:52:12

自定義返回類API開發

2009-04-09 09:51:09

ASP.NETSQL Server 自定義分頁

2009-08-04 13:35:16

ASP.NET自定義樣

2009-08-06 17:13:56

ASP.NET自定義控

2009-11-12 16:14:28

ADO.NET自定義對

2009-07-31 15:42:38

自定義providerASP.NET2.0

2018-07-12 16:22:45

Linux命令行文本顏色

2009-07-28 09:32:41

ASP.NET自定義控

2009-08-10 14:16:59

ASP.NET自定義控

2024-03-05 08:05:37

2009-11-10 17:12:22

VB.NET自定義類型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品中文字幕 | 久久国内精品 | 中国大陆高清aⅴ毛片 | 自拍偷拍一区二区三区 | 福利精品| 中文字幕第九页 | 99精品国产一区二区三区 | 日本成人在线免费视频 | 久久综合成人精品亚洲另类欧美 | 久久精品国产一区 | 久久久新视频 | 99亚洲精品 | 日韩欧美成人一区二区三区 | 日本精品一区二区三区在线观看视频 | 久久国产美女视频 | 欧美成人手机视频 | 欧美精品1区2区3区 免费黄篇 | 国产精品免费一区二区三区 | 国产乱码精品1区2区3区 | 视频一二三区 | 欧美日韩亚洲在线 | 国产精品日日做人人爱 | 亚洲成人免费观看 | 日韩欧美亚洲 | 欧美日韩一区二区视频在线观看 | 黄色网毛片 | 一区二区三区国产视频 | 欧美一级大片免费观看 | 日韩精品在线观看一区二区三区 | 国产日韩91 | 天天躁日日躁狠狠的躁天龙影院 | 涩爱av一区二区三区 | 国产成人精品综合 | 精品熟人一区二区三区四区 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 久久se精品一区精品二区 | ww亚洲ww亚在线观看 | 亚洲欧美精品在线 | 91在线观看 | 91久久久精品国产一区二区蜜臀 | 免费av一区二区三区 |