先貼認證授權官方文檔 https://docs.microsoft.com/zh-cn/aspnet/core/security
認證:又叫身份驗證,由用戶提供憑據,然后將其與存儲在操作系統、數據庫、應用或資源中的憑據進行比較。 在授權過程中,如果憑據匹配,則用戶身份驗證成功,可執行已向其授權的操作。
授權:判斷允許用戶執行的操作的過程。
在需要身份驗證的web服務中,經常存在一個網站需要滿足多種身份驗證的需求,asp.net core 框架提供的認證授權功能已經支持這種操作;
日常可能有兩種情況:
1. 不同的認證token 訪問的接口不同,比如后台管理的接口和前台用戶的接口放在一個web 項目中,分別提供不同路由;
2. 不同的認證token 訪問的接口相同,比如前台用戶認證有多種認證方式,都能訪問相同路由;
准備基礎代碼:
這里用兩個JWT認證模擬兩個不同的認證方案 AuthSettings.AdminScheme 、 AuthSettings.UserScheme
builder.Services.AddAuthentication(AuthSettings.AdminScheme) .AddJwtBearer(AuthSettings.AdminScheme, options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidIssuer = AuthSettings.AdminIssuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthSettings.AdminSecret)) }; }) .AddJwtBearer(AuthSettings.UserScheme, options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidIssuer = AuthSettings.UserIssuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthSettings.UserSecret)) }; });
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
1. 不同的認證token 訪問的接口不同
對於情況1,我們一般直接在 options.ForwardDefaultSelector 寫上獲取認證方案的邏輯就能實現動態切換認證方案,你可以根據路由地址,header 參數等自定義你想要執行的認證方案
builder.Services.AddAuthentication(AuthSettings.AdminScheme) .AddJwtBearer(AuthSettings.AdminScheme, options => {//動態轉發方案 options.ForwardDefaultSelector = content => { return content.Request.Path.Value!.Contains(AuthSettings.UserUrlBase) ? AuthSettings.UserScheme : null; }; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidIssuer = AuthSettings.AdminIssuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthSettings.AdminSecret)) }; }) .AddJwtBearer(AuthSettings.UserScheme, options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidIssuer = AuthSettings.UserIssuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthSettings.UserSecret)) }; });
當然,如果你不想這樣操作,也有針對接口的操作,你只需要在接口處申明你要執行的認證方案就行
[HttpGet("test4")] [Authorize(AuthenticationSchemes = AuthSettings.UserScheme)] public async Task<IActionResult> Test4() { return new JsonResult(new { Code = "OK" }) { StatusCode = (int)HttpStatusCode.OK }; }
當然也有針對授權策略的認證方案指定
builder.Services.AddAuthorization(options => {
options.AddPolicy("ClaimNamePolicy", options => {
options.AuthenticationSchemes = new[] { AuthSettings.UserScheme };
options.RequireClaim("ClaimName", "test2");
});
});
[HttpGet("test3")]
[Authorize("ClaimNamePolicy")]
public async Task<IActionResult> Test3()
{
return new JsonResult(new { Code = "OK" }) { StatusCode = (int)HttpStatusCode.OK };
}
以上三種方式都可以指定你想要的認證方案;
2. 不同的認證token 訪問的接口相同
對於不同的認證token 訪問相同接口,我們一般直接重新配置默認的授權策略,指定多個方案即可
builder.Services.AddAuthorization(options => {
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(new string[] { AuthSettings.UserScheme, AuthSettings.AdminScheme })
.Build();
});
使用比較簡單,但是里面有很多框架的邏輯需要理解,想要深入研究的,建議去看看 asp.net core 源碼