HttpSecurity 配置不适用于 Spring 上的 Keycloak 适配器
HttpSecurity configuration does not work with Keycloak Adapter on Spring
完整代码:https://github.com/czetsuya/Spring-Keycloak-with-REST-API
我正在尝试在 Spring 中实现一个 REST API,由仅承载客户端的 Keycloak (4.8.1) 保护。
问题:configure(HttpSecurity http) 不受尊重,只要用户通过身份验证,REST 端点就可以访问。
例如 .antMatchers("/admin*").hasRole("ADMIN"),/admin 应该只能由具有 ADMIN 角色的用户访问,但我能够使用 USER 访问角色。
我还尝试在 application.yml 中设置安全约束(但没有帮助):
security-constraints:
- auth-roles:
- ADMIN
- security-collections:
- name: admin
- patterns:
- /admin*
将@EnableGlobalMethodSecurity 与@PreAuthorize("hasRole('ADMIN')") 结合使用可以解决问题,但真的没有其他办法吗?
这是 application.xml。
keycloak:
enabled: true
realm: dev
auth-server-url: http://localhost:8083/auth
ssl-required: external
resource: dev-api
bearer-only: true
confidential-port: 0
use-resource-role-mappings: false
principal-attribute: preferred_username
这里是pom的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
.....
和 SecurityConfig 的一部分 class:
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
simpleAuthorityMapper.setConvertToUpperCase(true);
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(simpleAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
/**
* Secure appropriate endpoints
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests() //
.antMatchers("/users*").hasRole("USER") //
.antMatchers("/admin*").hasRole("ADMIN") //
.anyRequest().authenticated() //
.and().csrf().disable() //
;
}
启用详细日志后。我发现正在应用 application.yml 中定义的安全约束,而不是 java class 中定义的约束。
现在的问题是如何使用 java 约束而不是定义的 application.yml。
问题是 yml 配置错误。这是正确的版本:
security-constraints:
- auth-roles:
- User
security-collections:
- name: unsecured
patterns:
- /users
- auth-roles:
- Admin
security-collections:
- name: secured
patterns:
- /admin
请注意,当定义了 KeycloakSpringBootConfigResolver 时,configure(httpSecurity) 也会被调用。
在 application.yml 中启用下面的日志将向我们显示安全约束检查:
logging:
level:
org.apache.catalina: DEBUG
这里有更详细的解释和代码:http://czetsuya-tech.blogspot.com/2018/12/secure-spring-boot-rest-project-with.html
完整代码:https://github.com/czetsuya/Spring-Keycloak-with-REST-API
我正在尝试在 Spring 中实现一个 REST API,由仅承载客户端的 Keycloak (4.8.1) 保护。
问题:configure(HttpSecurity http) 不受尊重,只要用户通过身份验证,REST 端点就可以访问。
例如 .antMatchers("/admin*").hasRole("ADMIN"),/admin 应该只能由具有 ADMIN 角色的用户访问,但我能够使用 USER 访问角色。
我还尝试在 application.yml 中设置安全约束(但没有帮助):
security-constraints:
- auth-roles:
- ADMIN
- security-collections:
- name: admin
- patterns:
- /admin*
将@EnableGlobalMethodSecurity 与@PreAuthorize("hasRole('ADMIN')") 结合使用可以解决问题,但真的没有其他办法吗?
这是 application.xml。
keycloak:
enabled: true
realm: dev
auth-server-url: http://localhost:8083/auth
ssl-required: external
resource: dev-api
bearer-only: true
confidential-port: 0
use-resource-role-mappings: false
principal-attribute: preferred_username
这里是pom的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
.....
和 SecurityConfig 的一部分 class:
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
simpleAuthorityMapper.setConvertToUpperCase(true);
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(simpleAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate() {
return new KeycloakRestTemplate(keycloakClientRequestFactory);
}
/**
* Secure appropriate endpoints
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests() //
.antMatchers("/users*").hasRole("USER") //
.antMatchers("/admin*").hasRole("ADMIN") //
.anyRequest().authenticated() //
.and().csrf().disable() //
;
}
启用详细日志后。我发现正在应用 application.yml 中定义的安全约束,而不是 java class 中定义的约束。
现在的问题是如何使用 java 约束而不是定义的 application.yml。
问题是 yml 配置错误。这是正确的版本:
security-constraints:
- auth-roles:
- User
security-collections:
- name: unsecured
patterns:
- /users
- auth-roles:
- Admin
security-collections:
- name: secured
patterns:
- /admin
请注意,当定义了 KeycloakSpringBootConfigResolver 时,configure(httpSecurity) 也会被调用。
在 application.yml 中启用下面的日志将向我们显示安全约束检查:
logging:
level:
org.apache.catalina: DEBUG
这里有更详细的解释和代码:http://czetsuya-tech.blogspot.com/2018/12/secure-spring-boot-rest-project-with.html