我可以使用KecloakRestTemplate,其中一个keycloak客户端正在与另一个keycloak客户端进行通信。但是它只有在我登录到第一个keycloak客户端时才有效,即它将客户端ID,客户端密钥,用户名,密码发送到keycloak服务器。如果我没有在第一个客户端上使用用户和密码进行身份验证,我会收到“无法设置授权标头,因为没有经过验证的原则”。但是我已经将keycloak配置为使用第一个客户端的服务帐户(Client Credential Grant),因此我不应该使用用户/密码,而应仅依赖客户端ID /机密。这是OAuth 2规范的错误/偏离吗?
答案 0 :(得分:2)
<!DOCTYPE html>
<html>
body>
<body background="download.jpg">
<cfset name ="swanav"/>
<cfoutput>#name#</cfoutput>
</body>
</html>
将客户端ID,客户端密钥,用户名和密码发送到Keycloak服务器。我只想发送客户端ID和密码。我创建了一个KeycloakRestTemplate
KeycloakClientCredentialsRestTemplate
子类来执行此操作。它在Spring Boot中使用OAuth2支持来执行客户端凭据授权。它还需要来自OAuth2RestTemplate
的Keycloak属性。
application.properties
此外:
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
public class KeycloakClientCredentialsRestTemplate extends OAuth2RestTemplate {
public KeycloakClientCredentialsRestTemplate(OAuth2ProtectedResourceDetails resource,
OAuth2ClientContext context) {
super(resource, context);
}
}
答案 1 :(得分:0)
对于基于微服务架构的应用程序,我同时使用用户和service accounts。我猜Spring安全适配器只负责用户相关的东西(我使用的版本,至少是2.2.1)。我所做的就是拥有另一个RestTemplate
,我自己处理这个问题,以便作为客户端访问资源。
举个例子:
@Service
public class RemoteAccessService{
//Manages user access
private KeycloakRestTemplate userAccessRestTemplate;
//Manages client access
private RestTemplate clientAccessRestTemplate;
public RemoteAccessService(KeycloakRestTemplate userAccessRestTemplate,
@Qualifier("clientAccessRestTemplate") RestTemplate clientAccessRestTemplate;){
}
}
然后,在RestTemplate
类中构建一个@Configuration
bean以管理客户端授权:
@Bean
public RestTemplate clientAccessRestTemplate() {
RestTemplate template = new RestTemplate();
template.getMessageConverters().add(new FormHttpMessageConverter());
template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
template.getInterceptors().add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
//Intercept each of the requests performed by this template
//and add the client access token in the Authorization header
HttpRequest wrapper = new HttpRequestWrapper(request);
if (clientAccessToken != null) {
wrapper.getHeaders().set("Authorization",
"Bearer " + clientAccessToken.getToken());
}
return execution.execute(wrapper, body);
}
});
return template;
}
当然,你需要确保在拦截器中有一个合适的clientAccessToken
,否则你将获得401或403代码。在这里,你有一个关于如何在OAuth中执行此操作的post(您不需要用户/密码,只需要客户端凭据)。
作为旁注,keycloak适配器可以方便地管理某些情况,但它们无法访问keycloak的所有功能,这是一种更强大的功能。