. NET Базовая пользовательская роль AuthorizeAttribute работает на уровне класса, но не на уровне метода. - PullRequest
0 голосов
/ 30 апреля 2020

Атрибут Authorize срабатывает при размещении над классом, но его никогда не трогают при размещении над методом. Почему? Ниже приведен пример его работы с классом:

[AppAuthorization(RoleConjuction.Or, Admin, NormalUser, ReadOnlyUser)]
public class AccountRequestsModel : BaseModel<AccountRequestsModel>

Ниже приведен пример того, как он НЕ работает с методом:

[AppAuthorization(RoleConjuction.Or, Admin, NormalUser, ReadOnlyUser)]
public async Task<IActionResult> OnPostArchiveUserAsync(Guid userId)

Класс AppAuthorization:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AppAuthorizationAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter
{
/// <summary>
/// Initializes a new instance of the <see cref="AppAuthorizationAttribute"/> class.
/// </summary>
/// <param name="conjunction">App Enum Conjunction</param>
/// <param name="roles">App Roles</param>
public AppAuthorizationAttribute(RoleConjuction conjunction, params string[] roles)
{
    Conjunction = conjunction;
    Roles = string.Join(",", roles);
}

/// <summary>
/// Initializes a new instance of the <see cref="AppAuthorizationAttribute"/> class.
/// App Authorization Attribute
/// </summary>
/// <param name="roles">App Roles</param>
public AppAuthorizationAttribute(params string[] roles)
{
    Conjunction = RoleConjuction.Single;
    Roles = string.Join(",", roles);
}

/// <summary>
/// Gets or sets the conjunction.
/// </summary>
public RoleConjuction Conjunction { get; set; }

/// <summary>
/// The on authorization async.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
    if (string.IsNullOrEmpty(Roles))
    {
        return;
    }

    var roleArguments = Roles.Split(",");

    var userNumber = context.HttpContext.User.Claims.GetNumber();

    userNumber.Validate(nameof(userNumber), "string");

    var userService = context.HttpContext.RequestServices.GetService<IUserServices>();

    var userInfo = await userService.UserApplicationService.GetApplicationUserByuserNumberAsync(userNumber);

    var userRoles = userInfo?.Roles.ToList();

    if (userInfo == null || userInfo.Archived || !userRoles.Any())
    {
        context.Result = new ForbidResult();
        return;
    }

    switch (Conjunction)
    {
        case RoleConjuction.And:
            {
                var isAuthorized = roleArguments.All(userRoles.Select(x => x.RoleName).Contains);
                if (!isAuthorized)
                {
                    context.Result = new ForbidResult();
                }

                break;
            }

        case RoleConjuction.Or:
            {
                var isAuthorized = roleArguments.Any(userRoles.Select(x => x.RoleName).Contains);
                if (!isAuthorized)
                {
                    context.Result = new ForbidResult();
                }

                break;
            }

        case RoleConjuction.Single:
            {
                var isAuthorized = roleArguments.All(userRoles.Select(x => x.RoleName).Contains);
                if (!isAuthorized || userRoles.Count() != 1)
                {
                    context.Result = new ForbidResult();
                }

                break;
            }

        case RoleConjuction.None:
            {
                // TODO
                break;
            }
    }

    userService.Dispose();
}
}

Я полагаю, что проблема может быть где-то в моем Middleware. Я пользуюсь app.UseAuthentication(); Может там что-то не в порядке?

...