我想实现一个简单的Spring Boot客户端应用程序。哪个应该访问OAauth2安全服务。某种代理。这种“代理服务”应该不受保护。
我想使用KeycloakRestTemplate
进行远程REST调用。
按照文档:http://www.keycloak.org/docs/latest/securing_apps/index.html#_spring_boot_adapter
到目前为止,我包含了以下依赖项:
dependencyManagement {
imports {
mavenBom "org.keycloak.bom:keycloak-adapter-bom:3.4.0-FINAL"
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.keycloak:keycloak-spring-boot-starter')
compile('org.keycloak:keycloak-spring-security-adapter')
}
我添加了一个Config类:
@KeycloakConfiguration
public class KeycloakWebSecurityContextConfig extends
KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
/**
* Defines the session authentication strategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.anyRequest().permitAll();
}
}
并制作了服务组件:
@Autowired
private KeycloakRestTemplate template;
@Value("${person-service.url}")
private String endpoint;
@RequestMapping(value = "/person", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Collection<Person> getPerson(){
ResponseEntity<Person[]> entity = template.getForEntity(endpoint, Person[].class);
return Arrays.asList(entity.getBody());
}
BTW:“人员服务”是安全的远程服务。
调用getPerson方法会给我:
java.lang.IllegalStateException: Cannot set authorization header because Authentication is of type class org.springframework.security.authentication.AnonymousAuthenticationToken but class org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken is required
at org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory.getKeycloakSecurityContext(KeycloakClientRequestFactory.java:75) ~[keycloak-spring-security-adapter-3.4.0.Final.jar:3.4.0.Final]
我认为Spring-security会阻碍并在KeycloakAdapter有机会创建自己的SecurityContext之前创建一个AnonymousAuthenticationToken。
那么如何正确启动和使用KeycloakRestTemplate?
答案 0 :(得分:0)
问题可能是您(您的客户端)未对Keycloak进行身份验证,因此缺少Keycloak令牌。
如果您未登录Keycloak,则应使用Spring中的简单Rest模板,而不是Keycloak Rest Template。
import org.springframework.web.client.RestTemplate
...
RestTemplate rt = new RestTemplate();
rt.postForObject(uri, data ,String.class);
答案 1 :(得分:0)
当登录用户最初调用微服务时,KeycloakRestTemplate可以工作,然后您可以从那里调用其他受保护的微服务。
如果您希望微服务向另一个受保护的微服务发起呼叫,那么最好使用OAuth2RestTemplate。
下面的RestTemplate将使用Keycloak服务帐户自动登录到keycloak,并在必要时续订承载令牌:
$('#divAddDocument').on('change', 'input[id*="addDocCheckbox_"]', function(e) {
var _index = this.id.split('_')[1];
_docUpload.DmsDocumentsList[_index].IsGridItemSelected = true;
if (_docUpload.IsCorrespondence) {
$('input[id*="addDocCheckbox_"]').each(function() {
if (checkboxId != this.id) {
this.disabled = true;
this.checked = false;
var _counter = this.id.split('_')[1];
_docUpload.DmsDocumentsList[_counter].IsGridItemSelected = false;
}
});
}
});