Reputation: 715
We just went over to using Spring Boot and Spring Security for a new project that we have. The problem is, our company uses CXF with a custom implemented SAML authentication regime. Of course the custom implementation is rather old, so we are locked to CXF 2.7.*.
A while back, all worked fine since we only exposed SOAP web services and did not use Spring Security. The authenticator that we used in the old solution, uses some kind of JBossWebRealm thingy to authenticate through org.apache.catlina.connector.Request.
But now, we are going to expose REST services as well, using LDAP as an authentication provider. This works like a dream using Spring Security, but now, the security on SOAP services fails. It now tries to use Spring Security to authenticate using the SAML token as a password into AD.
Currently we have the default Servlet that Spring Boot creates. This one exposes the REST resources and a simple health check webpage. Then we have a servlet that exposes SOAP web services and one that exposes metrics (REST).
Servlet setup:
@Configuration
@EnableAutoConfiguration
@Import(ApplicationConfig.class)
public class ApplicationServletInitializer extends SpringBootServletInitializer {
@Bean
public WebMvcConfigurerAdapter dispatcherServletConfigurer(final MDCInterceptor mdcInterceptor) {
return new WebMvcConfigurerAdapter() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/internal/*");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(mdcInterceptor);
}
};
}
@Bean(name = "webServiceServlet")
public ServletRegistrationBean webServiceServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new CXFServlet());
servletRegistrationBean.setName("webServiceServlet");
servletRegistrationBean.addUrlMappings("/ws/*");
servletRegistrationBean.setLoadOnStartup(2);
return servletRegistrationBean;
}
@Bean(name = "metricsServlet")
public ServletRegistrationBean metricsServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new MetricsServlet());
servletRegistrationBean.setName("metricsServlet");
servletRegistrationBean.addUrlMappings("/internal/metrics/*");
servletRegistrationBean.setLoadOnStartup(3);
return servletRegistrationBean;
}
}
Security setup:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackageClasses = {
MDCInterceptor.class,
WebSecurityConfigurerAdapterConfig.class
})
public class RestSecurityConfig {
@Value("${ldap.url}")
private String ldapUrl;
@Value("${ldap.domain}")
private String ldapDomain;
@Bean
public ActiveDirectoryLdapAuthenticationProvider authenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
provider.setAuthoritiesMapper(authoritiesMapper());
provider.setUserDetailsContextMapper(userDetailsMapper());
provider.setUseAuthenticationRequestCredentials(true);
provider.setConvertSubErrorCodesToExceptions(true);
return provider;
}
@Bean
public MyAuthoritiesMapper authoritiesMapper() {
return new MyAuthoritiesMapper();
}
@Bean
public MyUserDetailsMapper userDetailsMapper() {
return new MyUserDetailsMapper();
}
}
@Component
public class WebSecurityConfigurerAdapterConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ActiveDirectoryLdapAuthenticationProvider authenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll()
.antMatchers("/api/**").hasRole("READ")
.and().httpBasic()
.and().anonymous()
.principal(anonymousPrincipal())
.authorities(anonymousRoles());
}
}
web.xml setup:
<security-constraint>
<web-resource-collection>
<web-resource-name>All pages</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
</security-constraint>
Does anyone know if it's possible to solve this? It's not an option to remove the usage of the old security framework that authenticates SAML for the SOAP web services.
Upvotes: 1
Views: 1391
Reputation: 715
Figured it out. When configuring Spring Security, in WebSecurityConfigurerAdapter, you can also override:
protected void configure(WebSecurity web).
Within this one, you can specify what to ignore. E.g.:
web.ignoring().antMatchers("/ws/**");
Upvotes: 3