A Spring Bean methods in an application I'm working on are being called in two ways:
through AngularJS and
Spring MVC controller(Form login) or by using SOAP(Basic Authentication).
To allow this I have setup the following configuration for the CXF servlet:
@Configuration
public class CxfConfiguration {
@Autowired
private ApplicationContext applicationContext;
@Bean
public ServletRegistrationBean dispatcherServletSOAP() {
return new ServletRegistrationBean(new CXFServlet(), "/soap/*");
}
@Bean(name= Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint documentEndpoint(){
Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID);
DocumentService implementor = new DocumentServiceImpl();
EndpointImpl endpoint = new EndpointImpl(bus, implementor);
endpoint.publish("/document");
return endpoint;
}
and security configuration:
@Configuration
@Order(1)
public static class SOAPSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.antMatcher("/soap/**")
.authorizeRequests()
.anyRequest()
.hasRole("USER");
}
}
@Configuration
@Order(2)
public static class HTTPSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/soap/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
I realize that this isn't a very good configuration as there are several cases in which from the browser or SOAP UI, things don't work as expected.
My questions would be: what would be a good way to implement security based on these requirements and am I on the right track with this configuration?
Also, I'm using Spring Boot 1.3.2 and Apache CXF 3.1.4
I finally ended up with this configuration that works:
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Configuration
@Order(1)
public static class SOAPWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().ignoringAntMatchers("/soap/**")
.and()
.antMatcher("/soap/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().requestCache().disable();
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
}
You should try this, may be it will help you:
@Configuration
@EnableWebSecurity
@Profile("container")
public class SOAPSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider authenticationProvider;
@Autowired
private AuthenticationProvider authenticationProviderDB;
@Override
@Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Order(2)
protected void ConfigureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/rest/**").authenticated()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
//To change body of generated methods,
response.setStatus(HttpServletResponse.SC_OK);
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ae) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
})
.loginProcessingUrl("/access/login")
.and()
.logout()
.logoutUrl("/access/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
})
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.csrf()//Disabled CSRF protection
.disable();
}
}