web-dev-qa-db-fra.com

Utilisation de JWT pour implémenter l'authentification sur l'API Web Asp.net

J'ai lu sur JWT.

Mais d'après ce que j'ai lu, ce n'est pas un mécanisme d'authentification, mais plutôt un élément crucial d'un mécanisme d'authentification.

J'ai actuellement mis en place une solution qui fonctionne, mais c'était juste pour essayer JWT et voir comment ça marche. Mais ce que je cherche maintenant, c’est de savoir comment l’utiliser. D'après mon expérience, c'est simplement un mécanisme de cryptage qui vous donne une clé cryptée unique. Vous pouvez également insérer des informations dans ce jeton.

Je souhaite l'implémenter en termes sur une API Web ASP.NET 2 destinée à être consommée par une application mobile.

Alors étape 1:

  1. app => Server: Login (utilisateur, mot de passe)
  2. Serveur => app: Connexion OK, voici votre JWT
  3. app => serveur: Obtenir mon profil (envoie JWT avec demande) Le serveur décrypte ensuite JWT et détermine l'identité de la demande.

Maintenant, c’est juste ce que j’en ai compris. Ecoutez, je pourrais être sur le mauvais chemin.

Est-ce que l'Idéal de JWT est tel que vous ne devez pas vous authentifier à chaque demande? Je viens d'authentifier les informations d'identification des utilisateurs une fois (sur la connexion initiale) et ensuite sur le serveur peut simplement utiliser JWT et pas besoin de rechercher les utilisateurs pw et utilisateur dans la base de données?

Je veux juste utiliser le JWT pour identifier qui est l'utilisateur. Je vais ensuite autoriser après que je les ai authentifiés. Comme je sais, il y a une grande confusion avec le nouveau MVC et Authentication and Authorization.

Alors, quelle est ma question?.

Comment puis-je mettre en œuvre efficacement et en toute sécurité un mécanisme d'authentification à l'aide de JWT? Je ne veux pas simplement avaler quelque chose qui semble fonctionner et qui n'a aucune idée des implications en matière de sécurité. Je suis sûr qu’il existe une source qui aurait éventuellement mis au point un mécanisme sécurisé qui répondrait à mes besoins.

Mes exigences sont:

  • Doit seulement vérifier la base de données pour les informations d'identification des utilisateurs une fois par session? En raison de l'utilisation de bcrypt, l'utilisation de nombreuses ressources permet de comparer les mots de passe.
  • Doit pouvoir identifier l'utilisateur à partir de leur demande. (Ie qui ils sont, userId sera suffisant) et de préférence sans accéder à la base de données aussi
  • Devrait être le moins de temps système possible en ce qui concerne les ressources côté serveur traitant la demande.
  • Si un intrus devait copier une requête précédente d'un périphérique, il ne devrait pas pouvoir accéder aux données des utilisateurs réels. (évidemment)

Merci

56
Zapnologica

Votre compréhension des JWT est bonne. Mais voici quelques corrections et quelques recommandations.

Authentification et autorisation

  • Les JWT n'ont rien à voir avec l'authentification. Les mots de passe de base de données et de hachage ne sont utilisés que lorsque vous vous authentifiez lors de la création du fichier JWT. Ceci est orthogonal aux JWT et vous pouvez le faire comme bon vous semble. Personnellement, j'aime bien Membership Reboot , qui offre également un bon exemple d'utilisation de JWT.
  • Théoriquement, vous pouvez demander à l'utilisateur de saisir un mot de passe une fois par an et de faire valider le JWT toute l'année. Ce n'est probablement pas la meilleure solution. Si le JWT était volé à un moment quelconque, les ressources des utilisateurs seraient compromises.

Cryptage

  • Les jetons peuvent, mais ne doivent pas être cryptés. Le cryptage de vos jetons augmentera la complexité de votre système et la quantité de calcul dont votre serveur a besoin pour lire les JWT. Cela peut être important si vous avez besoin que personne ne soit capable de lire le jeton lorsqu'il est au repos.
  • Les jetons sont toujours signés cryptographiquement par l'émetteur pour garantir leur intégrité. Cela signifie qu'ils ne peuvent pas être altérés par l'utilisateur ou par un tiers.

Réclamations

Vos JWT peuvent contenir toutes les informations que vous souhaitez. Le nom de l'utilisateur, sa date de naissance, son adresse électronique, etc. Vous le faites avec une autorisation basée sur les revendications. Vous dites alors simplement à votre fournisseur d’effectuer un test JWT avec ces revendications à partir du principe de revendications. Le code suivant provient de cet exemple de redémarrage d’appartenance et il vous explique comment procéder.

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    var svc = context.OwinContext.Environment.GetUserAccountService<UserAccount>();
    UserAccount user;
    if (svc.Authenticate("users", context.UserName, context.Password, out user))
    {
        var claims = user.GetAllClaims();

        var id = new System.Security.Claims.ClaimsIdentity(claims, "MembershipReboot");
        context.Validated(id);
    }

    return base.GrantResourceOwnerCredentials(context);
}

Cela vous permet de contrôler avec précision qui accède à vos ressources, le tout sans toucher votre service d'authentification intensive du processeur.

La mise en oeuvre

Un moyen très simple d'implémenter un fournisseur de jetons consiste à utiliser Microsoft OAuth Authorization Server dans votre projet WebAPI. Il vous donne les bases de ce dont vous avez besoin pour créer une OAuth serveur pour votre API.

Vous pouvez également consulter la version Identity Server de Thinktecture, qui vous permettrait de contrôler beaucoup plus facilement les utilisateurs. Par exemple, vous pouvez facilement implémenter des jetons d'actualisation avec le serveur d'identité, où l'utilisateur est authentifié une fois, puis pendant un certain temps (peut-être un mois), il peut continuer à obtenir des fichiers JWT de courte durée à partir d'Identity Server. Les jetons d'actualisation sont bons car ils peuvent être révoqués, alors que les JWT ne le peuvent pas. L'inconvénient de cette solution est que vous devez configurer un ou deux autres serveurs pour héberger le service d'identité.

Pour traiter de votre dernier point, un intrus ne devrait pas pouvoir copier la dernière requête pour accéder à une ressource, vous devez utiliser SSL au minimum. Ceci protégera le jeton dans transport.

Si vous protégez quelque chose d'extrêmement sensible, vous devriez limiter la durée de vie des jetons à une très courte période. Si vous protégez quelque chose de moins sensible, vous pourriez allonger la durée de vie. Plus le jeton est long, si valide, plus la fenêtre de temps qu'un attaquant devra emprunter pour emprunter l'identité de l'utilisateur authentifié si la machine de l'utilisateur est compromise.

55
Thomas Sobieck

J'ai écrit un article de blog détaillé sur la configuration du serveur d'autorisation OWIN pour qu'il émette des jetons Web JSON signés au lieu du jeton par défaut. Ainsi, les serveurs de ressources (Audience) peuvent s’inscrire auprès du serveur d’autorisations, puis utiliser les jetons JWT émis par la partie émettrice de jetons sans qu’il soit nécessaire d’unifier les valeurs machineKey entre toutes les parties. Vous pouvez lire le message jeton Web JSON dans ASP.NET Web API 2 avec Owin

23
Taiseer Joudeh