Java 用户';将OAuth2令牌插入RestTemplate
如何正确获取用户的会话oauth2令牌 我使用Java 用户';将OAuth2令牌插入RestTemplate,java,spring,spring-security,oauth-2.0,Java,Spring,Spring Security,Oauth 2.0,如何正确获取用户的会话oauth2令牌 我使用spring-security-OAuth2-autoconfigure实现了一个OAuth2授权/资源服务器 我实现了一个客户端应用程序,它使用授权服务器登录用户并获取他的访问令牌。登录阶段工作正常,因此可以检索登录数据(通过oauth2过滤器使用访问令牌)。客户端应用程序请求中的主体正确显示授权服务器填写的所有权限 我想使用客户端应用程序作为代理,使用请求调用的用户的给定访问令牌发送Rest请求 我已经尝试使用@enableAuth2Client
spring-security-OAuth2-autoconfigure
实现了一个OAuth2授权/资源服务器
我实现了一个客户端应用程序,它使用授权服务器登录用户并获取他的访问令牌。登录阶段工作正常,因此可以检索登录数据(通过oauth2过滤器使用访问令牌)。客户端应用程序请求中的主体
正确显示授权服务器填写的所有权限
我想使用客户端应用程序作为代理,使用请求调用的用户的给定访问令牌发送Rest请求
我已经尝试使用@enableAuth2Client
,但这不起作用。尝试自动连线时,OAuth2RestTemplate
为空
我必须重新实现restemplate
的请求范围bean,该bean从SecurityContext
获取tokenValue
。这样行得通,但我觉得这不干净。这种行为很常见,所以我应该错过一些东西
application.yml
spring:
application.name: client
security:
oauth2:
client:
registration:
myclient:
client-id: client-id
client-secret: client-secret
redirect-uri: http://localhost:8081/login/oauth2/code/
authorization-grant-type: authorization_code
provider:
myclient:
authorization-uri: http://localhost:8090/oauth/authorize
token-uri: http://localhost:8090/oauth/token
user-info-uri: http://localhost:8090/me
user-name-attribute: name
证券配置
@配置
公共类安全配置扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
//@formatter:off
http.authorizeRequests()
.antMatchers(“/”,“/login”).permitAll()
.antMatchers(“/admin/**”).hasRole(“admin”)
.anyRequest().authenticated()
.and().oauth2Login()
.and().oauth2Client()的
;
//@formatter:on
}
@豆子
@作用域(value=WebApplicationContext.Scope\u请求,proxyMode=ScopedProxyMode.TARGET\u类)
@限定符(“oauth2RestTemplate”)
公共RestTemplate oauth2RestTemplate(){
RestTemplate RestTemplate=新RestTemplate();
restTemplate.getInterceptors().add(新的ClientHttpRequestInterceptor()){
@凌驾
公共ClientHttpResponse截获(HttpRequest请求,字节[]正文,ClientHttpPrequesteExecution执行)
抛出IOException{
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
if(auth!=null&&auth.isAuthenticated()&&auth实例of OAuth2AuthenticationToken){
@抑制警告(“未选中”)
映射细节=(映射)((OAuth2AuthenticationToken)auth.getPrincipal().getAttributes().get(“细节”);
String tokenValue=(String)details.get(“tokenValue”);
if(tokenValue!=null){
request.getHeaders().add(“授权”、“承载人”+令牌值);
}
}
返回执行。执行(请求,正文);
}
});
返回REST模板;
}
}
在网络控制器中
private@Autowired@Qualifier(“oauth2RestTemplate”)RestTemplate oauth2RestTemplate;
@GetMapping(“/remote”)
公共地图远程(){
@抑制警告(“未选中”)
Map resp=oauth2RestTemplate.getForObject(URI.create(“http://localhost:8090/api/test(),Map.class);
返回响应;
}
它可以工作,但我认为我不应该自己配置
RestTemplate
。不幸的是,您必须定义OAuth2RestTemplate
。然而,这是一个更干净的实现
@Bean
public OAuth2RestTemplate oauth2RestTemplate() {
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setAccessTokenUri(format("%s/oauth/token", authServerUrl));
resourceDetails.setClientId("client_id");
resourceDetails.setClientSecret("client_secret");
resourceDetails.setGrantType("client_credentials");
resourceDetails.setScope(asList("read", "write"));
DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
return new OAuth2RestTemplate(resourceDetails, clientContext);
}
在这种情况下,您的资源服务器将使用自己的凭据代表您与授权服务器通信 据我所知,这不是我想要的行为。在您的示例中,应用程序将使用自己的凭据访问远程资源,因此在远程资源方面,将没有关于最初访问我们的应用程序的资源所有者的信息。老实说,我和@CreatixEA有同样的问题,不幸的是还没有答案……是的,你是对的。您可以使用用户令牌创建作用域请求的
@Bean
,然后在使用RestTemplate时将其作为参数/头插入。