自定义身份验证 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);
}
浙公网安备 33010602011771号