Как проверить, находится ли текущий пользователь в одной роли?
В моем приложении у меня может быть пользователь с несколькими ролями, но некоторые роли, такие как Role1
, имеют определенное поведение.
Как изолировать конкретное поведение от Role1
, когда у пользователя есть две роли (Role1
и Role2
)?
Если пользователь находится в Role2
, то у него должно быть другое поведение, даже если он тоже находится в Role1
.
Решение, которое я придумал, было
if (User.IsInRole(Role1.ToString()) && !User.IsInRole(Role2.ToString()))
{
//implementation
}
Есть ли другой способ сделать это? Может быть, с помощью политик?
Я думаю, что политика это лучший подход к вашему случаю. Создайте политику, которая использует RequireAssertion в построителе
См. этот пост: Авторизация на основе ролей в ASP.NET Core 3.1 с Identity и ExternalLogin
Есть ссылка или дополнительная информация о том, как это сделать?
Как проверить, находится ли текущий пользователь в одной роли?
После успешного входа пользователя вы можете использовать метод UserManager.GetRoleAsync(), чтобы получить список имен ролей, к которым принадлежит указанный пользователь. Затем на основе результата проверить, находится ли пользователь в одной роли.
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
var user = _userManager.FindByEmailAsync(Input.Email).Result;
var roles = _userManager.GetRolesAsync(user).Result.ToArray();
// then, based on the roles array to check if the current user is in a single role.
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
Скриншот, как показано ниже:
Как изолировать конкретное поведение от роли 1, когда у пользователя есть два роли (роль1 и роль2)? Если пользователь находится в роли 2, он должен иметь другое поведение, даже если они также находятся в роли1. Есть ли другой способ сделать это? Может быть, с помощью политик?
Да, авторизация на основе политик — хороший выбор. Например, в моем примере есть 3 вида ролей: администратор, менеджер и пользователь.
Мы могли бы создать следующие политики в файле Startup.cs:
services.AddAuthorization(options => {
options.AddPolicy("readpolicy",
builder => builder.RequireRole("Admin", "Manager", "User"));
options.AddPolicy("writepolicy",
builder => builder.RequireRole("Admin", "Manager"));
});
Затем мы применим эти политики к контроллеру ролей, как показано ниже:
[Authorize(Policy = "readpolicy")]
public IActionResult Index()
{
var roles = roleManager.Roles.ToList();
return View(roles);
}
[Authorize(Policy = "writepolicy")]
public IActionResult Create()
{
return View(new IdentityRole());
}
Теперь мы можем на основе политики вызывать метод действия.
Ссылка:
Добавление авторизации роли в основное приложение ASP.NET MVC
Авторизация на основе политик в ASP.NET Core
Это не решило мою проблему, но помогло мне, когда я кодировал решение.
Решением для меня было создание метода, который проверяет, был ли пользователь в какой-либо из ролей:
public async Task<bool> IsInAnyRoleAsync(TUser user, RoleEnum[] roles)
{
var userIsInRole = new List<bool>();
foreach (var role in roles)
{
var roleName = Enum.GetName(role.GetType(), role);
userIsInRole.Add(await IsInRoleAsync(user, roleName));
}
return userIsInRole.Any(isInRole => isInRole == true);
}
Использование:
await _userManager.IsInAnyRoleAsync(user, [Role1, Role2]);
ИМХО, вы должны кодировать права (или) разрешения (или) «претензии». Это недальновидно и сложно поддерживать код, написанный для ролей. Рассмотрим: granadacoder.wordpress.com/2010/12/01/…