我可以使用KecloakRestTemplate,其中一个keycloak客户端正在与另一个keycloak客户端进行通信。然而,只有当我登录到第一个keycloak客户端时它才有效,即它将客户端ID,客户端密码,用户名,密码发送到keycloak服务器。如果我没有在第一个客户端上使用用户和密码进行身份验证,则会收到“无法设置授权标头,因为没有经过身份验证的原则”。但是我已经配置了keycloak为第一个客户端使用服务帐户(Client Credential Grant),因此我不应该使用用户/密码,并且应该仅依赖于客户端ID /密码。这是否是OAuth 2规范的错误/偏差?Keycloak弹簧安全客户端凭证授权
0
A
回答
0
对于基于微服务架构的应用程序,我使用用户和客户端帐户。我猜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;){
}
}
然后,建立一个@Configuration
类RestTemplate
豆,以管理客户端授权:
@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所有功能的访问,这是一种更强大的方式。
0
KeycloakRestTemplate
将客户端ID,客户端密码,用户名和密码发送到Keycloak服务器。我只想发送客户端ID和密码。我创建了一个KeycloakClientCredentialsRestTemplate
子类OAuth2RestTemplate
来做到这一点。它在Spring Boot中使用OAuth2支持来执行客户端凭据授权。它还需要application.properties
的Keycloak属性。
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);
}
}
另外:
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
import org.springframework.stereotype.Service;
@Service
public class KeycloakClientCredentialsConfig {
@Value("${keycloak.realm}")
private String realm;
@Value("${keycloak.auth-server-url}")
private String authServerUrl;
@Value("${keycloak.resource}")
private String clientId;
@Value("${keycloak.credentials.secret}")
private String clientSecret;
@Bean
public KeycloakClientCredentialsRestTemplate createRestTemplate() {
return new KeycloakClientCredentialsRestTemplate(getClientCredentialsResourceDetails(),
new DefaultOAuth2ClientContext());
}
private ClientCredentialsResourceDetails getClientCredentialsResourceDetails() {
String accessTokenUri = String.format("%s/realms/%s/protocol/openid-connect/token",
authServerUrl, realm);
List<String> scopes = new ArrayList<String>(0); // TODO introduce scopes
ClientCredentialsResourceDetails clientCredentialsResourceDetails =
new ClientCredentialsResourceDetails();
clientCredentialsResourceDetails.setAccessTokenUri(accessTokenUri);
clientCredentialsResourceDetails.setAuthenticationScheme(AuthenticationScheme.header);
clientCredentialsResourceDetails.setClientId(clientId);
clientCredentialsResourceDetails.setClientSecret(clientSecret);
clientCredentialsResourceDetails.setScope(scopes);
return clientCredentialsResourceDetails;
}
}
相关问题
- 1. Keycloak和弹簧安全
- 2. OAuth2:JWT授权授权和客户端凭证授权与JWT客户端认证有什么区别?
- 3. 弹簧安全oauth2客户端
- 4. WCF安全 - 客户端授权
- 5. 只有弹簧安全授权
- 6. 按日期弹簧安全授权
- 7. 未授权访问弹簧安全
- 8. 弹簧安全授权ifAllGranted文档
- 9. Swashbuckle OAuth2用户授权使用客户端凭证流
- 10. 使用数据库弹簧安全认证和授权
- 11. 弹簧安全分割验证和授权
- 12. 使用OAuth2进行弹簧安全性的用户授权
- 13. 客户端角色的Keycloak弹簧启动配置
- 14. x509弹簧客户端,错误证书
- 15. Apache,SSL客户端证书,LDAP授权
- 16. 弹簧安全不认证
- 17. 弹簧安全2.0弹簧安全3.0
- 18. 使用弹簧安全性修改基本授权授权流程?
- 19. 与HTTP客户端弹簧安置模板NTLM身份验证
- 20. box.com是否支持自主客户端或客户端凭据授权?
- 21. 的客户端SSL授权
- 22. Python SOAP客户端,授权
- 23. 授权给Google客户端
- 24. 设置客户端凭证
- 25. 弹簧安全oauth2授权服务器没有任何UI
- 26. 虽然角色正确提供了弹簧安全授权
- 27. 授权访问资源与弹簧安全和Angularjs
- 28. 在弹簧安全性/ Auth0授权中添加'ROLE'
- 29. 弹簧安全性带有令牌授权的基本身份验证
- 30. 弹簧安全