spring security oauth2 jwt rsa非对称加密

spring | 2022-07-24 10:15:16

spring security只适合单机,spring security oauth2才是分布式的选择,分布式下我肯定搞jwt,要不然得考虑分布式session,jwt续签问题,不着急,慢慢来。

1.认证服务器配置token为jwt

package com.stackcloud.system.config;

import com.stackcloud.system.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import javax.sql.DataSource;
import java.util.Arrays;

/**
 * 认证服务器配置
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private TokenEnhancer tokenEnhancer;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    /**
     * <pre>
     *  我们配置了使用数据库来维护客户端信息。虽然在各种 Demo 中我们经常看到的是在内存中维护客户端信息, 通过配置直接写死在这里。
     *
     *  但是,对于实际的应用我们一般都会用数据库来维护这个信息,甚至还会建立一套工作流来允许客户端自己申请 ClientID,实现 OAuth 客户端接入的审批。
     * </pre>
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

    /**
     * 这里干了两件事儿。
     *   首先,打开了验证 Token 的访问权限(以便之后我们演示)。
     *   然后,允许 ClientSecret 明文方式保存,并且可以通过表单提交(而不仅仅是 BasicAuth方式提交),之后会演示到这个。
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("permitAll()")
                .allowFormAuthenticationForClients()
                .passwordEncoder(passwordEncoder);
    }

    /**
     * <pre>
     * 干了以下4件事儿:
     * 1. 配置我们的令牌存放方式为 JWT方式,而不是内存、数据库或 Redis方式。
     *      JWT 是 Json Web Token 的缩写,也就是使用 JSON 数据格式包装的令牌,由 .号把整个 JWT分隔为头、数据体、签名三部分。
     *      JWT保存 Token 虽然易于使用但是不是那么安全,一般用于内部,且需要走 HTTPS 并配置比较短的失效时间。
     * 2. 配置 JWT Token 的非对称加密来进行签名
     * 3. 配置一个自定义的 Token 增强器,把更多信息放入 Token 中
     * 4. 配置使用 JDBC 数据库方式来保存用户的授权批准记录
     * </pre>
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        //CustomTokenEnhancer 自定义的Token增强器,把更多信息放入Token中
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer, jwtAccessTokenConverter));
        endpoints
                //使用 JDBC 数据库方式来保存用户的授权批准记录
                .approvalStore(new JdbcApprovalStore(dataSource))
                //数据库保存授权码
                .authorizationCodeServices(new JdbcAuthorizationCodeServices(dataSource))
                //使用jwt
                .tokenStore(new JwtTokenStore(jwtAccessTokenConverter))
                .tokenEnhancer(tokenEnhancerChain)
                .authenticationManager(authenticationManager)
                .userDetailsService(sysUserService);
    }





}

2.JwtAccessTokenConverter研究

基于RSA无非就是私钥和公钥,看下源码

public void setKeyPair(KeyPair keyPair) {
		PrivateKey privateKey = keyPair.getPrivate();
		Assert.state(privateKey instanceof RSAPrivateKey, "KeyPair must be an RSA ");
		signer = new RsaSigner((RSAPrivateKey) privateKey);
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		verifier = new RsaVerifier(publicKey);
		verifierKey = "-----BEGIN PUBLIC KEY-----n" + new String(Base64.encode(publicKey.getEncoded()))
				+ "n-----END PUBLIC KEY-----";
	}

	/**
	 * Sets the JWT signing key. It can be either a simple MAC key or an RSA key. RSA keys
	 * should be in OpenSSH format, as produced by <tt>ssh-keygen</tt>.
	 *
	 * @param key the key to be used for signing JWTs.
	 */
	public void setSigningKey(String key) {
		Assert.hasText(key);
		key = key.trim();

		this.signingKey = key;

		if (isPublic(key)) {
			signer = new RsaSigner(key);
			logger.info("Configured with RSA signing key");
		}
		else {
			// Assume it's a MAC key
			this.verifierKey = key;
			signer = new MacSigner(key);
		}
	}

如果要用RSA得按OPENSSH得格式,需要用ssh-keygen生成,所谓格式就是上面得开头是 -----BEGIN PUBLIC KEY-----,结尾是-----END PUBLIC KEY-----。

3.生成RSA 密钥对

在linux上,随便搞个虚拟机都可以,基于java得 keygen下次再研究。

[root@localhost test]# openssl rsa -in jwt.pem
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqI/1ah3MdXUeSxKSlYqalvk9Kdns8K8cqKDaJ5qz0RCJw+CA
T032iaGL1PuK/hIbNaarLBzB0SZPxp5v1UE/ERnLfYiq+yFlTfp3FniWKEjdWby1
vvvWJYtYNb+zuk07gVLOzONAX/ZdOaZVtwUm/+lEU5wcHk6GnSvM/q8KYJJ/2VXG
kuXw7sQDok1deVuDsN7DBbXhfahYAdWupC22fy5RRPm8ea8oOxif/eZxzkgWicco
BgFExdiOZMTXg3y8LxDl2c23FRXYegT8ZmxANyjvuVDIchTmkqbMoa6SkRVL8B3W
esEpB35Ag8g6h71CMT6S2mUMgFBlU7JgSIM5SQIDAQABAoIBAHfafI6qh4GQ+Cw7
FX09I3Rr3eCPMtlkOcVxMgztBCSIVNyxGarJ7Z2o/ys+fHLxXuWED7v66pkTW7AH
Yc9JaFV5eOZWsfSEp2qNx/VzYplcTf+LndMhcAAcF2mIWHwEhGYNAjxO7awOGfVu
3w2WnUdjjpDAtIGcJj1FMqp4vbEx8kn/4ogeBZp2+tnHATQiU976ML0jxjcEAKMW
7unefDN1wmaVf8r0Glvef1YVjtZCVPVBkYs2GVsSvi44wka0Nkj/4mdk5QtOcb6s
XMKjqU1kUeCslSB2T7xHaknU+Xwo/skRWkMaOWO4ZQDrqunRu5QvfQQtnE25O37e
lguYu4ECgYEA0LBUKh6pEgFcWFutf3igWElGoH0OjwEaKdptvMYmGtC/YGViwhvn
t9JhUu44pUDt9tKJ6h8poB7xr6aQa05dEAbrN7paYTn/KsxBSOIj/vh8InNKCLFo
V9MU45qMikF8f57LSvIF5o4NVJstKQGWa45XPMdxTzNg3+9RUgiHJRkCgYEAzsbP
sVGsitly3nICRSVcLaT4JkXvfwk0EcGv+lha9TZR266w6V3LzgshyK1FbM8ukDTm
Fe5Q0zzHpeqjU4yhPxnCIIFXPQBVQxyZT0M2eN44E35pNTZ3liJS0r5/4n9HhPiM
n1eBZFwVhOlPjDkC6yZzD7Z6olXxO+AHyhEei7ECgYEAnhFxLpYaqbCuKZ8HQ04y
5axa+qS+qkLDdoAkLqBHrHgA/RrOOwi38tw/K3mVHlaX6CSAof0IomfN2KXpLd4l
T0ZuU7+rRYmQZPJhYLspWK8OF2oL4Zm+1wbjA6LEYNRJYMD+ar33CjL+ld8TzcOO
E9m06iyG/t6DuhqjFeevtcECgYAqWRFEMYPy0+HwqMzKOIKOXpDr1brc+5eMY2yV
Cu9l9QACy94zjSAmTKVYohPr2uqgYhUVPL+U44fH9SwJ+m0zrSTS32psddsAaaUE
VLGdQ3WcmHEXktYfC1yHCLjMPGD7XKQAJj27vhgyJk5CW5K7ch5yg17OTGehaZpu
yd7FoQKBgQCPvldGHOyCUl4NqW/r7NQI2h5DEAGyFZNqttcse0zLjScVeksFKgeX
dMIXZT84tMWHnfbDV3zH3PKw8OKruICbaF273ayl3ntmlAqfqmmQtbiKH880hJV4
SWeSmF+YNsmblmxSVYGNjvb+gYyesKLseYJE1YfEEedrFo87KaV6Kg==
-----END RSA PRIVATE KEY-----
[root@localhost test]# openssl rsa -in jwt.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqI/1ah3MdXUeSxKSlYqa
lvk9Kdns8K8cqKDaJ5qz0RCJw+CAT032iaGL1PuK/hIbNaarLBzB0SZPxp5v1UE/
ERnLfYiq+yFlTfp3FniWKEjdWby1vvvWJYtYNb+zuk07gVLOzONAX/ZdOaZVtwUm
/+lEU5wcHk6GnSvM/q8KYJJ/2VXGkuXw7sQDok1deVuDsN7DBbXhfahYAdWupC22
fy5RRPm8ea8oOxif/eZxzkgWiccoBgFExdiOZMTXg3y8LxDl2c23FRXYegT8ZmxA
NyjvuVDIchTmkqbMoa6SkRVL8B3WesEpB35Ag8g6h71CMT6S2mUMgFBlU7JgSIM5
SQIDAQAB
-----END PUBLIC KEY-----
[root@localhost test]#

 

4.添加到配置文件

  security:
    oauth2:
      jwt:
        privateKey: |
          -----BEGIN RSA PRIVATE KEY-----
          MIIEpAIBAAKCAQEAqI/1ah3MdXUeSxKSlYqalvk9Kdns8K8cqKDaJ5qz0RCJw+CA
          T032iaGL1PuK/hIbNaarLBzB0SZPxp5v1UE/ERnLfYiq+yFlTfp3FniWKEjdWby1
          vvvWJYtYNb+zuk07gVLOzONAX/ZdOaZVtwUm/+lEU5wcHk6GnSvM/q8KYJJ/2VXG
          kuXw7sQDok1deVuDsN7DBbXhfahYAdWupC22fy5RRPm8ea8oOxif/eZxzkgWicco
          BgFExdiOZMTXg3y8LxDl2c23FRXYegT8ZmxANyjvuVDIchTmkqbMoa6SkRVL8B3W
          esEpB35Ag8g6h71CMT6S2mUMgFBlU7JgSIM5SQIDAQABAoIBAHfafI6qh4GQ+Cw7
          FX09I3Rr3eCPMtlkOcVxMgztBCSIVNyxGarJ7Z2o/ys+fHLxXuWED7v66pkTW7AH
          Yc9JaFV5eOZWsfSEp2qNx/VzYplcTf+LndMhcAAcF2mIWHwEhGYNAjxO7awOGfVu
          3w2WnUdjjpDAtIGcJj1FMqp4vbEx8kn/4ogeBZp2+tnHATQiU976ML0jxjcEAKMW
          7unefDN1wmaVf8r0Glvef1YVjtZCVPVBkYs2GVsSvi44wka0Nkj/4mdk5QtOcb6s
          XMKjqU1kUeCslSB2T7xHaknU+Xwo/skRWkMaOWO4ZQDrqunRu5QvfQQtnE25O37e
          lguYu4ECgYEA0LBUKh6pEgFcWFutf3igWElGoH0OjwEaKdptvMYmGtC/YGViwhvn
          t9JhUu44pUDt9tKJ6h8poB7xr6aQa05dEAbrN7paYTn/KsxBSOIj/vh8InNKCLFo
          V9MU45qMikF8f57LSvIF5o4NVJstKQGWa45XPMdxTzNg3+9RUgiHJRkCgYEAzsbP
          sVGsitly3nICRSVcLaT4JkXvfwk0EcGv+lha9TZR266w6V3LzgshyK1FbM8ukDTm
          Fe5Q0zzHpeqjU4yhPxnCIIFXPQBVQxyZT0M2eN44E35pNTZ3liJS0r5/4n9HhPiM
          n1eBZFwVhOlPjDkC6yZzD7Z6olXxO+AHyhEei7ECgYEAnhFxLpYaqbCuKZ8HQ04y
          5axa+qS+qkLDdoAkLqBHrHgA/RrOOwi38tw/K3mVHlaX6CSAof0IomfN2KXpLd4l
          T0ZuU7+rRYmQZPJhYLspWK8OF2oL4Zm+1wbjA6LEYNRJYMD+ar33CjL+ld8TzcOO
          E9m06iyG/t6DuhqjFeevtcECgYAqWRFEMYPy0+HwqMzKOIKOXpDr1brc+5eMY2yV
          Cu9l9QACy94zjSAmTKVYohPr2uqgYhUVPL+U44fH9SwJ+m0zrSTS32psddsAaaUE
          VLGdQ3WcmHEXktYfC1yHCLjMPGD7XKQAJj27vhgyJk5CW5K7ch5yg17OTGehaZpu
          yd7FoQKBgQCPvldGHOyCUl4NqW/r7NQI2h5DEAGyFZNqttcse0zLjScVeksFKgeX
          dMIXZT84tMWHnfbDV3zH3PKw8OKruICbaF273ayl3ntmlAqfqmmQtbiKH880hJV4
          SWeSmF+YNsmblmxSVYGNjvb+gYyesKLseYJE1YfEEedrFo87KaV6Kg==
          -----END RSA PRIVATE KEY-----

        publicKey: |
          -----BEGIN PUBLIC KEY-----
          MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqI/1ah3MdXUeSxKSlYqa
          lvk9Kdns8K8cqKDaJ5qz0RCJw+CAT032iaGL1PuK/hIbNaarLBzB0SZPxp5v1UE/
          ERnLfYiq+yFlTfp3FniWKEjdWby1vvvWJYtYNb+zuk07gVLOzONAX/ZdOaZVtwUm
          /+lEU5wcHk6GnSvM/q8KYJJ/2VXGkuXw7sQDok1deVuDsN7DBbXhfahYAdWupC22
          fy5RRPm8ea8oOxif/eZxzkgWiccoBgFExdiOZMTXg3y8LxDl2c23FRXYegT8ZmxA
          NyjvuVDIchTmkqbMoa6SkRVL8B3WesEpB35Ag8g6h71CMT6S2mUMgFBlU7JgSIM5
          SQIDAQAB
          -----END PUBLIC KEY-----

 

5.JwtAccessTokenConverter设置

/**
     * 配置 JWT 使用非对称加密方式来验证
     *
     * @return
     */
    @Bean
    protected JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(jwtPrivateKey);
        converter.setVerifierKey(jwtPublicKey);
        return converter;
    }

SigningKey就是私钥,用私钥来签名,就是生成token的,VerifierKey就是公钥,等下jwt token进来 用公钥验签。

 

6.测试

获取token

http://localhost:9011/oauth/token?username=admin&grant_type=password&client_id=userservice1&client_secret=1234&password=admin

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlcnNlcnZpY2UiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJGT08iXSwiZXhwIjoxNjU4NjM1Nzg1LCJ1c2VyRGV0YWlscyI6eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiJDJhJDEwJDhFM01yTVcvY0RISldmLkNxSkpLcHVnaDVjQjZYNFlvZlQvQmkvNXZ6S1JKTGZiYVV4ckppIiwicm9sZUxpc3QiOm51bGwsImxvY2tlZCI6ZmFsc2UsImVuYWJsZWQiOnRydWUsImV4cGlyZWQiOmZhbHNlLCJhdXRob3JpdGllcyI6bnVsbCwiYWNjb3VudE5vbkxvY2tlZCI6dHJ1ZSwiY3JlZGVudGlhbHNOb25FeHBpcmVkIjp0cnVlLCJhY2NvdW50Tm9uRXhwaXJlZCI6dHJ1ZSwiY3JlZGVudGlhbHMiOnRydWV9LCJqdGkiOiI1Nzg1MjBmOS1iY2RlLTQxNGQtYjQyOS02N2ExZThiZmQ3NmYiLCJjbGllbnRfaWQiOiJ1c2Vyc2VydmljZTEifQ.Ibnf2rPlgpfcdUtQbJaqxGDXBegEPWTW4Xx0eDdMDyVtmc1fosIfXDiMfvBeTBe8ROWzOva9NrU57xBHOm-Nhr4xfnT44QE7X7dejYJ5CjRhRvVfiFlYvMO_8tZeGjPR3EuyIxnQia4uYQpIDn65yyagVYKALzLMVtiADzD10aS9dzrW5PQOtWMzM4DFI6GeIZlq_qhsX-NUsYFQYoTtaWFXEqzlPDZTrpI6LAvn9ZRui0kfz0h06Zy_5EC0ogRUTS-T-S4oOFs4sUi_MNb7gJFP8kts7BXQYndtXH_Djsm4GaytU6AjdW96mVKArrCMAlar45gBKPorvdlJt7qs3w",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlcnNlcnZpY2UiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJGT08iXSwiYXRpIjoiNTc4NTIwZjktYmNkZS00MTRkLWI0MjktNjdhMWU4YmZkNzZmIiwiZXhwIjoxNjYxMjIwNTg1LCJ1c2VyRGV0YWlscyI6eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiJDJhJDEwJDhFM01yTVcvY0RISldmLkNxSkpLcHVnaDVjQjZYNFlvZlQvQmkvNXZ6S1JKTGZiYVV4ckppIiwicm9sZUxpc3QiOm51bGwsImxvY2tlZCI6ZmFsc2UsImVuYWJsZWQiOnRydWUsImV4cGlyZWQiOmZhbHNlLCJhdXRob3JpdGllcyI6bnVsbCwiYWNjb3VudE5vbkxvY2tlZCI6dHJ1ZSwiY3JlZGVudGlhbHNOb25FeHBpcmVkIjp0cnVlLCJhY2NvdW50Tm9uRXhwaXJlZCI6dHJ1ZSwiY3JlZGVudGlhbHMiOnRydWV9LCJqdGkiOiJmNjU3ODVmMS0xNDI5LTQ1Y2MtOWRkZS04MTRiM2VkYmZjZmYiLCJjbGllbnRfaWQiOiJ1c2Vyc2VydmljZTEifQ.YhjHRbAmsSlh0gc1CzrRbMz918CQ42giW9a8MXPvF5y3Eg4fl_KwKjaZjhgKE8wnZr8ueDQxK46pviQwwzwfN5UBt1VgJahPEVUX2mtREEwdPl5MYZESMSx8pYDZopqMLD1qHpzrjkf45AbONVAECP6srfR-324lXxCd2ldA3jbwfxsexotQDawvC7UuQYn6N3KFV-P8QBpz9KE7dnkqEIFbMMzjtvzO-_u-_4A-tnCwXFxVULxXMawghLbjOb8jEoq0NbqOXHZxVlvigCDNy55x0OH74PU__SCmqp4qs05zJ5TANDM6OPvF2pAvbpD_b-oZzH3pA2mWNtqqPWkHpw",
    "expires_in": 7199,
    "scope": "FOO",
    "userDetails": {
        "id": 1,
        "username": "admin",
        "password": "$2a$10$8E3MrMW/cDHJWf.CqJJKpugh5cB6X4YofT/Bi/5vzKRJLfbaUxrJi",
        "locked": false,
        "enabled": true,
        "expired": false,
        "accountNonLocked": true,
        "credentialsNonExpired": true,
        "accountNonExpired": true,
        "credentials": true
    },
    "jti": "578520f9-bcde-414d-b429-67a1e8bfd76f"
}

验证token

http://localhost:9011/oauth/check_token?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlcnNlcnZpY2UiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJGT08iXSwiZXhwIjoxNjU4NjMzODQ1LCJ1c2VyRGV0YWlscyI6eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiJDJhJDEwJDhFM01yTVcvY0RISldmLkNxSkpLcHVnaDVjQjZYNFlvZlQvQmkvNXZ6S1JKTGZiYVV4ckppIiwicm9sZUxpc3QiOm51bGwsImxvY2tlZCI6ZmFsc2UsImVuYWJsZWQiOnRydWUsImV4cGlyZWQiOmZhbHNlLCJhdXRob3JpdGllcyI6bnVsbCwiYWNjb3VudE5vbkxvY2tlZCI6dHJ1ZSwiY3JlZGVudGlhbHNOb25FeHBpcmVkIjp0cnVlLCJhY2NvdW50Tm9uRXhwaXJlZCI6dHJ1ZSwiY3JlZGVudGlhbHMiOnRydWV9LCJqdGkiOiIzY2ZiMmE1NC01NjQzLTQ1YWEtYjZkZi01ZmY5MzIxN2U5MTQiLCJjbGllbnRfaWQiOiJ1c2Vyc2VydmljZTEifQ.gjb_otXav_FHzGqKo4KMNbQLNu0BXzbSmIR9_kl0BN2zFnKfCRm6oJKgquhwNv6U0M7UEFLhDlCC594Nuy8XDrdrGpkAb03t4fGQB_zqZscbD--n5kKLYP8yNb1FYrgS90d9p4Elfi4_IkS34nBKOmfmI-NS17ePAQBWXoQTEpTk8QJ3Nuh_OWSlG7EZoRsevCtD4OlRawLCCWhTIdUVKbTQeJz_V2qOrJKtu0jiTWIom_77CfaEd2sSF-s28ZndsEH1mOwd7KZlCUm_cGn1QnpFI_MEQLXWDzsZDY3Ctv97vX26gVlNCh8WUQhx4gsMdA7r53ClzQZld6FIV7pWQg

{
    "aud": [
        "userservice"
    ],
    "user_name": "admin",
    "scope": [
        "FOO"
    ],
    "active": true,
    "exp": 1658633845,
    "userDetails": {
        "id": 1,
        "username": "admin",
        "password": "$2a$10$8E3MrMW/cDHJWf.CqJJKpugh5cB6X4YofT/Bi/5vzKRJLfbaUxrJi",
        "locked": false,
        "enabled": true,
        "expired": false,
        "accountNonLocked": true,
        "credentialsNonExpired": true,
        "accountNonExpired": true,
        "credentials": true
    },
    "jti": "3cfb2a54-5643-45aa-b6df-5ff93217e914",
    "client_id": "userservice1"
}

 

7.异构系统之间的token使用

假如其他系统基于我这个权限验证,比如python,其他java程序,当然是可以的,因为spring security oauth2 jwt 也是标准的。

比如我基于java jwt

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.2.0</version>
        </dependency>

使用标准jwt来解析

        String ftoken="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidXNlcnNlcnZpY2UiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJGT08iXSwiZXhwIjoxNjU4NjMzODQ1LCJ1c2VyRGV0YWlscyI6eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiJDJhJDEwJDhFM01yTVcvY0RISldmLkNxSkpLcHVnaDVjQjZYNFlvZlQvQmkvNXZ6S1JKTGZiYVV4ckppIiwicm9sZUxpc3QiOm51bGwsImxvY2tlZCI6ZmFsc2UsImVuYWJsZWQiOnRydWUsImV4cGlyZWQiOmZhbHNlLCJhdXRob3JpdGllcyI6bnVsbCwiYWNjb3VudE5vbkxvY2tlZCI6dHJ1ZSwiY3JlZGVudGlhbHNOb25FeHBpcmVkIjp0cnVlLCJhY2NvdW50Tm9uRXhwaXJlZCI6dHJ1ZSwiY3JlZGVudGlhbHMiOnRydWV9LCJqdGkiOiIzY2ZiMmE1NC01NjQzLTQ1YWEtYjZkZi01ZmY5MzIxN2U5MTQiLCJjbGllbnRfaWQiOiJ1c2Vyc2VydmljZTEifQ.gjb_otXav_FHzGqKo4KMNbQLNu0BXzbSmIR9_kl0BN2zFnKfCRm6oJKgquhwNv6U0M7UEFLhDlCC594Nuy8XDrdrGpkAb03t4fGQB_zqZscbD--n5kKLYP8yNb1FYrgS90d9p4Elfi4_IkS34nBKOmfmI-NS17ePAQBWXoQTEpTk8QJ3Nuh_OWSlG7EZoRsevCtD4OlRawLCCWhTIdUVKbTQeJz_V2qOrJKtu0jiTWIom_77CfaEd2sSF-s28ZndsEH1mOwd7KZlCUm_cGn1QnpFI_MEQLXWDzsZDY3Ctv97vX26gVlNCh8WUQhx4gsMdA7r53ClzQZld6FIV7pWQg";
        
        String pkeyd=
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqI/1ah3MdXUeSxKSlYqan" +
                "lvk9Kdns8K8cqKDaJ5qz0RCJw+CAT032iaGL1PuK/hIbNaarLBzB0SZPxp5v1UE/n" +
                "ERnLfYiq+yFlTfp3FniWKEjdWby1vvvWJYtYNb+zuk07gVLOzONAX/ZdOaZVtwUmn" +
                "/+lEU5wcHk6GnSvM/q8KYJJ/2VXGkuXw7sQDok1deVuDsN7DBbXhfahYAdWupC22n" +
                "fy5RRPm8ea8oOxif/eZxzkgWiccoBgFExdiOZMTXg3y8LxDl2c23FRXYegT8ZmxAn" +
                "NyjvuVDIchTmkqbMoa6SkRVL8B3WesEpB35Ag8g6h71CMT6S2mUMgFBlU7JgSIM5n" +
                "SQIDAQABn" ;

        DecodedJWT decodedJWT = JWT.require(Algorithm.RSA256((RSAPublicKey)RSAUtil.getPublicKeyByBase64Code(pkeyd),null)).build().verify(ftoken);
        String userId= decodedJWT.getClaim("user_name").asString();
        System.out.println(userId);

注意要把publickey前缀后缀去掉,测试了一下,完全没问题

 

 

 

 

登录后即可回复 登录 | 注册
    
关注编程学问公众号