I had the same problem (my custom auth provider didnβt hit) and solved the problem by entering springSecurityFilterChain , reading Why Spring Security works in Tomcat, but not when deploying to Weblogic? So my problem might have been with WebServer, but I had a problem with an answering machine on Tomcat and now my work on setting up Tomcat has been verified.
I am using Spring boot version 1.4.1 which contains Spring 4.3.3 and Spring Security 4.1.3 and after Traditional deployment
I tested my configuration against Tomcat v9.0 as well as WebLogic 12c R2 and checked if it works on both. hope this helps at least someone who uses Tomcat.
Below my configuration is launched from the main class.
Application.java
public class Application { public static void main( String[] args ) { SpringApplication.run(new Class[] {AppConfig.class, Initializer.class, SecurityInitializer.class}, args); } }
Initializer.java
public class Initializer extends SpringBootServletInitializer implements WebApplicationInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(AppConfig.class); } @Override public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class);
Here AbstractSecurityWebApplicationInitializer creates the SpringSecurityFilterChain from the onStartup method. I have not implemented anything since I am trying to use the default configuration.
SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { }
Appconfig.java
@Configuration @EnableAutoConfiguration @EnableScheduling @EnableMBeanExport @EnableAsync @EnableAspectJAutoProxy @ComponentScan("com.my.package") public class AppConfig { }
SecurityConfig.java
@Configuration @EnableWebSecurity @ComponentScan("com.my.package") public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private RestfulRemoteAuthenticationProvider restfulRemoteAuthenticationProvider; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(restfulRemoteAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); } }
Webconfig.java
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.my.controller.package") public class WebConfig extends WebMvcConfigurerAdapter { @Bean public InternalResourceViewResolver internalViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); viewResolver.setOrder(1); return viewResolver; } }
This is my custom auth provider for receiving authentication information from another component via Restful request
RestfulRemoteAuthenticationProvider.java
@Component public class RestfulRemoteAuthenticationProvider implements AuthenticationProvider { @Autowired private ManagementClientAdapterFactory managementClientAdapterFactory; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = authentication.getCredentials().toString(); // my logic to get and configure authSource which is my environment specific thing, also same for RemoteAuthRequestResult RemoteAuthRequestResult result = (RemoteAuthRequestResult)authSource.sendRequest(); if(result.isAuthenticated()) { List<GrantedAuthority> grantedAuths = new ArrayList<>(); grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); return new UsernamePasswordAuthenticationToken(username, password, grantedAuths); } throw new BadCredentialsException("User not found by given credential"); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }