I'm using Spring Security 4.0.3 with a custom login form and Spring MVC 4.1.1, running in Glassfish 4.1.
My custom login page is presented correctly when I ask for a secured URL (/app/**). However, when the login form is submitted (POST /j_security_check), this request results in a basic authentication dialog being displayed. It seems that something feels that /j_security_check is a resource which is protected by basic authentication at the Glassfish level, since I get a 401 Unauthorized page from Glassfish when I hit Cancel on the dialog.
Here is my MVC initializer:
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MvcConfiguration.class, SecurityConfiguration.class, PersistenceConfiguration.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "*.html", "/j_security_check" };
}
}
My MVC Config:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.elemenopy.wishlist"})
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/*
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages", "validationMessages");
return source;
}
@Bean
@Override
public Validator getValidator() {
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(messageSource());
return factory;
}
@Bean
public MessageSourceAccessor messageSourceAccessor() {
return new MessageSourceAccessor(messageSource());
}
}
My security config:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("[email protected]").password("abc123").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/static/**", "/*.jsp").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/home.html").permitAll()
.antMatchers("/start.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login.html").permitAll()
.and()
.logout().logoutUrl("/logout.html").permitAll();
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authManager() throws Exception {
return authenticationManagerBean();
}
}
Any help would be greatly appreciated. Thanks!