ASP.NETCore编程实现基本认证
HTTP基本認證
????在HTTP中,HTTP基本認證(Basic Authentication)是一種允許瀏覽器或其他客戶端程序使用(用戶名,口令)請求資源的身份驗證方式,不要求cookie,session identifier、login page等標記或載體。??
所有瀏覽器據支持HTTP基本認證協議
基本身證原理不保證傳輸憑證的安全性,僅被based64編碼,并沒有encrypted或者hashed,一般部署在互信的內網,在公網上應用BA協議通常與https結合。
BA標準協議
??? BA協議的實施主要依靠約定的請求頭/響應頭,?典型的瀏覽器和服務器的BA認證流程:
① 瀏覽器請求應用了BA的網站,服務端響應一個401認證失敗響應碼,并寫入WWW-Authenticate響應頭,指示服務端支持BA協議。
HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="our site"或在初次請求時發送正確Authorization標頭,從而避免被質詢
②?客戶端以based64(用戶名:口令) 作為Authorization標頭值,重新發送請求:
Authorization: Basic userid:password
認證的范圍與realm相關,準確的realm由服務端定義,因為服務端可能有多個不同的realm.
> 瀏覽器客戶端,對于WWW-Authenticate響應頭彈出了口令輸入窗。
BA編程實踐
? ? ?ASP.NET Core網站利用FileServerMiddleware將部分路徑映射到文件資源,對該資源訪問路徑應用Http基本認證。
服務端實現BA認證
? ? ?①? 實現基本認證Handler:認證、無口令質詢、質詢失敗邏輯
# ...... namespace?EqidManager.Services {public static class BasicAuthenticationScheme{public const string DefaultScheme = "Basic";}public class BasicAuthenticationOption:AuthenticationSchemeOptions{public string Realm { get; set; }public string UserName { get; set; }public string UserPwd { get; set; }}public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOption>{private readonly BasicAuthenticationOption authOptions;public BasicAuthenticationHandler(IOptionsMonitor<BasicAuthenticationOption> options,ILoggerFactory logger,UrlEncoder encoder,ISystemClock clock): base(options, logger, encoder, clock){authOptions = options.CurrentValue;}/// <summary>/// 認證邏輯///?</summary>protected override async Task<AuthenticateResult> HandleAuthenticateAsync(){if (!Request.Headers.ContainsKey("Authorization"))return AuthenticateResult.Fail("Missing Authorization Header");string username, password;try{var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);var credentialBytes = Convert.FromBase64String(authHeader.Parameter);var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':');username = credentials[0];password = credentials[1];var isValidUser= IsAuthorized(username,password);if(isValidUser==?false)return?AuthenticateResult.Fail("Invalid?username?or?password");}catchreturn?AuthenticateResult.Fail("Invalid?Authorization?Header");var claims = new[] {new Claim(ClaimTypes.NameIdentifier,username),new Claim(ClaimTypes.Name,username),};var identity = new ClaimsIdentity(claims, Scheme.Name);var principal = new ClaimsPrincipal(identity);var ticket = new AuthenticationTicket(principal, Scheme.Name);return await Task.FromResult(AuthenticateResult.Success(ticket));}/// <summary>/// 質詢/// </summary>protected override async Task HandleChallengeAsync(AuthenticationProperties properties){Response.Headers["WWW-Authenticate"] = $"Basic realm=\"{Options.Realm}\"";await base.HandleChallengeAsync(properties);}/// <summary>/// 認證失敗///?</summary>protected override async Task HandleForbiddenAsync(AuthenticationProperties properties){await base.HandleForbiddenAsync(properties); }private bool IsAuthorized(string username, string password){return username.Equals(authOptions.UserName, StringComparison.InvariantCultureIgnoreCase)&& password.Equals(authOptions.UserPwd);}} }? ???②??實現BasicAuthenticationMiddleware: 要求對HttpContext應用BA Scheme。
// HTTP基本認證Middlewarepublic static class BasicAuthentication{public static void UseBasicAuthentication(this IApplicationBuilder app){app.UseMiddleware<BasicAuthenticationMiddleware>();}} public class BasicAuthenticationMiddleware {private readonly RequestDelegate _next;private?readonly?ILogger?_logger;public BasicAuthenticationMiddleware(RequestDelegate next, ILoggerFactory LoggerFactory){_next = next;_logger = LoggerFactory.CreateLogger<BasicAuthenticationMiddleware>();}public async Task Invoke(HttpContext httpContext, IAuthenticationService authenticationService){var authenticated = await authenticationService.AuthenticateAsync(httpContext, BasicAuthenticationScheme.DefaultScheme);_logger.LogInformation("Access Status:" + authenticated.Succeeded);if (!authenticated.Succeeded){await authenticationService.ChallengeAsync(httpContext, BasicAuthenticationScheme.DefaultScheme, new AuthenticationProperties { });return;}await _next(httpContext);} }? ? ?③??ASP.NET?Core?添加BA?Scheme?, 為待認證資源路徑啟用BA中間件,注意這里使用UseWhen插入中間件。
services.AddAuthentication(BasicAuthenticationScheme.DefaultScheme).AddScheme<BasicAuthenticationOption, BasicAuthenticationHandler>(BasicAuthenticationScheme.DefaultScheme,null); app.UseWhen(predicate:x => x.Request.Path.StartsWithSegments(new PathString(_protectedResourceOption.Path)),configuration:appBuilder => { appBuilder.UseBasicAuthentication();});現可在瀏覽器測試:
進一步思考?
以上是瀏覽器在BA協議中的行為:可嘗試程序自動向服務端發起BA請求,需要的同學看博客園源碼。
That's All . ?BA認證是常見的基礎認證協議,文章期待以清晰的方式傳遞協議原理和編程實現,要的同學閱讀原文。
往期精選
ASP.NET Core跨平臺技術內幕
AspNetCore結合Redis實踐消息隊列
實例解讀Docker Swarm?
基于docker-compose的Gitlab CI/CD實踐&排坑指南
?
總結
以上是生活随笔為你收集整理的ASP.NETCore编程实现基本认证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel催化剂回顾2019年产出(文章
- 下一篇: 使用ASP.NET Core 3.x 构