Spring Boot-使用JWT,OAuth以及单独的资源和Auth服务器 [英] Spring Boot - Using JWT, OAuth, and Separate Resource and Auth Servers

查看:373
本文介绍了Spring Boot-使用JWT,OAuth以及单独的资源和Auth服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个使用JWT令牌和OAuth2协议的Spring应用程序.感谢先前的问题,这是我当前的尝试:

I am attempting to build a Spring application that uses JWT tokens and the OAuth2 protocol. I have the Authentication Server running thanks to this tutorial. However, I am struggling with getting the Resource Server to function properly. From following the article, and thanks to a response to a prior question, this is my current attempt:

资源服务器的安全配置:

Security config for Resource Server:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${security.signing-key}")
    private String signingKey;

    @Value("${security.encoding-strength}")
    private Integer clientID;

    @Value("${security.security-realm}")
    private String securityRealm;

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setVerifierKey(signingKey);
        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean ResourceServerTokenServices tokenService() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        OAuth2AuthenticationManager authManager = new OAuth2AuthenticationManager();
        authManager.setTokenServices(tokenService());
        return authManager;
    }

}

资源服务器配置:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private ResourceServerTokenServices tokenServices;

@Value("${security.jwt.resource-ids}")
private String resourceIds;

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId(resourceIds).tokenServices(tokenServices);
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.requestMatchers().and().authorizeRequests().antMatchers("/actuator/**", "/api-docs/**").permitAll()
            .antMatchers("/**").authenticated();
}

}

授权服务器的安全性配置(来自已说明的教程):

Security config for Authorization Server (from noted tutorial):

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${security.signing-key}")
    private String signingKey;

    @Value("${security.encoding-strength}")
    private Integer encodingStrength;

    @Value("${security.security-realm}")
    private String securityRealm;

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(new ShaPasswordEncoder(encodingStrength));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .httpBasic()
                .realmName(securityRealm)
                .and()
                .csrf()
                .disable();

    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(signingKey);
        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    @Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }
}

现在,当我尝试向资源服务器发出请求时,收到如下错误:

Now, when I attempt to make a request to the Resource server, I receive an error such as follows:

{"error":"invalid_token","error_description":"Invalid access token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiam9obi5kb2UiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXh wIjoxNTE1MTE3NTU4LCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF"}

{"error":"invalid_token","error_description":"Invalid access token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiam9obi5kb2UiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXh wIjoxNTE1MTE3NTU4LCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF"}

我有几个问题:

  • 据我了解,该问题通常与令牌存储相关.使用JwtTokenStore时如何处理服务器分离?
  • 第二,当前,我的Resource应用程序依赖于对密钥的访问.就我对JWT和0Auth规范的理解而言,这不是必需的.相反,我应该能够将验证委派给身份验证服务器本身.从Spring文档中,我认为以下属性可能适用security.oauth2.resource.token-info-uri=http://localhost:8080/oauth/check_token.但是,如果我尝试不依赖资源服务器上的密钥,则会遇到设置ResourceServerTokenService的困难.该服务需要一个令牌存储,JWTTokenStore使用一个JwtAccessTokenConverter,而转换器使用一个密钥(删除密钥会导致我之前遇到的相同的invalid token错误).
  • To my understanding, the issue is often associated with token stores. How does one handle separting the servers when a JwtTokenStore is used?
  • Second, currently, my Resource app relies on having access to a key. To my understanding of the JWT and 0Auth specs, this should not be necessary. Rather, I should be able to delegate the validation to the Authentication server itself. From the Spring docs, I thought the following property might be applicable security.oauth2.resource.token-info-uri=http://localhost:8080/oauth/check_token. However, if I attempt to not rely on a key with my Resource Server, then I run into difficulties setting my ResourceServerTokenService. The service expects a token store, the JWTTokenStore uses a JwtAccessTokenConverter, and the converter uses a key (removing the key resulted in the same invalid token error I experienced earlier).

我真的很难找到可以显示如何将Auth和Resource服务器分开的文章.任何建议将不胜感激.

I am really struggling to find articles that show how to separate the Auth and Resource server. Any advice would be appreciated.

实际上,资源服务器的代码现在无法通过以下消息进行编译:

Actually, the code for the Resource Server is now failing to compile with the following message:

Caused by: java.lang.IllegalStateException: For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key

推荐答案

我尝试了spring oauth,但遇到了相同的错误:

I tried spring oauth and I came across the same error :

Caused by: java.lang.IllegalStateException: For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key

我的错误是我的公开证书是:

My mistake was that my public certificate was :

-----BEGIN PUBLIC KEY-----
tadadada
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
tadadada
-----END CERTIFICATE-----

这是不允许的.删除证书,只需将公钥放入此文件中即可:

And this is not allowed. REMOVE the certificate, just let the public key in this file :

-----BEGIN PUBLIC KEY-----
tadadada
-----END PUBLIC KEY-----

并且启动错误将消失.

对于第二个问题,这就是我的理解:

For your second question, that's what I understand :

  • 身份验证服务器为您提供一个加密的令牌(使用私钥加密),其中包含用户的所有权限.

  • The authentication server give you an encrypted token (encrypted with the private key), that contains ALL the permissions of your user.

资源服务器使用公共密钥解密令牌,并假定令牌中包含的权限为TRUE.

The resource server decrypts the token with the public key, and assumes that the permissions contained in the token are TRUE.

希望获得帮助.

这篇关于Spring Boot-使用JWT,OAuth以及单独的资源和Auth服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆