自定义身份验证 IAuthenticationHandler
自定义身份验证
接口 实现 IAuthenticationHandler
public interface IAuthenticationHandler { Task<AuthenticateResult> AuthenticateAsync(); Task ChallengeAsync(AuthenticationProperties? properties); Task ForbidAsync(AuthenticationProperties? properties); Task InitializeAsync(AuthenticationScheme scheme, HttpContext context); }
通过请求头 信息 获取 用户信息
_context?.Request.Headers["Authorization"];
如果用户信息验证成功 那么生成 ticket
public class CustomerAuthenticationHandler : IAuthenticationHandler { public const string schemeName = "BTest"; private AuthenticationScheme _scheme; private HttpContext _context; public CustomerAuthenticationHandler() { } public async Task<AuthenticateResult> AuthenticateAsync() { StringValues? header = _context?.Request.Headers["Authorization"]; if (!string.IsNullOrEmpty(header) && header.HasValue) { string headerValue = header.Value; string[] array = headerValue.Split('_'); string name = array[1]??throw new ArgumentException(nameof(name)); string password = array[2]??throw new ArgumentException(nameof(password)); string role = array[3] ?? throw new ArgumentException(nameof(role)); //这里查询数据库 if (name == "test") { var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, name), new Claim("userID", password), new Claim(ClaimTypes.Role, role) }, schemeName) ; ClaimsPrincipal claimsPrincipal = new System.Security.Claims.ClaimsPrincipal(claimsIdentity); AuthenticationTicket authenticationTicket = new(claimsPrincipal, schemeName); await Task.Delay(1); return AuthenticateResult.Success(authenticationTicket); } return AuthenticateResult.Fail("身份验证不通过"); } else { return AuthenticateResult.Fail("身份验证不通过"); } } /// <summary> /// 没有登陆的情况 /// </summary> /// <param name="properties"></param> /// <returns></returns> public Task ChallengeAsync(AuthenticationProperties? properties) { _context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return Task.CompletedTask; } /// <summary> /// 拒绝的情况 /// </summary> /// <param name="properties"></param> /// <returns></returns> public Task ForbidAsync(AuthenticationProperties? properties) { _context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return Task.CompletedTask; } public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) { _context = context; _scheme = scheme; return Task.CompletedTask; } }
两个项目测试 一个请求 一个响应
注入
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CustomerAuthenticationHandler.schemeName;
options.DefaultScheme = CustomerAuthenticationHandler.schemeName;
options.AddScheme<CustomerAuthenticationHandler>(CustomerAuthenticationHandler.schemeName,
CustomerAuthenticationHandler.schemeName);
});
这里简单的将用户信息 传递出去了 正常应该做一些加密 例如md5 散列算法
public interface IBaseToken { string Name { get; } string Create(); } public class BearerToken : IBaseToken { public string Name => "Bearer"; public string Create() { return "test_111_User"; } }
[HttpGet("Send")] public async Task<IActionResult> Send() { using HttpClient client = _httpClientFactory.CreateClient(); client.BaseAddress = new Uri("http://localhost:5006/api/users"); using HttpRequestMessage requestMessage = new HttpRequestMessage(); string token = _baseToken.Create(); requestMessage.Headers.Add("Authorization", $"BTest_{token}"); using HttpResponseMessage responseMessage = await client.SendAsync(requestMessage); //if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK) //{ // string content = await responseMessage.Content.ReadAsStringAsync(); // await Console.Out.WriteLineAsync(content); //} //else //{ //} string content = await responseMessage.Content.ReadAsStringAsync(); await Console.Out.WriteLineAsync(content); return Ok(content); }