Spring 安全 OAuth2 JWT 令牌中继问题
Spring Security OAuth2 JWT Token Relay Issue
我在从一个 ResourceServer 与另一个 ResourceServer 通信时遇到令牌中继问题。
我的 AuthServer 基于 Dave Sayer 的示例,这是资源服务器 1 的 application.yml。
security:
user:
password: none
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: trusted
clientSecret: secret
资源服务器 2 中的配置非常相似,只是它使用不同的 clientId
这是我在资源服务器 1 中创建 OAuth2RestTemplate 的方式。
@LoadBalanced
@Bean
@Autowired
public OAuth2RestTemplate loadBalancedOauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
此调用需要 JWT OAuth2 令牌中继,但它可能不会发生。
@GetMapping("/test-relay")
public String fetchMyProfile2() {
final ResponseEntity<String> forEntity = oauthRestTemplate.getForEntity("http://my-oauth/users/me", String.class);
final String body = forEntity.getBody();
System.out.println("body = " + body);
return body;
}
这是我从 Postman RestClient 调用此端点 /test-relay
时遇到的异常。我在调用时在授权 Header 中指定了 JWT 令牌。
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)
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:205)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:648)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
我正在使用 Spring Boot 1.5.2/3。我的资源服务器也是一个 UI 服务器,如果我使用 Web 浏览器点击 url.
,这个调用工作正常
UPDATE-1
这个问题只发生在资源服务器上,它也是一个 UI 服务器,即上面有 @EnableOAuth2Sso
注释。对于没有 @EnableOAuth2Sso
的纯资源服务器,令牌中继工作得很好。
您可能会受到我报告的错误的影响 https://github.com/spring-cloud/spring-cloud-security/issues/123。查看此解决方法是否有帮助:
@Configuration
public class WorkaroundConfig extends WebMvcConfigurerAdapter {
@Autowired
@Qualifier("tokenRelayRequestInterceptor")
HandlerInterceptor handlerInterceptor;
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(handlerInterceptor);
}
}
我在从一个 ResourceServer 与另一个 ResourceServer 通信时遇到令牌中继问题。
我的 AuthServer 基于 Dave Sayer 的示例,这是资源服务器 1 的 application.yml。
security:
user:
password: none
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: trusted
clientSecret: secret
资源服务器 2 中的配置非常相似,只是它使用不同的 clientId
这是我在资源服务器 1 中创建 OAuth2RestTemplate 的方式。
@LoadBalanced
@Bean
@Autowired
public OAuth2RestTemplate loadBalancedOauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
此调用需要 JWT OAuth2 令牌中继,但它可能不会发生。
@GetMapping("/test-relay")
public String fetchMyProfile2() {
final ResponseEntity<String> forEntity = oauthRestTemplate.getForEntity("http://my-oauth/users/me", String.class);
final String body = forEntity.getBody();
System.out.println("body = " + body);
return body;
}
这是我从 Postman RestClient 调用此端点 /test-relay
时遇到的异常。我在调用时在授权 Header 中指定了 JWT 令牌。
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)
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:205)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:648)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
我正在使用 Spring Boot 1.5.2/3。我的资源服务器也是一个 UI 服务器,如果我使用 Web 浏览器点击 url.
,这个调用工作正常UPDATE-1
这个问题只发生在资源服务器上,它也是一个 UI 服务器,即上面有 @EnableOAuth2Sso
注释。对于没有 @EnableOAuth2Sso
的纯资源服务器,令牌中继工作得很好。
您可能会受到我报告的错误的影响 https://github.com/spring-cloud/spring-cloud-security/issues/123。查看此解决方法是否有帮助:
@Configuration
public class WorkaroundConfig extends WebMvcConfigurerAdapter {
@Autowired
@Qualifier("tokenRelayRequestInterceptor")
HandlerInterceptor handlerInterceptor;
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(handlerInterceptor);
}
}