Ich arbeite an einer Webanwendung, die mit Java und AngularJS entwickelt wurde, und habe mich für die Implementierung der Tokenauthentifizierung und -autorisierung entschieden. Zu Übungszwecken bin ich an dem Punkt angelangt, an dem ich die Anmeldeinformationen an den Server sende, ein zufälliges Token generiere, es speichere und an den Client zurücksende. Bei jeder Anfrage an den Server füge ich das Token in den Header ein und es funktioniert perfekt. Für die Authentifizierung ist der Standpunkt perfekt und würde nicht mehr brauchen.
Jetzt möchte ich jedoch den Benutzertyp (Administrator, regulärer Benutzer ...) sowie dessen ID oder ein anderes eindeutiges Feld verfolgen. Wie ich verstanden habe, muss ich das in dem Token verschlüsseln, das ich während der Anmeldeaktion an den Client zurücksende. Ist das korrekt?
Gibt es eine JWT-Bibliothek, die Sie verwendet haben und die solche Token generieren, verschlüsseln und entschlüsseln kann? Ein Link zur API- und Maven-Abhängigkeit der Bibliothek wäre sehr willkommen.
Vielen Dank
Antworten:
JJWT soll die am einfachsten zu verwendende und zu verstehende JWT-Bibliothek für JVM und Android sein:
https://github.com/jwtk/jjwt
quelle
Wenn jemand eine Antwort braucht,
Ich habe diese Bibliothek verwendet: http://connect2id.com/products/nimbus-jose-jwt Maven hier: http://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt/2.10.1
quelle
Unter https://jwt.io/ finden Sie
jwt
Implementierungen in vielen Sprachen, einschließlichjava
. Die Site bietet auch einen Vergleich zwischen diesen Implementierungen (den von ihnen unterstützten Algorithmen und ...).Für
java
diese werden Bibliotheken erwähnt:quelle
Diese Bibliothek scheint gut zu funktionieren: https://code.google.com/p/jsontoken/ .
Es hängt von Google Guava ab. Hier sind die Maven-Artefakte:
<dependency> <groupId>com.googlecode.jsontoken</groupId> <artifactId>jsontoken</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency>
Die Bibliothek wird tatsächlich von Google Wallet verwendet.
So erstellen Sie ein JWT, überprüfen es und deserialisieren es:
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.StringUtils; 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 String AUDIENCE = "NotReallyImportant"; private static final String ISSUER = "YourCompanyOrAppNameHere"; private static final String SIGNING_KEY = "LongAndHardToGuessValueWithSpecialCharacters@^($%*$%"; /** * Creates a json web token which is a digitally signed token that contains a payload (e.g. 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 String createJsonWebToken(String 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(String token) { try { final Verifier hmacVerifier = new HmacSHA256Verifier(SIGNING_KEY.getBytes()); VerifierProvider hmacLocator = new VerifierProvider() { @Override public List<Verifier> findVerifier(String id, String 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(); String issuer = payload.getAsJsonPrimitive("iss").getAsString(); String userIdString = payload.getAsJsonObject("info").getAsJsonPrimitive("userId").getAsString(); if (issuer.equals(ISSUER) && !StringUtils.isBlank(userIdString)) { t.setUserId(new ObjectId(userIdString)); 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; } }
Dies basiert auf Code hier: https://developers.google.com/wallet/instant-buy/about-jwts Und hier: https://code.google.com/p/wallet-online-sample-java/source /browse/src/com/google/wallet/online/jwt/util/WalletOnlineService.java?r=08b3333bd7260b20846d7d96d3cf15be8a128dfa
quelle
IETF hat Jose Libs in seinem Wiki vorgeschlagen: http://trac.tools.ietf.org/wg/jose/trac/wiki
Ich würde empfehlen, sie zum Signieren zu verwenden. Ich bin kein Java-Typ, aber jose4j scheint eine gute Option zu sein. Hat auch schöne Beispiele: https://bitbucket.org/b_c/jose4j/wiki/JWS%20Examples
Ich würde gerne hören, was andere Java-Entwickler bevorzugen.
quelle
Ich fand das klein und vollständig https://github.com/auth0/java-jwt
quelle
Diese Seite enthält Verweise auf Implementierungen in verschiedenen Sprachen, einschließlich Java, und vergleicht die Funktionen: http://kjur.github.io/jsjws/index_mat.html
quelle
Wenn Sie nur nicht signierte unverschlüsselte Token analysieren müssen, können Sie diesen Code verwenden:
boolean parseJWT_2() { String authToken = getToken(); String[] segments = authToken.split("\\."); String base64String = segments[1]; int requiredLength = (int)(4 * Math.ceil(base64String.length() / 4.0)); int nbrPaddings = requiredLength - base64String.length(); if (nbrPaddings > 0) { base64String = base64String + "====".substring(0, nbrPaddings); } base64String = base64String.replace("-", "+"); base64String = base64String.replace("_", "/"); try { byte[] data = Base64.decode(base64String, Base64.DEFAULT); String text; text = new String(data, "UTF-8"); tokenInfo = new Gson().fromJson(text, TokenInfo.class); } catch (Exception e) { e.printStackTrace(); return false; } return true; }
quelle
https://github.com/networknt/jsontoken
Dies ist eine Abzweigung des ursprünglichen Google Jsontoken
Es wurde seit dem 11. September 2012 nicht aktualisiert und hängt von einigen alten Paketen ab.
Was habe ich getan:
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.
Alle vorhandenen Komponententests wurden zusammen mit einigen neu hinzugefügten Testfällen bestanden.
Hier ist ein Beispiel zum Generieren eines Tokens und zum Überprüfen des Tokens. Weitere Informationen finden Sie unter https://github.com/networknt/light Quellcode zur Verwendung.
Ich bin der Autor von jsontoken und Omni-Channel Application Framework.
quelle