feat(api): аутентификация и авторизация. Кастомные ParrAuthenticationHandler и BaseSimpleRoleProvider.
This commit is contained in:
48
PARR.API/RoleProvider/BaseSimpleRoleProvider.cs
Normal file
48
PARR.API/RoleProvider/BaseSimpleRoleProvider.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using PARR.API.Services.Interfaces;
|
||||
|
||||
namespace PARR.API.RoleProvider
|
||||
{
|
||||
public class BaseSimpleRoleProvider : ISimpleRoleProvider
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
public BaseSimpleRoleProvider(IServiceProvider serviceProvider)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public async Task<ICollection<string>> GetUserRolesAsync(string ipClient)
|
||||
{
|
||||
// Авторизация - проверка на разрешения
|
||||
// В данном случае, получаем все разрешения (роли)
|
||||
|
||||
ICollection<string> defaultResult = new string[0];
|
||||
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
//var clientService = scope.ServiceProvider.GetRequiredService<IClientService>();
|
||||
|
||||
//var ipClient = clientService.GetClientIp()?.ToString();
|
||||
//if (string.IsNullOrEmpty(ipClient))
|
||||
// return await Task.FromResult(defaultResult);
|
||||
|
||||
var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();
|
||||
|
||||
// проверяем блокировку пользователя
|
||||
var userIsBlocked = await authService.UserIsBlockedAsync(ipClient);
|
||||
if (userIsBlocked)
|
||||
return await Task.FromResult(defaultResult);
|
||||
|
||||
// получаем пользователя из кэша или бд
|
||||
var user = await authService.GetUserAsync(ipClient);
|
||||
if (user == null)
|
||||
return await Task.FromResult(defaultResult);
|
||||
|
||||
|
||||
return user.Roles.Select(t => t.Name).ToList();
|
||||
}
|
||||
|
||||
// return await Task.FromResult(defaultResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
PARR.API/RoleProvider/ISimpleRoleProvider.cs
Normal file
7
PARR.API/RoleProvider/ISimpleRoleProvider.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PARR.API.RoleProvider
|
||||
{
|
||||
public interface ISimpleRoleProvider
|
||||
{
|
||||
Task<ICollection<string>> GetUserRolesAsync(string ipClient);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace PARR.API.RoleProvider
|
||||
{
|
||||
public static class SimpleRoleAuthorizationServiceCollectionExtensions
|
||||
{
|
||||
public static void AddSimpleRoleAuthorization<TRoleProvider>(this IServiceCollection services)
|
||||
where TRoleProvider : class, ISimpleRoleProvider
|
||||
{
|
||||
services.AddSingleton<ISimpleRoleProvider, TRoleProvider>();
|
||||
services.AddSingleton<IClaimsTransformation, SimpleRoleAuthorizationTransform>();
|
||||
}
|
||||
}
|
||||
}
|
||||
39
PARR.API/RoleProvider/SimpleRoleAuthorizationTransform.cs
Normal file
39
PARR.API/RoleProvider/SimpleRoleAuthorizationTransform.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace PARR.API.RoleProvider
|
||||
{
|
||||
public class SimpleRoleAuthorizationTransform : IClaimsTransformation
|
||||
{
|
||||
//private static readonly string RoleClaimType = $"http://{typeof(SimpleRoleAuthorizationTransform).FullName.Replace('.', '/')}/role";
|
||||
private static readonly string RoleClaimType = ClaimTypes.Role;
|
||||
|
||||
private readonly ISimpleRoleProvider roleProvider;
|
||||
|
||||
public SimpleRoleAuthorizationTransform(ISimpleRoleProvider roleProvider)
|
||||
{
|
||||
this.roleProvider = roleProvider ?? throw new ArgumentNullException(nameof(roleProvider));
|
||||
}
|
||||
|
||||
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
|
||||
{
|
||||
// Cast the principal identity to a Claims identity to access claims etc...
|
||||
var oldIdentity = (ClaimsIdentity)principal.Identity!;
|
||||
|
||||
// "Clone" the old identity to avoid nasty side effects.
|
||||
// NB: We take a chance to replace the claim type used to define the roles with our own.
|
||||
var newIdentity = new ClaimsIdentity(
|
||||
oldIdentity.Claims,
|
||||
oldIdentity.AuthenticationType,
|
||||
oldIdentity.NameClaimType,
|
||||
RoleClaimType);
|
||||
|
||||
// Fetch the roles for the user and add the claims of the correct type so that roles can be recognized.
|
||||
var roles = await roleProvider.GetUserRolesAsync(newIdentity.Name!);
|
||||
newIdentity.AddClaims(roles.Select(r => new Claim(RoleClaimType, r)));
|
||||
|
||||
// Create and return a new claims principal
|
||||
return new ClaimsPrincipal(newIdentity);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user