web-dev-qa-db-fra.com

Comment consommez-vous des paramètres supplémentaires dans la demande de jeton OAuth2 dans l'application .net WebApi2

J'ai un projet spécifique à l'API dans une grande solution Web .net MVC 5. J'utilise les modèles WebApi2 prêts à l'emploi pour authentifier un utilisateur via l'API. À l'aide de comptes individuels pour s'authentifier, le corps de la demande requis pour obtenir un jeton d'accès est:

grant_type=password&username={someuser}&password={somepassword}

Cela fonctionne comme prévu.

Cependant, je dois ajouter une 3ème dimension à la méthode échafaudée "GrantResourceOwnerCredentials". En plus de vérifier le nom d'utilisateur/mot de passe, je dois ajouter un identifiant d'appareil, qui est destiné à restreindre l'accès d'un compte d'utilisateur à un appareil spécifique. Ce qui n'est pas clair, c'est comment ajouter ces paramètres de demande supplémentaires au "OAuthGrantResourceOwnerCredentialsContext" déjà défini. Ce contexte fait actuellement de la place pour le nom d'utilisateur et le mot de passe, mais je devrai évidemment en inclure davantage.

Ma question est simplement: existe-t-il un moyen standard d'étendre les exigences de connexion pour la demande de jeton OWIN OAuth2 pour inclure plus de données? Et, comment feriez-vous de manière fiable dans un environnement .NET WebApi2?

37
nak5ive

Comme c'est souvent le cas, j'ai trouvé la réponse immédiatement après avoir posé la question ...

ApplicationOAuthProvider.cs contient le code suivant prêt à l'emploi

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    using (UserManager<IdentityUser> userManager = _userManagerFactory())
    {
        IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

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

        ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,
            context.Options.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,
            CookieAuthenticationDefaults.AuthenticationType);
        AuthenticationProperties properties = CreateProperties(context.UserName, data["udid"]);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }
}

En ajoutant simplement

var data = await context.Request.ReadFormAsync();

dans la méthode, vous pouvez accéder à toutes les variables publiées dans le corps de la demande et les utiliser comme vous le souhaitez. Dans mon cas, je l'ai placé immédiatement après le contrôle nul sur l'utilisateur pour effectuer un contrôle de sécurité plus restrictif.

J'espère que cela aide quelqu'un!

95
nak5ive