Maison >Java >javaDidacticiel >Comment intégrer l'authentification JWT dans SpringBoot (avec code)

Comment intégrer l'authentification JWT dans SpringBoot (avec code)

不言
不言avant
2019-03-19 09:39:393517parcourir

Le contenu de cet article explique comment intégrer l'authentification JWT dans SpringBoot (avec du code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. . Aide.

1. À propos de JWT

1.1 Qu'est-ce que JWT

Pour commencer par le cliché, si l'on veut utiliser un tel outil, il faut d'abord connaître ce qui suit problèmes.

  • Qu'est-ce que cet outil et quel problème cet outil résout-il ?
  • Est-il applicable au scénario commercial actuel dans lequel nous nous trouvons ?
  • Est-ce que cela posera des problèmes après l'avoir utilisé ? Autres questions
  • Comment l'utiliser est la meilleure pratique

Alors, qu'est-ce que JWT ? Ce qui suit est ma traduction de l'introduction à JWT sur le site officiel de jwt.

JSON Web Token (JWT) est un standard ouvert (RFC 7519) qui définit une méthode compacte et indépendante pour transmettre en toute sécurité des informations entre les parties à l'aide d'objets JSON.

Nous savons désormais que JWT est en fait un standard ouvert permettant de transmettre en toute sécurité des données représentées par JSON entre plusieurs points. Pendant le processus de transmission, JWT apparaît dans notre champ de vision sous la forme d'une chaîne. Les informations contenues dans cette chaîne peuvent être vérifiées et fiables grâce aux signatures numériques. (Recommandé : Tutoriel Java)

1.2 Scénarios d'application

Quels sont les scénarios d'application de JWT en développement réel ?

1.2.1 Autorisation

Cela doit être considéré comme le scénario d'utilisation le plus courant de JWT. Dans l'interface frontale, une fois que l'utilisateur s'est connecté avec succès, le JWT renvoyé par le back-end sera reçu. Les demandes ultérieures incluront le JWT renvoyé par le backend comme informations d'identification pour accéder aux routes, services et ressources du backend.

1.2.2 Échange d'informations

L'utilisation de JWT pour transférer des informations entre plusieurs parties présente un certain degré de sécurité. Par exemple, JWT peut utiliser l'algorithme de cryptage asymétrique HMAC, RSA et l'algorithme de signature numérique ECDSA pour. La signature peut garantir que l'expéditeur du message est le véritable expéditeur, et en utilisant le calcul de signature de l'en-tête et de la charge utile, nous pouvons également vérifier si le message envoyé a été falsifié.

2. La structure de JWT

De manière générale, JWT est une chaîne composée de trois parties header.payload.signature Il y a trop de messages sur Internet pour présenter cette partie, je vais donc brièvement. présentez-le ici, bien.

L'en-tête 2.1

header comprend l'algorithme de signature utilisé et le type de jeton. Par exemple, le type de jeton est un standard ouvert tel que JWT, et l'algorithme de signature utilisé est. HS256, qui est l'algorithme HmacSHA256. D'autres algorithmes de cryptage incluent HmacSHA512, SHA512withECDSA, etc.

Convertissez ensuite cet objet JSON contenant deux attributs en une chaîne puis utilisez l'encodage Base64 pour enfin former l'en-tête JWT.

Charge utile 2.2

payloadPour parler franchement, elle est similaire aux données de votre requestBody. Il n’en existe que trois types : pré-déclaré, personnalisé et privé. Comme l'iss expéditeur et le exp délai d'expiration, ce sont tous des relevés pré-enregistrés.

La pré-déclaration des données dans le payload n'est pas obligatoire, mais est officiellement recommandée. Ensuite, cette chaîne de JSON similaire à requestBody est codée en Base64 pour former la deuxième partie du JWT.

Signature 2.3

Si vous souhaitez générer signature, vous devez utiliser le secret dans l'élément de configuration personnalisé jwt, qui est la clé requise pour le cryptage de l'algorithme Hmac. Connectez l'en-tête et la charge utile précédemment codés en Base64 avec ., puis utilisez une clé personnalisée pour signer le message et enfin générez une signature.

La signature générée permet de vérifier que le message n'a pas été altéré lors de la transmission. Lors de l'utilisation d'un algorithme de chiffrement asymétrique pour la signature, il peut également être utilisé pour vérifier si l'expéditeur du JWT est la même personne que l'expéditeur déclaré dans la charge utile.

3. Scénarios d'application JWT dans les projets Spring

3.1 Générer JWT

Le code est le suivant.

public String createJwt(String userId, String projectId) throws IllegalArgumentException, UnsupportedEncodingException {
    Algorithm al = Algorithm.HMAC256(secret);
    Instant instant = LocalDateTime.now().plusHours(outHours).atZone(ZoneId.systemDefault()).toInstant();
    Date expire = Date.from(instant);
    String token = JWT.create()
            .withIssuer(issuer)
            .withSubject("userInfo")
            .withClaim("user_id", userId)
            .withClaim("project_id", projectId)
            .withExpiresAt(expire)
            .sign(al);
    return token;
}

Les deux revendications transmises sont les charges utiles personnalisées du projet, al est l'algorithme sélectionné, et secret est la clé pour signer les informations, et subject est le jeton. sujet, withExpiresAt identifie l'heure d'expiration du jeton.

3.2 Renvoi du JWT

Une fois que l'utilisateur s'est connecté avec succès au système, le jeton est utilisé comme paramètre de retour et renvoyé au front-end.

3.3 Vérifier le jeton

Une fois le jeton renvoyé au front-end, ce que le back-end doit faire est de vérifier si le jeton est légal et si les ressources du serveur sont accessibles . Cela peut être vérifié principalement par les méthodes suivantes.

3.3.1 Analyser le jeton

Utilisez JWTVerifier pour analyser le jeton C'est la première étape pour vérifier si le jeton est légal. Par exemple, le jeton transmis depuis le front-end est un. chaîne de chaînes dénuées de sens, une erreur peut être générée à cette étape. L’exemple de code est le suivant.

try {
    Algorithm algorithm = Algorithm.HMAC256(secret);
    JWTVerifier verifier = JWT.require(algorithm).build();
    DecodedJWT jwt = verifier.verify(token);
} catch (JWTVerificationException e) {
    e.printStackTrace();
}

JWTVerifier peut utiliser l'algorithme qui formule la signature secrète et la revendication spécifiée pour vérifier la légitimité du jeton.

3.3.2 Déterminer la validité du jeton

Après avoir jugé que le jeton est valide, vérifiez la validité du jeton.

try {
    Algorithm algorithm = Algorithm.HMAC256(secret);
    JWTVerifier verifier = JWT.require(algorithm).build();
    DecodedJWT jwt = verifier.verify(token);
    if (jwt.getExpiresAt().before(new Date())) {
        System.out.println("token已过期");
        return null;
    }
} catch (JWTVerificationException e) {
    e.printStackTrace();
    return null;
}

Si le token expire, l'accès aux ressources du serveur n'est pas autorisé. Le processus spécifique est le suivant.

Comment intégrer lauthentification JWT dans SpringBoot (avec code)

3.3.3 Délai d'expiration de l'actualisation

La durée de validité du jeton créé ci-dessus est configurable, en supposant qu'elle est de 2 heures, et que l'utilisateur se connecte et travaille en continu pendant 1 heure À 59 minutes, lorsque vous effectuez une opération très importante, cliquez sur OK. À ce moment-là, le jeton a expiré. Si le programme ne dispose pas d'une stratégie de protection, alors près de deux heures de travail de l'utilisateur seront vaines.

Lorsque nous rencontrons un tel problème, notre conception de processus précédente sera inévitablement confrontée à une reconstruction. Vous avez peut-être des questions, n'est-il pas nécessaire d'actualiser le délai d'expiration du token pour chaque opération après la connexion de l'utilisateur ?

Ensuite la question se pose. Nous savons que le jeton est composé de trois éléments de contenu header.payload.signature, et le délai d'expiration appartient à la charge utile. Si le délai d'expiration est modifié, le hachage de la charge utile finale générée. sera forcément le même que celui de la charge utile différent de la dernière génération.

En d’autres termes, il s’agit d’un tout nouveau jeton. Comment le front-end reçoit-il ce nouveau jeton ? La solution envisageable n'est rien d'autre que d'actualiser continuellement le jeton en fonction du retour dans l'en-tête de réponse pour chaque requête. Mais cette méthode envahit la couche métier du développement front-end. Chaque interface doit actualiser le jeton.

On peut dire qu'il ne s'agit rien d'autre que l'ajout d'un intercepteur, qui ne gênera pas beaucoup l'activité. Même si cette partie de la logique est écrite dans l'intercepteur, le frontal possède ce code supplémentaire en raison de la logique d'authentification du jeton. En termes de division fonctionnelle du travail, cette partie du code est en fait la logique back-end.

Pour le dire plus simplement, l'actualisation du jeton et la gestion de l'actualité du jeton doivent être effectuées par le backend. Le frontal n’a pas besoin et ne devrait pas se soucier de cette partie de la logique.

3.3.4 Redis est une bonne méthode

En résumé, le délai d'expiration du jeton d'actualisation doit être placé sur le backend, et la validité du jeton ne peut pas être jugée en jugeant l'expiration dans la charge utile dans le JWT .

Ainsi, une fois que l'utilisateur s'est connecté avec succès et a renvoyé le jeton au front-end, il doit être écrit dans le cache Redis avec une représentation unique comme clé et le jeton actuel comme valeur. Et une fois que chaque demande utilisateur est réussie, le délai d'expiration du jeton est actualisé. Le processus est le suivant.

Comment intégrer lauthentification JWT dans SpringBoot (avec code)

Après une telle reconstruction, le processus devient ainsi.

Comment intégrer lauthentification JWT dans SpringBoot (avec code)

Il existe un processus supplémentaire pour actualiser le jeton au cours du processus. Tant que l'utilisateur se connecte au système, chaque opération actualisera le délai d'expiration du jeton et il n'y aura aucune perte de données causée par une panne soudaine lors d'une opération, comme mentionné précédemment.

Dans les deux heures suivant la connexion de l'utilisateur, si l'utilisateur n'effectue aucune opération, une nouvelle demande d'interface après 2 heures se verra directement refuser l'accès par le serveur.

4. Résumé

En général, il n'est pas recommandé de mettre des informations particulièrement sensibles dans JWT. Si l'algorithme de chiffrement asymétrique n'est pas utilisé, vous pouvez directement vous rendre sur le site officiel de jwt pour l'analyser en ligne après avoir copié le token. Si la demande est interceptée, toutes les informations qu'elle contient sont égales à transparentes.

Mais JWT peut être utilisé comme identifiant pour accéder aux ressources du serveur pendant un certain temps. Par exemple, si la charge utile JWT contient le champ userId, alors la légitimité de l'utilisateur identifié par le jeton peut être vérifiée. Par exemple, l'utilisateur est-il actuellement verrouillé ? L'utilisateur identifié par ce userId existe-t-il dans notre système ? etc.

Et en rendant le token public, les utilisateurs peuvent se connecter depuis plusieurs terminaux en même temps. La création d'un jeton après la connexion comme avant limite l'utilisateur à ne pouvoir se connecter que sur un seul appareil à la fois.


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer