Asp.net-Core
為什麼我需要設置 DefaultForbidScheme
在 WebAPI .net 核心項目中,我創建了一個驗證 api 密鑰的中間件類。通過驗證它,它在呼叫方法中檢索密鑰具有的權限(使用者或管理員)。
我通過一個開關來設置原理
GenericIdentity identity = new GenericIdentity("API"); GenericPrincipal principle = null; //we have a valid api key, so set the role permissions of the key switch (keyValidatorRes.Role) { case Roles.User: principle = new GenericPrincipal(identity, new[] { "User" }); context.User = principle; break; case Roles.Admin: principle = new GenericPrincipal(identity, new[] { "Admin" }); context.User = principle; break; default: principle = new GenericPrincipal(identity, new[] { "Other" }); context.User = principle; break; }在控制器方法上我有
[Authorize(Roles = "Admin")]驗證經過身份驗證的 api 密鑰的角色
如果使用者有管理原則,它會按預期進行。但是,如果它有使用者或其他原則,那麼我會收到關於
沒有 DefaultForbidScheme
我四處搜尋並使用客戶方案將身份驗證添加到我的 startup.cs
services.AddAuthentication(options=> { options.DefaultForbidScheme = "forbidScheme"; options.AddScheme<AuthSchemeHandle>("forbidScheme", "Handle Forbidden"); });並創建了AuthSchemeHandle
public class AuthSchemeHandle : IAuthenticationHandler { private HttpContext _context; public Task<AuthenticateResult> AuthenticateAsync() { return Task.FromResult(AuthenticateResult.NoResult()); } public Task ChallengeAsync(AuthenticationProperties properties) { throw new NotImplementedException(); } public Task ForbidAsync(AuthenticationProperties properties) { return Task.FromResult(AuthenticateResult.Fail("Failed Auth")); } public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) { _context = context; return Task.CompletedTask; } }現在,如果該原則沒有 Admin,它會失敗而不會出現錯誤,但 API 上返回的響應
200沒有內容。我期待4xx回复消息“驗證失敗”我只是想弄清楚為什麼它不像預期的那樣,雖然它看起來“固定”我不明白它是如何修復它的。
我應該這樣做有更好的方法嗎?
為什麼它不像預期的那樣,雖然它似乎“固定”我不明白它是如何修復它的。
IAuthenticationHandler.ForbidAsync()身份驗證處理程序呼叫方法時沒有黑魔法。我們必須自己做相關的事情。簡而言之,StatusCode=403根據需要設置。public async Task ForbidAsync(AuthenticationProperties properties) { properties = properties ?? new AuthenticationProperties(); _context.Response.StatusCode = 403; // ... return Task.CompletedTask; }附帶說明一下,您不需要 return a
Task.FromResult()因為它不關心結果。我應該這樣做有更好的方法嗎?
ASP.NET Core 團隊為我們提供了一個抽像類
AuthenticationHandler來處理身份驗證。這個抽像類有一個內置的實現ForbidAsync(AuthenticationProperties properties)(以及其他公共方法)。所以很容易擴展這個抽像類,如下所示:public class MyAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> { public MyAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { } protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { return AuthenticateResult.NoResult(); } }最後,添加認證服務的配置:
services .AddAuthentication(options=>{ options.DefaultAuthenticateScheme = "forbidScheme"; options.DefaultForbidScheme = "forbidScheme"; options.AddScheme<MyAuthenticationHandler>("forbidScheme", "Handle Forbidden"); });它應該按預期工作。