I am creating a Spring security configuration that will be used as a library by any developer who wants to create a Spring Stormpath application protected by Spring Security.
To do this, I subclassed WebSecurityConfigurerAdapter and defined Stormpath Access Controls in configure(HttpSecurity) , as well as Stormpath AuthenticationProvider using configure(AuthenticationManagerBuilder) . All of this can be seen in this abstract class and its specific subclass:
@Order(99) public abstract class AbstractStormpathWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
In short, we basically define our entry and exit mechanisms and integrate our CSRF code to play well with Spring Security.
Up to this point, everything is working fine.
But this is just a "library", and we want users to create their own applications on top of it.
So, we created the Sample application to demonstrate how the user will use our library.
Basically, users will want to create their own WebSecurityConfigurerAdapter . Like this:
@EnableStormpathWebSecurity @Configuration @ComponentScan @PropertySource("classpath:application.properties") @Order(1) public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated(); } }
If it is really necessary, WebApplicationInitializer as follows:
public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(SpringSecurityWebAppConfig.class); context.register(StormpathMethodSecurityConfiguration.class); sc.addListener(new ContextLoaderListener(context)); ServletRegistration.Dynamic dispatcher = sc.addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/");
All this code loads correctly. If I go to localhost:8080 , I will see a welcome screen. If I go to localhost:8080/login , I will see the login screen. But if I go to localhost:8080/restricted , I should be redirected to the login page, since we have this line: http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated(); . However, I see the Access Denied page.
Then, if I add the login URL to the application access control, for example:
protected void configure(HttpSecurity http) throws Exception { http .formLogin().loginPage("/login") .and() .authorizeRequests().antMatchers("/restricted").fullyAuthenticated(); }
Now it redirects me to the login page, but as soon as I submit the credentials, I get a CSRF problem meaning that our entire configuration is not really part of this filter chain.
When I debug all this, it seems that each WebApplicationInitializer has its own instance with its own filter chain. I would expect them to be somehow concatenated, but it seems like this is not really happening ...
Has anyone ever tried something like this?
BTW: As a workaround, users can do the public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfiguration instead of SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter . This way it works, but I want users to have a clean Spring security code, and extending from our StormpathWebSecurityConfiguration deviate from this goal.
All code can be seen here . Spring Stormpath security library for Spring is under extensions/spring/stormpath-spring-security-webmvc . A sample application using the library is under examples/spring-security-webmvc .
It is very easy to run ... You just need to register with the Stormpath as described here . Then you can check the spring_security_extension_redirect_to_login_not_working branch and run the sample application as follows:
$ git clone git@github.com :mrioan/stormpath-sdk-java.git $ git checkout spring_security_extension_redirect_to_login_not_working $ mvn install -DskipTests=true $ cd examples/spring-security-webmvc $ mvn jetty:run
Then you can go to localhost:8080/restricted to see that you are not redirected to the login page.
Any help is much appreciated!