Spring security 当配置为使用JWT时,Spring OAuth2RestTemplate将丢失令牌
我有一系列配置为使用Spring Boot和Cloud OAuth2 SSO的微服务项目。它具有以下组件: 弹簧靴1.3.0 春季云彩Brixton.M3 auth server有Spring Boot 1.2.7和Cloud Angel.SR4Spring security 当配置为使用JWT时,Spring OAuth2RestTemplate将丢失令牌,spring-security,oauth-2.0,spring-boot,jwt,spring-cloud,Spring Security,Oauth 2.0,Spring Boot,Jwt,Spring Cloud,我有一系列配置为使用Spring Boot和Cloud OAuth2 SSO的微服务项目。它具有以下组件: 弹簧靴1.3.0 春季云彩Brixton.M3 auth server有Spring Boot 1.2.7和Cloud Angel.SR4 Zuul代理(网关) 身份验证服务器 资源服务器 用户界面服务器 尤里卡服务器 基本流程是: 使用解析UI服务器的URL点击网关 通过身份验证服务器进行身份验证(通过SSO) 重定向到UI服务器 UI服务器从资源服务器请求资源(就像Hello W
- Zuul代理(网关)
- 身份验证服务器
- 资源服务器
- 用户界面服务器
- 尤里卡服务器
- 使用解析UI服务器的URL点击网关
- 通过身份验证服务器进行身份验证(通过SSO)
- 重定向到UI服务器
- UI服务器从资源服务器请求资源(就像Hello World一样的字符串)
- UI服务器在页面上显示字符串
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "foobar".toCharArray())
.getKeyPair("test");
converter.setKeyPair(keyPair);
return converter;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter());
}
然后使用公钥更改“客户端”服务的配置:
security:
oauth2:
resource:
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnGp/Q5lh0P8nPL21oMMrt2RrkT9AW5jgYwLfSUnJVc9G6uR3cXRRDCjHqWU5WYwivcF180A6CWp/ireQFFBNowgc5XaA0kPpzEtgsA5YsNX7iSnUibB004iBTfU9hZ2Rbsc8cWqynT0RyN4TP1RYVSeVKvMQk4GT1r7JCEC+TNu1ELmbNwMQyzKjsfBXyIOCFU/E94ktvsTZUHF4Oq44DBylCDsS1k7/sfZC2G5EU7Oz0mhG8+Uz6MSEQHtoIi6mc8u64Rwi3Z3tscuWG2ShtsUFuNSAFNkY7LkLn+/hxLCu2bNISMaESa8dG22CIMuIeRLVcAmEWEWH5EEforTg+QIDAQAB
-----END PUBLIC KEY-----
在UI服务器上运行之前,一切似乎都正常。也就是说,网关获取JWT令牌并可以对其进行解密,然后调用UI服务器。但是UI服务器中有一些代码调用另一个资源:
@EnableResourceServer
@EnableDiscoveryClient
@RestController
@SpringBootApplication
public class UiServerApplication {
// Must use OAuth2RestTemplate for token forwarding.
// To use load balancing could probably use Ribbon API to get service URL
@Autowired
private OAuth2RestTemplate restTemplate;
private static final String RESOURCE_URL = "http://localhost:9004/resource";
@RequestMapping("/")
public String home() {
return this.restTemplate.getForObject(RESOURCE_URL, String.class);
}
public static void main(String[] args) {
SpringApplication.run(UiServerApplication.class, args);
}
// Bug workaround. Apparently fixed in Spring Boot 1.3.1
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
static class WorkaroundRestTemplateCustomizer implements UserInfoRestTemplateCustomizer {
public void customize(OAuth2RestTemplate template) {
template.setInterceptors(new ArrayList<>(template.getInterceptors()));
}
}
}
更新:下面是我有时看到的另一个错误:
org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessTokenProvider.java:359) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:205) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:264) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at uk.co.aquilauk.UiServerApplication.home(UiServerApplication.java:33) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
令牌转发功能在Spring Cloud Security中(是谁为您创建了
OAuth2RestTemplate
)。它不是设计用来与JWT令牌一起工作的,但它可能可以被修改。为什么不提出一个问题?发生这种情况的原因是,当OAuth2AuthenticationManager工作时(即没有JWT),它有一个UserInfoTokenServices实例,该实例在身份验证后在OAuth2RestTemplate中设置访问令牌。当为JWT配置时,它有一个DefaultTokenServices实例,但它不这样做。所以我不确定问题出在哪里-配置错误还是什么。。。
org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessTokenProvider.java:359) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:205) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:264) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at uk.co.aquilauk.UiServerApplication.home(UiServerApplication.java:33) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]