用于Java的JWT(JSON Web令牌)库
我正在开发一个使用Java和AngularJS开发的Web应用程序,并select实现令牌authentication和授权。 出于练习的目的,我已经到了将凭据发送到服务器的地步,生成随机令牌存储并将其发送回客户端。 在服务器的每个请求中,我都将标记附加在标题中,并且完美地工作。 对于authentication的angular度来看是完美的,并不需要更多。
但是,我现在想跟踪用户types(admin,普通用户…),以及它的id,或任何其他唯一字段; 据我所知,我必须encryption在令牌,我在发送回login到客户端的过程中。 那是对的吗?
是否有任何JWT库,您可以生成,encryption和解密这些令牌? 链接到图书馆的API和Maven的依赖将非常感激。
谢谢
JJWT旨在成为最容易使用和理解JVM和Android的JWT库:
如果有人需要回答,
我用这个库: http ://connect2id.com/products/nimbus-jose-jwt这里的Maven: http : //mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt/2.10.1
这个库似乎工作得很好: https : //code.google.com/p/jsontoken/ 。
这取决于Google Guava。 这里是Maven的工件:
<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>
该图书馆实际上是由Google电子钱包使用的。
这里是如何创build一个jwt,并validation它并反序列化它:
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 (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 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; } }
这是基于这里的代码: https : //developers.google.com/wallet/instant-buy/about-jwts在这里: https : //code.google.com/p/wallet-online-sample-java/source /browse/src/com/google/wallet/online/jwt/util/WalletOnlineService.java?r=08b3333bd7260b20846d7d96d3cf15be8a128dfa
通过引用https://jwt.io/,您可以在多种语言(包括;java
findjwt
实现。 此外,该网站提供了这些实施(他们支持的algorithm和….)之间的一些比较。
对于java
这些提到的库:
IETF在它的维基上build议了jose libs: http : //trac.tools.ietf.org/wg/jose/trac/wiki
我强烈build议使用它们进行签名。 我不是一个Java的人,但似乎jose4j似乎是一个不错的select。 有很好的例子: https : //bitbucket.org/b_c/jose4j/wiki/JWS%20Examples
更新:jwt.io提供了几个jwt相关库的简洁比较,以及它们的function。 一定要检查!
我很想听听其他的java开发者更喜欢什么。
我发现这是很小,完整的https://github.com/auth0/java-jwt
https://github.com/networknt/jsontoken
这是原来的谷歌jsontoken分叉
它自2012年9月11日以来一直未更新,取决于一些旧的软件包。
我做了什么:
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.
所有现有的unit testing都与一些新增的testing用例一起传递。
以下是生成令牌并validation令牌的示例。 欲了解更多信息,请查看https://github.com/networknt/light源代码的使用情况。;
我是jsontoken和Omni-Channel应用程序框架的作者。
本页面保持对包括Java在内的各种语言的实现的引用,并比较function: http : //kjur.github.io/jsjws/index_mat.html
如果您只需parsing未签名的未encryption的令牌,则可以使用以下代码:
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; }