title: spring security mapping for wildcards
body: <p>Using <strong>Spring-Boot 1.1.17, Spring-MVC</strong> with <strong>Spring-Security:</strong></p>
  
  <p>I have several subdomains that I want to to allow unauthenticated users (Visitors) access to.  For example:</p>
  
  <ul>
  <li>mysite.com/customerA</li>
  <li>mysite.com/customerB</li>
  </ul>
  
  <p>If a invalid customer site is attempted, then my controller would either throw an exception or redirect back to /  (mysite.com/)  Naturally other parts of the domain (mysite.com/customerA/myaccount) will require login.</p>
  
  <p>I haven't really figured out how to do this with spring security and spring-mvc.  Here is what I am attempting so far:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Configuration
  @EnableWebMvcSecurity
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private CustomUserDetailsService customUserDetailsService;
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
                  .addFilterAfter(new CSRFTokenGeneratorFilter(), CsrfFilter.class)
                  .authorizeRequests()
                  .antMatchers("/").permitAll()
                  .antMatchers( "/**/" ).permitAll()
                  .antMatchers("/login").permitAll()
                  .antMatchers("/wizard").permitAll()
                  .antMatchers("/menu").permitAll()
                  .antMatchers("/error").permitAll()
                  .antMatchers("/resources/**").permitAll()
                  .antMatchers("/css/**").permitAll()
                  .antMatchers("/js/**").permitAll()
                  .antMatchers("/fonts/**").permitAll()
                  .antMatchers("/libs/**").permitAll();
  
          http
                  .formLogin()
                  .loginPage("/loginPage")
                  .permitAll()
                  .loginProcessingUrl("/login")
                  .failureUrl("/login?error")
                  .defaultSuccessUrl("/?tab=success")
                  .and()
                  .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
                  .permitAll()
                  .and()
                  .csrf();
  
          http
                  .sessionManagement()
                  .maximumSessions(1)
                  .expiredUrl("/login?expired")
                  .maxSessionsPreventsLogin(true)
                  .and()
                  .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                  .invalidSessionUrl("/");
  
          http
                  .authorizeRequests().anyRequest().authenticated();
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          PasswordEncoder encoder = new BCryptPasswordEncoder();
          auth.userDetailsService( customUserDetailsService ).passwordEncoder( encoder );
      }
  
      @Override
      public void configure(WebSecurity security){
          security.ignoring().antMatchers("/css/**","/fonts/**","/libs/**");
      }
  }
  </code></pre>
  
  <p>And my homepage controller:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Controller
  @RequestMapping("/{officeName}/")
  public class HomeController {
  private AuthenticatedUser getVisitor(@PathVariable String officeName) {
  
  .. do something with the office if found, redirect otherwise
           if (!StringUtils.isEmpty(officeName)) {
              Office office = officeService.findByName( officeName );
              return office.getUrl();
  
          }
          return "/";
  }
  </code></pre>
  
  <p>When I try to access that url, I get the following errors:</p>
  
  <pre><code> o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/customerA/]
   s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /customerA/
   s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/customerA/]
   o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/customerA/] are [/**]
   o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/customerA/] are {}
   o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/customerA/] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.ResourceHttpRequestHandler@2f295527] and 1 interceptor
   o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/customerA/] is: -1
   o.s.w.s.r.ResourceHttpRequestHandler     : Trying relative path [customerA] against base location: ServletContext resource [/]
   o.s.w.s.r.ResourceHttpRequestHandler     : Trying relative path [customerA] against base location: class path resource [META-INF/resources/]
   o.s.w.s.r.ResourceHttpRequestHandler     : Trying relative path [customerA] against base location: class path resource [resources/]
   o.s.w.s.r.ResourceHttpRequestHandler     : Trying relative path [customerA] against base location: class path resource [static/]
   o.s.w.s.r.ResourceHttpRequestHandler     : Trying relative path [customerA] against base location: class path resource [public/]
   o.s.w.s.r.ResourceHttpRequestHandler     : No matching resource found - returning 404 
  </code></pre>
  
  <p>I tried adding this ServletRegistrationBean:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Bean
  public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) {
      ServletRegistrationBean registration = new ServletRegistrationBean( dispatcherServlet );
  
      registration.addUrlMappings("/", "/testCustomer/*"  );
  
      for ( Office office : officeService.findAllActiveOffices() ) {
          registration.addUrlMappings( office.getUrl() + "/*" );
      }
      return registration;
  }
  </code></pre>
  
  <p>But this would seem to only work if the application knows of the customer at startup, not dynamically in the case of customer signup.</p>
  
  <p>Is there a way to configure this to handle these types of wildcards? </p>