пользовательская авторизация в asp.net core mvc - PullRequest
0 голосов
/ 05 октября 2018

В проекте asp.net core mvc я хочу создать новые роли пользователей и дать разрешение каждой роли для действий контроллера.
Допустим, у меня есть SchoolController, внутри него у меня есть три метода

  • CreateSchool
  • UpdateSchool
  • DeleteSchool

И скажем, у меня есть Admin и Staff роли.Я хочу предоставить доступ ко всем методам для Admin и дать UpdateSchool для Staff.
Это означает, что администратор может создавать, обновлять, удалять школу.И сотрудники могут только UpdateSchool.
Я сохраню это разрешение ролей в базе данных, например

Role
----------------------------------------
RoleId  Name
1       Admin
2       Staff


Module
----------------------------------------
ModuleId   Name
1          SchoolController/CreateSchool
2          SchoolController/UpdateSchool
3          SchoolController/DeleteSchool

RoleModules (middle table for relation of roles and module )
----------------------------------------
RoleId      ModuleId
1           1
1           2
1           3
2           2

Хорошо, допустим, у нас здесь 3 человека, Person_1, Person_2 и Person_3.
И у них разныетакие роли, как

Person_1 ( Admin )
Person_2 ( Staff )
Person_3 ( Staff )

Когда пользователи получают доступ к CreateSchool действию контроллера, я хочу проверить, имеет ли текущий пользователь доступ к этому действию или нет.

[Authorize]
public async Task<IActionResult> CreateSchool(SchoolViewModel model)
{
     //code to create school
}

Для этого мне следуетнужно использовать IAuthorizationHandler 'HandleRequirementAsync?
Где мне получить информацию из базы данных и проверить запрос пользователя?
Есть ли какие-либо ссылки, которые соответствуют моему требованию ??

Примечание : Роли и модули будут динамически создаваться во время выполнения.

Обновление : я должен использовать ActionFilter?( ссылка )

1 Ответ

0 голосов
/ 05 октября 2018

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

Создайте класс требования:

public class HasRoleRequirement: IAuthorizationRequirement { }

Затем реализуйте обработчик:

public class RoleRequirementHandler : AuthorizationHandler<HasRoleRequirement>
{
    protected IHttpContextAccessor m_httpContextAccessor;

    public RequirementHandlerBase(IHttpContextAccessor httpContextAccessor)
    {
        m_httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasRoleRequirement requirement)
    {
        var requestPath = m_httpContextAccessor.Request.Path;
        var module = GetModule(path); // Get your module from DB
        var requiredRoles = GetRequiredRoles(module.ModuleId); // Get the required roles for the module/path
        bool isAuthorized = IsInAnyRole(m_httpContext.User, requiredRoles); // Check whether the user has any of the required roles
        if (isAuthorized)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }

        return Task.CompletedTask;
    }
}

Зарегистрируйте политику вметод ConfigureServices в Startup.cs:

services.AddAuthorization(options => 
{
    options.AddPolicy("HasRole", policy => policy.Requirements.Add(new HasRoleRequirement()));
}
services.AddSingleton<IAuthorizationHandler, RoleRequirementHandler>();

Используйте авторизацию по оформлению вашего метода [Authorize(Policy = "IsInRole")]

Для повторного использования и более чистого кода вы можете объявить строки имени политики как константыв статическом классе.

См. документы .

Вам нужно будет реализовать методы GetModule.GetRequiredRoles и IsInAnyRole себя.

...