JWT介绍
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。有如下优点:
- 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快
- 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
JWT的主要应用场景
身份认证
在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。
信息交换
在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。
关于JWT的介绍,有两篇文章介绍的很不错。
文章传送门1:http://blog.leapoahead.com/2015/09/06/understanding-jwt/
文章传送门2:https://segmentfault.com/a/1190000005047525
集成JWT
集成参考文章:http://blog.csdn.net/sun_t89/article/details/51923017
pom中引入SDK
jjwt库
<!-- JWT Json Web Token 依赖 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
添加登录获取token时,所需认证信息类
LoginParam.java
package com.redsoft.spirit.entity;
/*
* 登录获取token时,所需要的认证信息类
*/
public class LoginParam {
private String clientId;
private String userName;
private String password;
private String captchaCode;
private String captchaValue;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCaptchaCode() {
return captchaCode;
}
public void setCaptchaCode(String captchaCode) {
this.captchaCode = captchaCode;
}
public String getCaptchaValue() {
return captchaValue;
}
public void setCaptchaValue(String captchaValue) {
this.captchaValue = captchaValue;
}
}
添加JWT解析的帮助类
JwtHelper.java
package com.redsoft.spirit.util.jwt;
import java.security.Key;
import java.util.Date;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/*
* 构造及解析jwt的工具类
*/
public class JwtHelper {
public static Claims parseJWT(String jsonWebToken, String base64Security){
try
{
Claims claims = Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))
.parseClaimsJws(jsonWebToken).getBody();
return claims;
}
catch(Exception ex)
{
return null;
}
}
/**
* 生成token
*
* @author hetiewei
* @date 2016年10月18日 下午2:51:38
* @param name keyId
* @param userId
* @param role
* @param audience 接收者
* @param issuer 发行者
* @param TTLMillis 过期时间(毫秒)
* @param base64Security
* @return
*/
public static String createJWT(String name, String userId, String role,
String audience, String issuer, long TTLMillis, String base64Security)
{
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//生成签名密钥
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.claim("role", role)
.claim("userName", name)
.claim("userId", userId)
.setIssuer(issuer)
.setAudience(audience)
.signWith(signatureAlgorithm, signingKey);
//添加Token过期时间
if (TTLMillis >= 0) {
long expMillis = nowMillis + TTLMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp).setNotBefore(now);
}
//生成JWT
return builder.compact();
}
}
添加token返回结果类
AccessToken.java
package com.redsoft.spirit.entity;
/*
* JWT Token的返回结果
*/
public class AccessToken {
private String accessToken;
private String tokenType;
private long expiresIn;
private String userId;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}