Bibliothèque JWT (JSON Web Token) pour Java

Je travaille sur une application Web développée avec Java et AngularJS et j’ai choisi d’implémenter l’authentification et l’autorisation de jetons. Pour les besoins de l’exercice, j’en arrive au point où j’envoie les informations d’identification au serveur, génère un stock de jeton aléatoire et le renvoie au client. A chaque demande au serveur, je joins le jeton dans l’en-tête et cela fonctionne parfaitement. Car le sharepoint vue de l’authentification est parfait et ne nécessite pas plus.

Cependant, je veux maintenant garder une trace du type d’utilisateur (admin, utilisateur régulier …), ainsi que son identifiant, ou tout autre champ unique; Si j’ai bien compris, je dois chiffrer cela dans le jeton que je renvoie au client lors de la connexion. Est-ce exact?

Y a-t-il une bibliothèque JWT que vous avez utilisée et peut générer, chiffrer et déchiffrer ces jetons? Un lien vers les dépendances API et Maven de la bibliothèque serait très apprécié.

Merci

JJWT se veut le plus simple à utiliser et à comprendre de la bibliothèque JWT pour JVM et Android:

https://github.com/jwtk/jjwt

Si quelqu’un dans le besoin d’une réponse,

J’ai utilisé cette bibliothèque: http://connect2id.com/products/nimbus-jose-jwt Maven ici: http://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt/2.10.1

Cette bibliothèque semble bien fonctionner: https://code.google.com/p/jsontoken/ .

Cela dépend de Google Guava. Voici les artefacts Maven:

 com.googlecode.jsontoken jsontoken 1.0   com.google.guava guava 18.0  

La bibliothèque est en fait utilisée par Google Wallet.

Voici comment créer un fichier jwt, et le vérifier et le désérialiser:

 import java.security.InvalidKeyException; import java.security.SignatureException; import java.util.Calendar; import java.util.List; import net.oauth.jsontoken.JsonToken; import net.oauth.jsontoken.JsonTokenParser; import net.oauth.jsontoken.crypto.HmacSHA256Signer; import net.oauth.jsontoken.crypto.HmacSHA256Verifier; import net.oauth.jsontoken.crypto.SignatureAlgorithm; import net.oauth.jsontoken.crypto.Verifier; import net.oauth.jsontoken.discovery.VerifierProvider; import net.oauth.jsontoken.discovery.VerifierProviders; import org.apache.commons.lang3.SsortingngUtils; import org.bson.types.ObjectId; import org.joda.time.DateTime; import com.google.common.collect.Lists; import com.google.gson.JsonObject; /** * Provides static methods for creating and verifying access tokens and such. * @author davidm * */ public class AuthHelper { private static final Ssortingng AUDIENCE = "NotReallyImportant"; private static final Ssortingng ISSUER = "YourCompanyOrAppNameHere"; private static final Ssortingng SIGNING_KEY = "LongAndHardToGuessValueWithSpecialCharacters@^($%*$%"; /** * Creates a json web token which is a digitally signed token that contains a payload (eg userId to identify * the user). The signing key is secret. That ensures that the token is authentic and has not been modified. * Using a jwt eliminates the need to store authentication session information in a database. * @param userId * @param durationDays * @return */ public static Ssortingng createJsonWebToken(Ssortingng userId, Long durationDays) { //Current time and signing algorithm Calendar cal = Calendar.getInstance(); HmacSHA256Signer signer; try { signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes()); } catch (InvalidKeyException e) { throw new RuntimeException(e); } //Configure JSON token JsonToken token = new net.oauth.jsontoken.JsonToken(signer); token.setAudience(AUDIENCE); token.setIssuedAt(new org.joda.time.Instant(cal.getTimeInMillis())); token.setExpiration(new org.joda.time.Instant(cal.getTimeInMillis() + 1000L * 60L * 60L * 24L * durationDays)); //Configure request object, which provides information of the item JsonObject request = new JsonObject(); request.addProperty("userId", userId); JsonObject payload = token.getPayloadAsJsonObject(); payload.add("info", request); try { return token.serializeAndSign(); } catch (SignatureException e) { throw new RuntimeException(e); } } /** * Verifies a json web token's validity and extracts the user id and other information from it. * @param token * @return * @throws SignatureException * @throws InvalidKeyException */ public static TokenInfo verifyToken(Ssortingng token) { try { final Verifier hmacVerifier = new HmacSHA256Verifier(SIGNING_KEY.getBytes()); VerifierProvider hmacLocator = new VerifierProvider() { @Override public List findVerifier(Ssortingng id, Ssortingng key){ return Lists.newArrayList(hmacVerifier); } }; VerifierProviders locators = new VerifierProviders(); locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator); net.oauth.jsontoken.Checker checker = new net.oauth.jsontoken.Checker(){ @Override public void check(JsonObject payload) throws SignatureException { // don't throw - allow anything } }; //Ignore Audience does not mean that the Signature is ignored JsonTokenParser parser = new JsonTokenParser(locators, checker); JsonToken jt; try { jt = parser.verifyAndDeserialize(token); } catch (SignatureException e) { throw new RuntimeException(e); } JsonObject payload = jt.getPayloadAsJsonObject(); TokenInfo t = new TokenInfo(); Ssortingng issuer = payload.getAsJsonPrimitive("iss").getAsSsortingng(); Ssortingng userIdSsortingng = payload.getAsJsonObject("info").getAsJsonPrimitive("userId").getAsSsortingng(); if (issuer.equals(ISSUER) && !SsortingngUtils.isBlank(userIdSsortingng)) { t.setUserId(new ObjectId(userIdSsortingng)); t.setIssued(new DateTime(payload.getAsJsonPrimitive("iat").getAsLong())); t.setExpires(new DateTime(payload.getAsJsonPrimitive("exp").getAsLong())); return t; } else { return null; } } catch (InvalidKeyException e1) { throw new RuntimeException(e1); } } } public class TokenInfo { private ObjectId userId; private DateTime issued; private DateTime expires; public ObjectId getUserId() { return userId; } public void setUserId(ObjectId userId) { this.userId = userId; } public DateTime getIssued() { return issued; } public void setIssued(DateTime issued) { this.issued = issued; } public DateTime getExpires() { return expires; } public void setExpires(DateTime expires) { this.expires = expires; } } 

Ceci est basé sur le code ici: https://developers.google.com/wallet/instant-buy/about-jwts Et ici: https://code.google.com/p/wallet-online-sample-java/source /browse/src/com/google/wallet/online/jwt/util/WalletOnlineService.java?r=08b3333bd7260b20846d7d96d3cf15be8a128dfa

En vous référant à https://jwt.io/, vous pouvez trouver des implémentations jwt dans de nombreuses langues, y compris java . Le site fournit également une comparaison entre ces implémentations (les algorithmes qu’ils supportent et ….).

Pour java ces bibliothèques sont mentionnées:

L’IETF a suggéré des bibliothèques jose sur son wiki: http://trac.tools.ietf.org/wg/jose/trac/wiki

Je recommande fortement de les utiliser pour la signature. Je ne suis pas un gars de Java, mais jose4j semble être une bonne option. A aussi de beaux exemples: https://bitbucket.org/b_c/jose4j/wiki/JWS%20Examples

Mise à jour: jwt.io fournit une comparaison soignée de plusieurs bibliothèques liées à jwt et de leurs fonctionnalités. Un must check!

J’aimerais beaucoup savoir ce que les autres développeurs Java préfèrent.

J’ai trouvé que c’était petit et complet https://github.com/auth0/java-jwt

Cette page conserve des références aux implémentations dans différents langages, y compris Java, et compare les fonctionnalités: http://kjur.github.io/jsjws/index_mat.html

https://github.com/networknt/jsontoken

Ceci est une fourchette de google original jsontoken

Il n’a pas été mis à jour depuis le 11 septembre 2012 et dépend de certains anciens paquets.

Ce que j’ai fait:

 Convert from Joda time to Java 8 time. So it requires Java 8. Covert Json parser from Gson to Jackson as I don't want to include two Json parsers to my projects. Remove google collections from dependency list as it is stopped long time ago. Fix thread safe issue with Java Mac.doFinal call. 

Tous les tests unitaires existants ont été accompagnés de nouveaux cas de test ajoutés.

Voici un exemple pour générer un jeton et vérifier le jeton. Pour plus d’informations, consultez le code source https://github.com/networknt/light .

Je suis l’auteur à la fois de jsontoken et d’Omni-Channel Application Framework.

Si vous devez uniquement parsingr les jetons non chiffrés non signés, vous pouvez utiliser ce code:

 boolean parseJWT_2() { Ssortingng authToken = getToken(); Ssortingng[] segments = authToken.split("\\."); Ssortingng base64Ssortingng = segments[1]; int requiredLength = (int)(4 * Math.ceil(base64Ssortingng.length() / 4.0)); int nbrPaddings = requiredLength - base64Ssortingng.length(); if (nbrPaddings > 0) { base64Ssortingng = base64Ssortingng + "====".subssortingng(0, nbrPaddings); } base64Ssortingng = base64Ssortingng.replace("-", "+"); base64Ssortingng = base64Ssortingng.replace("_", "/"); try { byte[] data = Base64.decode(base64Ssortingng, Base64.DEFAULT); Ssortingng text; text = new Ssortingng(data, "UTF-8"); tokenInfo = new Gson().fromJson(text, TokenInfo.class); } catch (Exception e) { e.printStackTrace(); return false; } return true; }