spring cloud oauth2 jwt 使用说明
spring cloud oauth2 jwt 使用说明
*************************
jwt签名、验签相关类及接口
JwtAccessTokenConverter:token转换类
public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConverter, InitializingBean {
public static final String TOKEN_ID = "jti";
public static final String ACCESS_TOKEN_ID = "ati";
private static final Log logger = LogFactory.getLog(JwtAccessTokenConverter.class);
private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
private JwtClaimsSetVerifier jwtClaimsSetVerifier = new JwtAccessTokenConverter.NoOpJwtClaimsSetVerifier();
private JsonParser objectMapper = JsonParserFactory.create();
private String verifierKey = (new RandomValueStringGenerator()).generate(); //验签key,默认为随机值
private Signer signer; //签名操作
private String signingKey; //签名key
private SignatureVerifier verifier; //验签操作
*************
构造方法
public JwtAccessTokenConverter() {
this.signer = new MacSigner(this.verifierKey); //默认使用时MacSigner签名,使用算法HMACSHA256
this.signingKey = this.verifierKey; //签名key默认与verifierKey相同
}
*************
普通方法
public void setSigningKey(String key) { //设置签名key
Assert.hasText(key);
key = key.trim();
this.signingKey = key;
if (this.isPublic(key)) { //key以"----BEGIN"开头,则使用RsaSigner签名
this.signer = new RsaSigner(key);
logger.info("Configured with RSA signing key");
} else {
this.verifierKey = key;
this.signer = new MacSigner(key);
} //不以"----BEGIN"开头,则使用MacSigner签名
}
private boolean isPublic(String key) {
return key.startsWith("-----BEGIN");
}
public void setVerifierKey(String key) { //设置验签key
public void setVerifier(SignatureVerifier verifier) { //设置签名验证方法
public void setSigner(Signer signer) { //设置签名方法
public Map<String, String> getKey() {
public void setKeyPair(KeyPair keyPair) {
public void setAccessTokenConverter(AccessTokenConverter tokenConverter) {
public AccessTokenConverter getAccessTokenConverter() {
public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
public void setJwtClaimsSetVerifier(JwtClaimsSetVerifier jwtClaimsSetVerifier) {
public JwtClaimsSetVerifier getJwtClaimsSetVerifier() {
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
public boolean isPublic() {
public boolean isRefreshToken(OAuth2AccessToken token) {
public void afterPropertiesSet() throws Exception {
if (this.verifier == null) {
Object verifier = new MacSigner(this.verifierKey);
//验签优先使用MacSigner
try {
verifier = new RsaVerifier(this.verifierKey); //Rsaverifier创建成功,则使用RsaVerifier验签
} catch (Exception var5) {
logger.warn("Unable to create an RSA verifier from verifierKey (ignoreable if using MAC)");
}
if (this.signer instanceof RsaSigner) {
byte[] test = "test".getBytes();
try {
((SignatureVerifier)verifier).verify(test, this.signer.sign(test));
logger.info("Signing and verification RSA keys match");
} catch (InvalidSignatureException var4) {
logger.error("Signing and verification RSA keys do not match");
}
} else if (verifier instanceof MacSigner) {
Assert.state(this.signingKey == this.verifierKey, "For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key");
} //signingKey、verifierKey要相同,不同抛出异常
this.verifier = (SignatureVerifier)verifier;
}
}
MacSigner:签名、验签类,默认使用的算法为HMACSHA256
public class MacSigner implements SignerVerifier {
private static final String DEFAULT_ALGORITHM = "HMACSHA256";
private final String algorithm;
private final SecretKey key;
**************
构造方法
public MacSigner(byte[] key) {
public MacSigner(String key) {
public MacSigner(SecretKey key) {
public MacSigner(String algorithm, SecretKey key) {
**************
普通方法
public byte[] sign(byte[] bytes) {
try {
Mac mac = Mac.getInstance(this.algorithm);
mac.init(this.key);
return mac.doFinal(bytes);
} catch (GeneralSecurityException var3) {
throw new RuntimeException(var3);
} //对bytes进行签名
}
public void verify(byte[] content, byte[] signature) {
byte[] signed = this.sign(content);
if (!this.isEqual(signed, signature)) {
throw new InvalidSignatureException("Calculated signature did not match actual value");
} //检验content、签名内容signature是否想等,不相等则抛出异常
}
public String algorithm() {
return this.algorithm;
}
RsaVerifier:rsa验签类,默认使用的算法为SHA256withRSA
public class RsaVerifier implements SignatureVerifier {
private final RSAPublicKey key;
private final String algorithm;
public RsaVerifier(BigInteger n, BigInteger e) {
this(RsaKeyHelper.createPublicKey(n, e));
}
public RsaVerifier(RSAPublicKey key) {
this(key, "SHA256withRSA");
}
public RsaVerifier(RSAPublicKey key, String algorithm) {
this.key = key;
this.algorithm = algorithm;
}
public RsaVerifier(String key) {
this(RsaKeyHelper.parsePublicKey(key.trim()), "SHA256withRSA");
}
public void verify(byte[] content, byte[] sig) {
try {
Signature signature = Signature.getInstance(this.algorithm);
signature.initVerify(this.key);
signature.update(content);
if (!signature.verify(sig)) {
throw new InvalidSignatureException("RSA Signature did not match content");
}
} catch (GeneralSecurityException var4) {
throw new RuntimeException(var4);
}
}
public String algorithm() {
return this.algorithm;
}
}
SignerVerifier:签名、验签接口
public interface SignerVerifier extends Signer, SignatureVerifier {
}
Signer:签名接口
public interface Signer extends AlgorithmMetadata {
byte[] sign(byte[] var1);
}
SignatureVerifier:验签接口
public interface SignatureVerifier extends AlgorithmMetadata {
void verify(byte[] var1, byte[] var2);
}
AlgorithmMetadata:签名、验签算法
public interface AlgorithmMetadata {
String algorithm();
}
*************************
jwt 存储相关类及接口
JwtTokenStore:jwt存储
public class JwtTokenStore implements TokenStore {
private JwtAccessTokenConverter jwtTokenEnhancer; //token转换类
private ApprovalStore approvalStore; //token使用状态
***************
构造方法
public JwtTokenStore(JwtAccessTokenConverter jwtTokenEnhancer) {
***************
普通方法
public void setApprovalStore(ApprovalStore approvalStore) {
public OAuth2AccessToken readAccessToken(String tokenValue) {
public void removeAccessToken(OAuth2AccessToken token) {
public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
public OAuth2RefreshToken readRefreshToken(String tokenValue) {
public void removeRefreshToken(OAuth2RefreshToken token) {
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
public OAuth2Authentication readAuthentication(String token) {
public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
public void setTokenEnhancer(JwtAccessTokenConverter tokenEnhancer) {
ApprovalStore:设置客户端使用、禁用接口
public interface ApprovalStore {
boolean addApprovals(Collection<Approval> var1);
boolean revokeApprovals(Collection<Approval> var1);
Collection<Approval> getApprovals(String var1, String var2);
}
Approval:token使用状态
public class Approval {
private String userId;
private String clientId;
private String scope;
private Approval.ApprovalStatus status;
private Date expiresAt;
private Date lastUpdatedAt;
************
构造方法
public Approval(String userId, String clientId, String scope, int expiresIn, Approval.ApprovalStatus status) {
public Approval(String userId, String clientId, String scope, Date expiresAt, Approval.ApprovalStatus status) {
public Approval(String userId, String clientId, String scope, Date expiresAt, Approval.ApprovalStatus status, Date lastUpdatedAt) {
************
普通方法
public void setUserId(String userId) {
public void setClientId(String clientId) {
public void setScope(String scope) {
public void setStatus(Approval.ApprovalStatus status) {
public void setExpiresAt(Date expiresAt) {
public void setLastUpdatedAt(Date lastUpdatedAt) {
public String getUserId() {
public String getClientId() {
public String getScope() {
public Approval.ApprovalStatus getStatus() {
public Date getExpiresAt() {
public Date getLastUpdatedAt() {
public boolean isCurrentlyActive() {
return this.expiresAt != null && this.expiresAt.after(new Date());
} //过期时间不为null,且在当前时间之后则token存活
public boolean isApproved() {
return this.isCurrentlyActive() && this.status == Approval.ApprovalStatus.APPROVED;
} //token处于存活状态,且approval为Approved,则返回true
public static enum ApprovalStatus {
APPROVED, //使用
DENIED; //拒绝使用
private ApprovalStatus() {
}
}
还没有评论,来说两句吧...