Пользовательская роль атрибута авторизации не работает аутентификация веб-API

Я столкнулся с проблемой при работе с проверкой подлинности веб-API Azure Ad.

У меня есть контроллер, как показано ниже, тот, который дает правильный ответ, но тот, у которого есть пользовательские роли авторизации, вызывающие ошибку аутентификации, был для этого запроса.

[RoutePrefix("api/hospitals")]
public class hospitals : ApiController
{
    [Route("GetAll")]
    [HttpGet]
    [Authorize]
    public async Task<IEnumerable<Hospitals>> GetAll()
    {
        // return ok;
    }
    [Route("Getbeds")]
    [HttpGet]
    [SmAuthorize(Constants.Roles.Admin,
        Constants.Roles.HotSpitalAdmin,
        Constants.Roles.QA)]
    public async Task<IEnumerable<Hospitals>> Getbeds()
    {
        // return ok;
    }
}

Метод Getbeds выдает ошибку, так как была запрошена авторизация.

Пожалуйста, найдите мне класс пользовательских атрибутов

public class SmAuthorizeAttribute : AuthorizeAttribute
{
    public SmAuthorizeAttribute(params string[] roles)
    {
        this.Roles = string.Join(",", roles.Select(s => s.Trim()).ToArray());
    }
}

Кто-нибудь может помочь в этом?


person Naurto san    schedule 27.07.2020    source источник
comment
Пожалуйста, потратьте некоторое время на форматирование кода.   -  person Süleyman Sümertaş    schedule 27.07.2020
comment
@Selvin, проверь, я отредактировал имя   -  person Naurto san    schedule 27.07.2020


Ответы (1)


Вы можете обратиться к этому ТАК ответ на вопрос Дерека Грира для ядра Dot Net, дополнительно я повторю ответ ниже -

Подход, рекомендованный группой ASP.Net Core, заключается в использовании нового дизайна политики, который полностью задокументирован здесь. Основная идея нового подхода заключается в использовании нового атрибута [Authorize] для обозначения политики (например, [Authorize( Policy = YouNeedToBe18ToDoThis)], где политика зарегистрирована в файле Startup.cs приложения для выполнения некоторого блока кода (т. у пользователя есть возрастное требование, где возраст составляет 18 лет или старше).

Дизайн политик — отличное дополнение к платформе, и команда ASP.Net Security Core заслуживает похвалы за его введение. Тем не менее, он не подходит для всех случаев. Недостаток этого подхода заключается в том, что он не может предоставить удобное решение для наиболее распространенной потребности просто утверждать, что данный контроллер или действие требуют данного типа утверждения. В случае, когда приложение может иметь сотни дискретных разрешений, управляющих операциями CRUD с отдельными ресурсами REST (CanCreateOrder, CanReadOrder, CanUpdateOrder, CanDeleteOrder и т. д.), новый подход либо требует повторяющихся однозначных сопоставлений между именем политики и имя утверждения (например, options.AddPolicy(CanUpdateOrder, policy =› policy.RequireClaim(MyClaimTypes.Permission, CanUpdateOrder));), или написать некоторый код для выполнения этих регистраций во время выполнения (например, прочитать все типы утверждений из базы данных и выполнить вышеупомянутый вызов в цикле). Проблема с этим подходом в большинстве случаев заключается в том, что это ненужные накладные расходы.

Хотя команда ASP.Net Core Security рекомендует никогда не создавать собственное решение, в некоторых случаях это может быть наиболее разумным вариантом для начала.

Ниже приведена реализация, которая использует IAuthorizationFilter, чтобы предоставить простой способ выразить требование утверждения для данного контроллера или действия:

public class ClaimRequirementAttribute : TypeFilterAttribute
{
    public ClaimRequirementAttribute(string claimType, string claimValue) : base(typeof(ClaimRequirementFilter))
    {
        Arguments = new object[] {new Claim(claimType, claimValue) };
    }
}

public class ClaimRequirementFilter : IAuthorizationFilter
{
    readonly Claim _claim;

    public ClaimRequirementFilter(Claim claim)
    {
        _claim = claim;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value);
        if (!hasClaim)
        {
            context.Result = new ForbidResult();
        }
    }
}


[Route("api/resource")]
public class MyController : Controller
{
    [ClaimRequirement(MyClaimTypes.Permission, "CanReadResource")]
    [HttpGet]
    public IActionResult GetResource()
    {
        return Ok();
    }
}

Часть этого ответа для . NET Framework-

Рекомендуемый класс настраиваемых атрибутов:

public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    protected override Boolean IsAuthorized(HttpActionContext actionContext)
    {
        var currentIdentity = actionContext.RequestContext.Principal.Identity;
        if (!currentIdentity.IsAuthenticated)
            return false;

        var userName = currentIdentity.Name;
        using (var context = new DataContext())
        {
            var userStore = new UserStore<AppUser>(context);
            var userManager = new UserManager<AppUser>(userStore);
            var user = userManager.FindByName(userName);

            if (user == null)
                return false;

            foreach (var role in permissionActions)
                if (!userManager.IsInRole(user.Id, Convert.ToString(role)))
                    return false;

            return true;
        }
    }
}
person singhh-msft    schedule 28.07.2020