feat(api): аутентификация и авторизация. Кастомные ParrAuthenticationHandler и BaseSimpleRoleProvider.

This commit is contained in:
Mikhail Trubnikov
2023-12-01 16:41:37 +10:00
parent 78f2310199
commit d0c309e642
23 changed files with 395 additions and 11 deletions

View File

@@ -0,0 +1,8 @@
namespace PARR.API.Authentication.Models
{
public class UserCache
{
public required string UserIp { get; set; }
public List<UserRoleInCache> Roles { get; set; } = new List<UserRoleInCache>();
}
}

View File

@@ -0,0 +1,8 @@
namespace PARR.API.Authentication.Models
{
public class UserRoleInCache
{
public required string Name { get; set; }
public required string Description { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using PARR.API.Services.Interfaces;
using System.Security.Claims;
using System.Text.Encodings.Web;
namespace PARR.API.Authentication
{
public class ParrAuthenticationHandler : AuthenticationHandler<ParrAuthenticationOptions>
{
private readonly IServiceProvider serviceProvider;
public ParrAuthenticationHandler(
IOptionsMonitor<ParrAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
IServiceProvider serviceProvider) : base(options, logger, encoder, clock)
{
this.serviceProvider = serviceProvider;
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var ipClient = Request.HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString();
if (ipClient == null)
return AuthenticateResult.Fail($"IP address not defined.");
// Аутентификация - просто проверка, есть ли у нас такой пользователь
using (var scope = serviceProvider.CreateScope())
{
var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();
var userIsBlocked = await authService.UserIsBlockedAsync(ipClient);
if (userIsBlocked)
return AuthenticateResult.Fail($"IP address is on the blocking list.");
var user = await authService.GetUserAsync(ipClient);
if (user == null)
return AuthenticateResult.Fail($"IP address not defined.");
// пользователь найден, аутентификация пройдена
var claims = new List<Claim> {
new Claim(ClaimTypes.Name, user.UserIp)
};
var claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
return AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name));
}
}
}
}

View File

@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Authentication;
namespace PARR.API.Authentication
{
public class ParrAuthenticationOptions : AuthenticationSchemeOptions
{
public const string DefaultScheme = "ParrAuthenticationScheme";
//public string TokenHeaderName { get; set; } = "MyToken";
}
}