Подтвердить что ты не робот

Роли авторизации WebAPI oauth owin

Я реализовал систему авторизации токенов в веб-API ASP.NET с промежуточным программным обеспечением OWIN. Я успешно могу выполнить аутентификацию с помощью клиента REST и получить токен авторизации для вызова API. Если я поместил атрибут [Authorize] в действие GET в моем контроллере, он также работает правильно. Если у меня нет действительного токена, он отрицает ресурс с сообщением 401, но если я использую [Authorize(Roles="admins")] с параметром roles, он не распознает роли пользователя. Я проверил вещи в базе данных и проверил, что usersinroles правильно заполнен.

Это фрагмент кода:

[Authorize(Roles = "admins")]
public IEnumerable<CompanyModel> Get()
{
    ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
    bool isrole = principal.IsInRole("admins");

Я также проверил действие без параметра roles, а isrole boolean всегда false. Должен ли я активировать что-то?

4b9b3361

Ответ 1

Вы должны добавить метод GrantResourceOwnerCredentials:

identity.AddClaim(new Claim(ClaimTypes.Role, "admins"));

Шаг за шагом

В классе StartUp.cs у вас должен быть пользовательский поставщик, например, строка

Provider = new CustomAuthorizationServerProvider()

например:

public void ConfigureOAuth(IAppBuilder app)
{
    OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
        Provider = new CustomAuthorizationServerProvider()
    };

    // Token Generation
    app.UseOAuthAuthorizationServer(oAuthServerOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}

Затем ваш CustomAuthorizationServerProvider, который наследует класс OAuthAuthorizationServerProvider, переопределит GrantResourceOwnerCredentials (контекст OAuthGrantResourceOwnerCredentialsContext).

Затем, проверив, что пользователь имеет правильное имя пользователя и пароль, вы должны добавить

var identity = new ClaimsIdentity(context.Options.AuthenticationType);
...
// other claims
...
identity.AddClaim(new Claim(ClaimTypes.Role, "admins"));
...
var ticket = new AuthenticationTicket(identity, properties);
context.Validated(ticket);

Edited

Вы можете получить роли пользователя из БД, вместо того, чтобы использовать строку "admins" harcoded:

var roles = await userManager.GetRolesAsync(userId);

Таким образом, вы можете добавить в свой репозиторий следующий метод:

public async Task<IList<string>> UserRoles(string userId)
{
    IList<string> roles = await userManager.GetRolesAsync(userId);

    return roles;
}

И затем назовите это из вашего переопределенного GrantResourceOwnerCredentials, добавив:

using (AuthRepository repository = new AuthRepository())
{
    IdentityUser user = await repository.FindUser(context.UserName, context.Password);

    if (user == null)
    {
        context.SetError("invalid_grant", "The user name or password is incorrect");
        return;
    }

    var roles = repository.UserRoles(user.Id);
}