基本身份认证Basic Authentication,简称BA认证
概览
      
 HTTP基本身份验证是一种最简单的web资源访问控制的技术,客户端携带username、password去请求服务器资源,不要求cookie,session 
identifier、login page等标记或载体。
基本身份认证过程主要在header特定字段中体现,不需要handshakes。
https://en.wikipedia.org/wiki/Basic_access_authentication 
<https://en.wikipedia.org/wiki/Basic_access_authentication>
特征
        基本身份认证协议不保证传输凭证的安全性,他们仅仅只是被based64编码,并没有encrypted或者hashed,因此Basic 
Authentication为了保密性通常与https结合一起使用。
因为基本身份认证字段必须在HTTP Header 中发送,所以web 
browser需要在一个合理的时间内缓存凭据,缓存策略因浏览器不同而异,IE默认缓存15 分钟。 
HTTP不会为客户端提供一个logout方法,但是有很多方法在浏览器中可以清除缓存凭据。
<script>document.execCommand('ClearAuthenticationCache');</script> 
 
BA认证的标准协议
客户端
客户端使用Authorization Request header 发送认证凭据,凭据生成方式如下:
 * 
username、password字段以冒号分隔(username不能包含冒号)
 * 
string ---> 字节
 * 
Baseed64编码
 * 
在编码后字符串前加上Authorization 方法和一个空格
Authorization: Basic RmlzYWRzYWQ6YXNkYWRz 
服务端
当服务端设定了基本身份认证服务时,服务端要给未通过认证请求适当的认证提示:
response status code:401 (Unauthorized)
repsonse header:WWW-Authenticate
HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="180.76.176.244" 
        客户端表现如下图:
  
BA认证的日常应用、实现
日常应用
       IIS自带基本身份验证,以下是在IIS website中配置使用基本身份认证:
 
以.NetCore实践BA认证
 服务端:
 * 
实现基本身份认证Handler, 包含认证方式、认证挑战的提示
 * 
.netcore 添加认证中间件
 * 
注册认证中间件
public class BasicAuthenticationHandler : 
AuthenticationHandler<BasicAuthenticationOption> { private 
BasicAuthenticationOption authOptions;public BasicAuthenticationHandler( 
IOptionsMonitor<BasicAuthenticationOption> options, ILoggerFactory logger, 
UrlEncoder encoder, ISystemClock clock) :base(options, logger, encoder, clock) 
{ authOptions= options.CurrentValue; } /// <summary> /// BA认证过程 /// </summary> 
/// <returns></returns> 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"); } } catch { return 
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> /// 
重写该方法以体现身份验证挑战(401)时发生时提示 /// </summary> /// <param name="properties"></param> 
/// <returns></returns> protected override async Task 
HandleChallengeAsync(AuthenticationProperties properties) { Response.Headers["
WWW-Authenticate"] = $"Basic realm=\"{Options.Realm}\",charset=\"utf-8\""; await
base.HandleChallengeAsync(properties); } /// <summary> 进行BA认证,此处不关注该方法 /// 
override the method to influence what happens when an forbidden response (403)
/// </summary> /// <param name="properties"></param> /// <returns></returns> 
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); } } 
 
// 添加BA认证计划
services.AddAuthentication(BasicAuthentication.DefaultScheme) .AddScheme
<BasicAuthenticationOption, 
BasicAuthenticationHandler>(BasicAuthentication.DefaultScheme,null); 
 
// 这里我使用UseWhen启用一个中间件: 对某些路径开启BA认证
app.UseWhen( predicate:x => x.Request.Path.StartsWithSegments(new 
PathString(_protectedResourceOption.Path)), configuration:appBuilder=> 
appBuilder.UseAuthentication() ); 
 
客户端:
 *  添加认证请求Handler 
 *  以上述Handler 配置命名HtttpClient /// <summary> /// BA认证请求Handler
 /// </summary> public class BasicAuthenticationClientHandler : 
HttpClientHandler {public static string BAHeaderNames = "authorization"; private
 RemoteBasicAuth _remoteAccount;public 
BasicAuthenticationClientHandler(RemoteBasicAuth remoteAccount) { _remoteAccount
= remoteAccount; AllowAutoRedirect = false; UseCookies = true; } protected 
override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, 
CancellationToken cancellationToken) {var authorization = $"
{_remoteAccount.UserName}:{_remoteAccount.Password}"; var authorizationBased64 =
"Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization)); 
request.Headers.Remove(BAHeaderNames); request.Headers.Add(BAHeaderNames, 
authorizationBased64);return base.SendAsync(request, cancellationToken); } } 
 
// 配置命名HttpClient
services.AddHttpClient("eqid-ba-request", x => x.BaseAddress = new 
Uri(_proxyOption.Scheme +"://"+ _proxyOption.Host+":"+_proxyOption.Port ) ) 
.ConfigurePrimaryHttpMessageHandler(y=> new 
BasicAuthenticationClientHandler(_remoteAccount){} ) 
.SetHandlerLifetime(TimeSpan.FromMinutes(2)) 
.AddPolicyHandler(GetRetryPolicy()); 
 
以上应该是从协议、场景、实现讲述了BA认证的全部知识点 。
 
--------------如果你觉得文章对你有价值,请点赞或者关注;如有问题请大胆斧正,蟹蟹--------------~~。。~~
--------------
热门工具 换一换