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() {
        }
    }
发布了337 篇原创文章 · 获赞 92 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43931625/article/details/104200687