用于 Java 的 JWT(JSON Web 令牌)库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23808460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JWT (JSON Web Token) library for Java
提问by Marius Manastireanu
I am working on a web application developed using Java and AngularJS and chose to implement token authentication and authorization. For the exercise purpose, I've come to the point where I send the credentials to the server, generate a random token store it and send it back to the client. At every request to the server I'm attaching the token in the header and it works perfectly. For the authentication point of view is perfect and wouldn't need more.
我正在开发一个使用 Java 和 AngularJS 开发的 Web 应用程序,并选择实现令牌身份验证和授权。出于练习目的,我已经将凭据发送到服务器,生成一个随机令牌存储它并将其发送回客户端。在对服务器的每个请求中,我都会在标头中附加令牌,并且它运行良好。对于身份验证的观点是完美的,不需要更多。
However, I now want to keep track of the user type (admin, regular user...), as well as it's id, or any other unique field; as I understood I have to encrypt that in the token that I'm sending back to the client during the log in action. Is that correct?
但是,我现在想跟踪用户类型(管理员、普通用户...),以及它的 id 或任何其他唯一字段;据我了解,我必须在登录操作期间发送回客户端的令牌中对其进行加密。那是对的吗?
Is there any JWT library that you used and can generate, encrypt and decrypt such tokens? A link to the library's API and Maven dependency would be much appreciated.
您是否使用过任何 JWT 库并且可以生成、加密和解密此类令牌?非常感谢指向库的 API 和 Maven 依赖项的链接。
Thanks
谢谢
采纳答案by Marius Manastireanu
If anyone in the need for an answer,
如果有人需要答案,
I used this library: http://connect2id.com/products/nimbus-jose-jwtMaven here: http://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt/2.10.1
我使用了这个库:http: //connect2id.com/products/nimbus-jose-jwtMaven 在这里:http: //mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt/2.10.1
回答by Marquez
This library seems to work well: https://code.google.com/p/jsontoken/.
这个库似乎运行良好:https: //code.google.com/p/jsontoken/。
It depends on Google Guava. Here are the Maven artifacts:
这取决于谷歌番石榴。以下是 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>
The library is in fact used by Google Wallet.
该库实际上由 Google 电子钱包使用。
Here is how to create a jwt, and to verify it and deserialize it:
下面是如何创建一个 jwt,并验证它和反序列化它:
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;
}
}
This is based on code here: https://developers.google.com/wallet/instant-buy/about-jwtsAnd Here: https://code.google.com/p/wallet-online-sample-java/source/browse/src/com/google/wallet/online/jwt/util/WalletOnlineService.java?r=08b3333bd7260b20846d7d96d3cf15be8a128dfa
这是基于这里的代码: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
回答by Priyeshj
IETF has suggested jose libs on it's wiki: http://trac.tools.ietf.org/wg/jose/trac/wiki
IETF 在其 wiki 上建议了 jose 库:http: //trac.tools.ietf.org/wg/jose/trac/wiki
I would highly recommend using them for signing. I am not a Java guy, but seems like jose4j seems like a good option. Has nice examples as well: https://bitbucket.org/b_c/jose4j/wiki/JWS%20Examples
我强烈建议使用它们进行签名。我不是 Java 人,但 jose4j 似乎是一个不错的选择。也有很好的例子:https: //bitbucket.org/b_c/jose4j/wiki/JWS%20Examples
Update: jwt.io provides a neat comparison of several jwt related libraries, and their features. A must check!
更新:jwt.io 提供了几个 jwt 相关库及其功能的简洁比较。必须检查!
I would love to hear about what other java devs prefer.
我很想听听其他 Java 开发人员更喜欢什么。
回答by Les Hazlewood
JJWT aims to be the easiest to use and understand JWT library for the JVM and Android:
JJWT 旨在成为 JVM 和 Android 上最容易使用和理解的 JWT 库:
回答by mfirry
I found this to be small and complete https://github.com/auth0/java-jwt
我发现这是小而完整的https://github.com/auth0/java-jwt
回答by Steve Hu
https://github.com/networknt/jsontoken
https://github.com/networknt/jsontoken
This is a fork of original google jsontoken
这是原始 google jsontoken 的一个分支
It has not been updated since Sep 11, 2012 and depends on some old packages.
它自 2012 年 9 月 11 日起未更新,并且依赖于一些旧包。
What I have done:
我做了什么:
Convert from Joda time to Java 8 time. So it requires Java 8.
Covert Json parser from Gson to Hymanson 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.
All existing unit tests passed along with some newly added test cases.
所有现有的单元测试以及一些新添加的测试用例都通过了。
Here is a sample to generate token and verify the token. For more information, please check https://github.com/networknt/lightsource code for usage.
这是生成令牌并验证令牌的示例。更多信息,请查看https://github.com/networknt/light源代码的用法。
I am the author of both jsontoken and Omni-Channel Application Framework.
我是 jsontoken 和 Omni-Channel Application Framework 的作者。
回答by Hans Z.
This page keeps references to implementations in various languages, including Java, and compares features: http://kjur.github.io/jsjws/index_mat.html
此页面保留对包括 Java 在内的各种语言实现的引用,并比较功能:http: //kjur.github.io/jsjws/index_mat.html
回答by Anton Duzenko
If you only need to parse unsigned unencrypted tokens you could use this code:
如果您只需要解析未签名的未加密令牌,您可以使用以下代码:
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;
}
回答by Alireza Fattahi
By referring to https://jwt.io/you can find jwt
implementations in many languages including java
. Also the site provide some comparison between these implementation (the algorithms they support and ....).
通过参考https://jwt.io/,您可以找到jwt
多种语言的实现,包括java
. 该站点还提供了这些实现之间的一些比较(它们支持的算法和......)。
For java
these are mentioned libraries:
对于java
这些提到的库: