Я реализовал решение, которое позволяет мне предотвратить несколько сеансов пользователей для одной и той же учетной записи.
Для этого в методе ConfigureServices
я добавил следующую конфигурацию:
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<SoccerForecastContext>()
.AddDefaultTokenProviders();
var defaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddRequirements(new ValidSessionRequirement())
.Build();
services.AddAuthorization(options =>
{
options.DefaultPolicy = defaultPolicy;
});
services.AddScoped<IUserClaimsPrincipalFactory<User>, ApplicationClaimsPrincipalFactory>();
services.AddTransient<IAuthorizationHandler, ValidSessionHandler>();
По существу для каждого запроса конвейер будет вызывать
public class ApplicationClaimsPrincipalFactory : UserClaimsPrincipalFactory<User>
{
private readonly UserManager<User> _userManager;
public ApplicationClaimsPrincipalFactory(UserManager<User> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor)
{
_userManager = userManager;
}
public async override Task<ClaimsPrincipal> CreateAsync(User user)
{
var claims = await _userManager.GetClaimsAsync(user);
var session = claims.Where(e => e.Type == "session");
await _userManager.RemoveClaimsAsync(user, session);
await _userManager.AddClaimAsync(user, new Claim("session", Guid.NewGuid().ToString()));
var principal = await base.CreateAsync(user);
return principal;
}
}
класс ValidSessionRequirement
просто наследует, что:
public class ValidSessionRequirement : IAuthorizationRequirement
{
}
Теперь, если я вызову этот метод:
[HttpGet]
[Authorize(Roles = "Customer, Admin, SuperAdmin")]
public async Task<IActionResult> Profile()
{
Я получаю: AccessDenied
, но роль пользователя будет SuperAdmin
, если я удаляю логику над всеми работами, как ожидалось, есть идеи?