Как вытащить роли пользователей из базы данных при подключении OAUTH для ASP.NET Identity 2.0?

Я работаю над некоторыми веб-API, и мне было поручено добавить авторизацию на основе ролей для некоторых конечных точек с использованием ASP.NET Identity 2.0.

Я создал административную структуру на основе API для управления пользователями и ролями и столкнулся с камнем преткновения при попытке реализовать авторизацию/аутентификацию с использованием токенов OAUTH Bearer.

(ПРИМЕЧАНИЕ. Я читал, что JWT лучше использовать и упрощает предоставление пользовательских данных, но вопрос касается ванильного OAUTH)

Итак, что касается кода, вот что у меня есть до сих пор, включая точку преткновения:

Запуск.cs:

private static void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
    // Configure the db context, user manager and role manager to use a single instance per request
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

    // Create the options for the token authorization
    var oauthAuthorizationServerOptions = new OAuthAuthorizationServerOptions
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
        Provider = new SimpleAuthorizationServerProvider()
    };

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

SimpleAuthorizationServerProvider.cs:

public sealed class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        // We are not validating clients at this point, simply "resource owners" i.e. user / pass combos
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        using (var repo = new AuthorizationRepository())
        {
            var user = repo.FindUser(context.UserName, context.Password);

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

                return;
            }
        }

        // How do you pull the user data (including roles) from the database here, and place into a claim for API consumption??
    }
}

В Интернете я нашел следующее, но это создает только роль по умолчанию для пользователя (или список ролей):

var identity = new ClaimsIdentity(context.Options.AuthenticationType);

identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("sub", context.UserName));

context.Validated(identity);

Приведенный выше код является проблемой, потому что он проверяет пользователя, но затем назначает КАЖДОМУ пользователю роль администратора в сгенерированном токене!

Любая помощь будет оценена по достоинству, и спасибо за вашу помощь!


person BatmanPriddy    schedule 14.01.2019    source источник
comment
Вы хотите использовать ApplicationManager, зарегистрированный OWIN, и использовать его для создания файла ClaimsIdentity по умолчанию. var mgr = context.OwinContext.GetUserManager<ApplicationUserManager>();, а затем var identity = await mgr.CreateIdentityAsync(user, context.Options.AuthenticationType);   -  person Brendan Green    schedule 15.01.2019
comment
+1 За этот ответ @BrendanGreen, хотел бы я отметить это как решенный ответ! Большое спасибо за помощь, все сработало отлично! Порылся в инете в поисках ответа на этот вопрос! Здоровья, приятель!   -  person BatmanPriddy    schedule 15.01.2019
comment
Добавлено как ответ, так что вы можете принять :-)   -  person Brendan Green    schedule 15.01.2019
comment
Круто, еще раз большое спасибо @BrendanGreen!   -  person BatmanPriddy    schedule 15.01.2019


Ответы (1)


Проблема в том, что вы не устанавливаете требования из ApplicationUserManager, которые могут сделать для вас большую часть тяжелой работы. Кроме того, вы просто настраиваете общий ClaimsIdentity, который, как вы уже указали, всегда будет возвращать один и тот же набор ролей для всех пользователей.

В GrantResourceOwnerCredentials() вы хотите сделать следующее:

//
// Get an instance of the ApplicationUserManager that you've already registered
// with OWIN
//
var mgr = context.OwinContext.GetUserManager<ApplicationUserManager>();

//
// Have the ApplicationUserManager build your ClaimsIdentity instead
//
var identity = await mgr.CreateIdentityAsync(user, 
                                             context.Options.AuthenticationType);

//
// Then here, you could add other application-specific claims if you wanted to.
person Brendan Green    schedule 15.01.2019
comment
Большое спасибо, Брендан, это отлично решило проблему! - person BatmanPriddy; 15.01.2019