title: Multiple WebSecurityConfigurerAdapter: one as a library, in the other users can add their own security access
body: <p>I am creating a Spring Security configuration to be used as a library by any developer who wants to create a Stormpath Spring application secured by Spring Security.</p>
  
  <p>For that I have sub-classed <code>WebSecurityConfigurerAdapter</code> and defined the Stormpath Access Controls in <code>configure(HttpSecurity)</code> as well as the Stormpath <code>AuthenticationProvider</code> by means of <code>configure(AuthenticationManagerBuilder)</code>. All this can be seen in this abstract class and its concrete sub-class:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Order(99)
  public abstract class AbstractStormpathWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      //Removed properties and beans for the sake of keeping focus on the important stuff
  
      /**
       * The pre-defined Stormpath access control settings are defined here.
       *
       * @param http the {@link HttpSecurity} to be modified
       * @throws Exception if an error occurs
       */
      protected void configure(HttpSecurity http, AuthenticationSuccessHandler successHandler, LogoutHandler logoutHandler)
              throws Exception {
  
          if (loginEnabled) {
              http
                      .formLogin()
                      .loginPage(loginUri)
                      .defaultSuccessUrl(loginNextUri)
                      .successHandler(successHandler)
                      .usernameParameter("login")
                      .passwordParameter("password");
          }
  
          if (logoutEnabled) {
              http
                      .logout()
                      .invalidateHttpSession(true)
                      .logoutUrl(logoutUri)
                      .logoutSuccessUrl(logoutNextUri)
                      .addLogoutHandler(logoutHandler);
  
          }
  
          if (!csrfProtectionEnabled) {
              http.csrf().disable();
          } else {
              //Let's configure HttpSessionCsrfTokenRepository to play nicely with our Controllers' forms
              http.csrf().csrfTokenRepository(stormpathCsrfTokenRepository());
          }
      }
  
      /**
       * Method to specify the {@link AuthenticationProvider} that Spring Security will use when processing authentications.
       *
       * @param auth the {@link AuthenticationManagerBuilder} to use
       * @param authenticationProvider the {@link AuthenticationProvider} to whom Spring Security will delegate authentication attempts
       * @throws Exception if an error occurs
       */
      protected void configure(AuthenticationManagerBuilder auth, AuthenticationProvider authenticationProvider) throws Exception {
          auth.authenticationProvider(authenticationProvider);
      }
  }
  
  @Configuration
  public class StormpathWebSecurityConfiguration extends AbstractStormpathWebSecurityConfiguration {
  
      //Removed beans for the sake of keeping focus on the important stuff
  
      @Override
      protected final void configure(HttpSecurity http) throws Exception {
          configure(http, stormpathAuthenticationSuccessHandler(), stormpathLogoutHandler());
      }
  
      @Override
      protected final void configure(AuthenticationManagerBuilder auth) throws Exception {
          configure(auth, super.stormpathAuthenticationProvider);
      }
  }
  </code></pre>
  
  <p>In short, we are basically defining our login and logout mechanisms and integrating our CSRF code to play nicely with Spring Security's one.</p>
  
  <p>Up to this point everything works OK.</p>
  
  <p>But this is just the "library" and we want users to build their own applications on top of it. </p>
  
  <p>So, we have created a Sample application to demonstrate how a user will use our library. </p>
  
  <p>Basically users will want to create their own <code>WebSecurityConfigurerAdapter</code>. Like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>@EnableStormpathWebSecurity
  @Configuration
  @ComponentScan
  @PropertySource("classpath:application.properties")
  @Order(1)
  public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {
  
      /**
       * {@inheritDoc}
       */
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
      }
  
  }
  </code></pre>
  
  <p>In case this is actually needed, the <code>WebApplicationInitializer</code> looks like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>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("/");
  
          //Stormpath Filter
          FilterRegistration.Dynamic filter = sc.addFilter("stormpathFilter", new DelegatingFilterProxy());
          EnumSet&lt;DispatcherType&gt; types =
                  EnumSet.of(DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
          filter.addMappingForUrlPatterns(types, false, "/*");
  
          //Spring Security Filter
          FilterRegistration.Dynamic securityFilter = sc.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
          securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
      }
  }
  </code></pre>
  
  <p>All this code boots up correctly. If I go to <code>localhost:8080</code> I see the welcome screen. If I go to <code>localhost:8080/login</code> I see the login screen. But, if I go to <code>localhost:8080/restricted</code> I should be redirected to the login page since we have this line: <code>http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();</code>. However I am seeing the <code>Access Denied</code> page instead.</p>
  
  <p>Then, if I add the login url in the App's access control, like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>protected void configure(HttpSecurity http) throws Exception {
      http
              .formLogin().loginPage("/login")
              .and()
              .authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
  }
  </code></pre>
  
  <p>It now redirects me to the login page but as soon as I submit the credentials I get an CSRF problem meaning that all our configuration is not actually part of this filter chain.</p>
  
  <p>When I debug it all it seems that each <code>WebApplicationInitializer</code> is having its own instance with its own Filter Chain. I would expect them to be concatenated somehow but it seems that it is not actually happening...</p>
  
  <p>Anyone has ever tried something like this?</p>
  
  <p>BTW: As a workaround users can do <code>public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfiguration</code> instead of <code>SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter</code>. This way it works but I want users to have pure Spring Security code and extending from our <code>StormpathWebSecurityConfiguration</code> diverges from that goal.</p>
  
  <p>All the code can be seen <a href="https://github.com/mrioan/stormpath-sdk-java/tree/spring_security_extension_redirect_to_login_not_working" rel="noreferrer">here</a>. The Stormpath Spring Security library for Spring is under <code>extensions/spring/stormpath-spring-security-webmvc</code>. The Sample App using the library is under <code>examples/spring-security-webmvc</code>.</p>
  
  <p>It is very simple to run... You just need to register to Stormpath <a href="http://docs.stormpath.com/rest/quickstart/#get-an-api-key" rel="noreferrer">as explained here</a>. Then you can checkout the <code>spring_security_extension_redirect_to_login_not_working</code> branch and start the sample app like this:</p>
  
  <pre><code>$ 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
  </code></pre>
  
  <p>Then you can go to <code>localhost:8080/restricted</code> to see that you are not being redirected to the login page.</p>
  
  <p>Any help is very much appreciated!</p>