ASP.NET Core 2 авторизация из таблицы базы данных - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть серия веб-страниц, и авторизация для этих страниц определяется в пользовательской таблице базы данных.Например, у меня есть роль, называемая «суперпользователь», и этой роли разрешен доступ на определенных веб-страницах.У меня есть пользователи, которым назначена эта роль.

Я не понимаю, как я могу поместить атрибут Authorize на контроллер и передать имя страницы (представление), а затем иметь собственный обработчик некоторого типа, считанный измоя база данных, чтобы увидеть, если пользователь находится в группе, которая имеет разрешение.Я читал об авторизации на основе политик здесь: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2 и пытаюсь понять ее для моей ситуации.

Я на правильном пути с авторизацией на основе политик или есть другаяспособ сделать проверку базы данных для разрешения, прежде чем разрешить пользователю доступ к странице?

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

.Net Core -> если вы собираетесь использовать подход, основанный на политике, вы должны определить определение политики в методе ConfigureServices в файле startup.cs

Пример:

 services.AddAuthorization(options =>
            {
                options.AddPolicy("UserPolicy", policy => policy.RequireRole("USER"));
            });

Тогда вы можетеприменить политику, как показано ниже в контроллере или методе действия.

Авторизовать (Policy = "UserPolicy")

0 голосов
/ 14 декабря 2018

Атрибут Authorize сам по себе служит только для указания вида авторизации, который вам необходим на определенной странице или контроллере.Этот атрибут предназначен для использования в дополнение к платформе Identity и может включать роли, политики и схемы аутентификации.

Вам нужно создать мост между платформой Identity и вашей базой данных, что можно сделать с помощью пользовательских UserStore и RoleStore, что подробно описано на этой странице .

Подводя итог довольно сложному процессу:

  1. Атрибут Authorize указывает браузеру аутентифицировать вашего пользователя
  2. Ваш пользователь перенаправлен на страницу аутентификации
  3. Если это удастся, вам предоставляется экземпляр ClaimsPrincipal, который затем необходимо сопоставить с пользователем вашей базы данных с помощью пользовательского UserStore
  4. . Затем ваш пользователь может проверитьРоли в БД

Вот краткий пример всего этого в действии (НЕ полностью завершенного, потому что это будет слишком много кода).

Startup.cs

// This class is what allows you to use [Authorize(Roles="Role")] and check the roles with the custom logic implemented in the user store (by default, roles are checked against the ClaimsPrincipal roles claims)
public class CustomRoleChecker : AuthorizationHandler<RolesAuthorizationRequirement>
{
    private readonly UserManager<User> _userManager;

    public CustomRoleChecker(UserManager<User> userManager)
    {
        _userManager = userManager;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)
    {
        var user = await _userManager.GetUserAsync(context.User);

        // for simplicity, I use only one role at a time in the attribute
        var singleRole = requirement.AllowedRoles.Single();
        if (await _userManager.IsInRoleAsync(user, singleRole))
            context.Succeed(requirement);
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services
    .AddIdentity<User, Role>()
    .AddUserStore<MyUserStore>()
    .AddRoleStore<MyRoleStore>();

    // custom role checks, to check the roles in DB 
   services.AddScoped<IAuthorizationHandler, CustomRoleChecker>();
}

, где User и Role - ваши основные объекты EF.

MyUserStore

public class MyUserStore : IUserStore<User>, IUserRoleStore<User>, IQueryableUserStore<User>
{
    private Context _db;
    private RoleManager<Role> _roleManager;
   ...

    public async Task<User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
    {
        // bridge your ClaimsPrincipal to your DB users
        var user = db.Users.SingleOrDefault(_ => _.Email.ToUpper() == normalizedUserName);
        return await Task.FromResult(user);
    }

   ...
    public async Task<bool> IsInRoleAsync(User user, string roleName, CancellationToken cancellationToken)
    {
        if (roleName == null)
            return true;

        // your custom logic to check role in DB
        var result = user.Roles.Any(_ => _.RoleName == roleName);
        return await Task.FromResult(result);
    }
0 голосов
/ 13 декабря 2018

Если вы ищете аутентификацию на основе ролей, это кажется хорошим ресурсом: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2

Вы можете добавить атрибуты к классам, и все, что там будет, потребует указанной вами роли:

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...