gub*_*bak 6 security spring-boot keycloak
我的Spring Boot Web应用程序有一个非常特殊的要求:我有内部和外部用户。内部用户使用keycloak身份验证登录到Web应用程序(他们可以在Web应用程序中工作),但是我们的外部用户通过简单的Spring Boot身份验证登录(他们可以做的只是下载Web应用程序生成的一些文件)
我想做的是拥有多种身份验证模型:/ download / *以外的所有路径都将通过我们的Keycloak身份验证来进行身份验证,而/ download / *路径将通过SpringBoot基本身份验证来进行身份验证。
目前,我有以下内容:
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@Order(1)
public static class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.regexMatcher("^(?!.*/download/export/test)")
.authorizeRequests()
.anyRequest().hasAnyRole("ADMIN", "SUPER_ADMIN")
.and()
.logout().logoutSuccessUrl("/bye");
}
}
@Configuration
@Order(2)
public static class DownloadableExportFilesSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/download/export/test")
.authorizeRequests()
.anyRequest().hasRole("USER1")
.and()
.httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password1").roles("USER1");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这并不能很好地起作用,因为每次外部用户要下载某些内容(/ download / export / test)时,它都会提示登录表单,但是在输入正确的外部用户用户名和密码后,它会提示keycloak身份验证登录形成。
我没有得到任何错误,只是一个警告:
2016-06-20 16:31:28.771 WARN 6872 --- [nio-8087-exec-6] o.k.a.s.token.SpringSecurityTokenStore : Expected a KeycloakAuthenticationToken, but found org.springframework.security.authentication.UsernamePasswordAuthenticationToken@3fb541cc: Principal: org.springframework.security.core.userdetails.User@36ebcb: Username: user; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER1; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: 4C1BD3EA1FD7F50477548DEC4B5B5162; Granted Authorities: ROLE_USER1
Run Code Online (Sandbox Code Playgroud)
你有什么想法?
在 Keycloak 身份验证旁边实现基本身份验证时,我遇到了一些麻烦,因为在“按书”执行多个 WebSecurityAdapter 实现时,即使基本身份验证成功,也会调用 Keycloak 身份验证过滤器。
原因就在这里:http : //www.keycloak.org/docs/latest/securing_apps/index.html#avoid-double-filter-bean-registration
因此,如果您将 Keycloak Spring Security Adapter 与 Spring Boot 一起使用,请确保添加这两个 bean(除了 Jacob von Lingen 的有效答案):
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Configuration
@Order(1) //Order is 1 -> First the special case
public static class DownloadableExportFilesSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.antMatcher("/download/export/test")
.authorizeRequests()
.anyRequest().hasRole("USER1")
.and()
.httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password1").roles("USER1");
}
}
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
//no Order, will be configured last => All other urls should go through the keycloak adapter
public static class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
// necessary due to http://www.keycloak.org/docs/latest/securing_apps/index.html#avoid-double-filter-bean-registration
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
// necessary due to http://www.keycloak.org/docs/latest/securing_apps/index.html#avoid-double-filter-bean-registration
@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().hasAnyRole("ADMIN", "SUPER_ADMIN")
.and()
.logout().logoutSuccessUrl("/bye");
}
}
}
Run Code Online (Sandbox Code Playgroud)
多个 HttpSecurity 的关键是在正常情况之前注册“特殊情况”。换句话说,/download/export/test身份验证适配器应该在 keycloak 适配器之前注册。
另一件需要注意的重要事情是,一旦身份验证成功,就不会调用其他适配器(因此.regexMatcher("^(?!.*/download/export/test)")没有必要)。可以在此处找到有关多 HttpSecurity 的更多信息。
下面的代码进行了最小的更改:
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Configuration
@Order(1) //Order is 1 -> First the special case
public static class DownloadableExportFilesSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/download/export/test")
.authorizeRequests()
.anyRequest().hasRole("USER1")
.and()
.httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password1").roles("USER1");
}
}
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@Order(2) //Order is 2 -> All other urls should go through the keycloak adapter
public static class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
//removed .regexMatcher("^(?!.*/download/export/test)")
.authorizeRequests()
.anyRequest().hasAnyRole("ADMIN", "SUPER_ADMIN")
.and()
.logout().logoutSuccessUrl("/bye");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1952 次 |
| 最近记录: |