2014-11-17 2 views
0

Использование Spring-Boot 1.1.17, Spring MVC- с Спринг-Security:весной отображение безопасности для групповых символов

У меня есть несколько субдоменов, которые я хочу, чтобы позволить непроверенным пользователям (посетители) доступ. Например:

  • mysite.com/customerA
  • mysite.com/customerB

Если недействительный сайт клиент пытался, то мой контроллер будет либо выбросить исключение или перенаправление на/(mysite.com/) Естественно, что другие части домена (mysite.com/customerA/myaccount) потребуют входа в систему.

Я действительно не понял, как это сделать с весной безопасности и весной-mvc. Вот что я пытаюсь до сих пор:

@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/**"); 
    } 
} 

И на моей домашней странице контроллера:

@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 "/"; 
} 

Когда я пытаюсь получить доступ к этому URL, я получаю следующие ошибки:

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.[email protected]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 

I попробовал добавить этот ServletRegistrationBean:

@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; 
} 

Но это, похоже, работает только в том случае, если приложение знает о клиенте при запуске, а не динамически в случае регистрации клиента.

Есть ли способ настроить это для обработки этих типов подстановочных знаков?

+0

Это частный метод с привязкой '@ PathVariable' (вероятно, не будет работать с Spring MVC)? –

+0

@Dave - oops, спасибо за улов. К сожалению, это действительно не повлияло на мою проблему. Подход ServletRegistrationBean, казалось бы, стал началом, есть ли в любом случае динамическое обновление ServletRegistrationBean во время выполнения (т. Е. Новый клиент подписывается)? – sonoerin

+1

Я действительно не понимаю случай использования, если вам нужно это сделать. Spring MVC может динамически сопоставлять пути (как вы пытаетесь сделать с '@ PathVariable'), поэтому вам действительно нужно использовать эту функцию. –

ответ

1

Вы можете попробовать с конфигурацией, как следующее:

@Configuration 
@EnableWebMvcSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService _userService; 

    @Autowired 
    private PasswordEncoder _passwordEncoder; 

    /** 
    * Defines the password encoder used by Spring security during the 
    * authentication procedure. 
    */ 
    @Bean 
    public PasswordEncoder passwordEncoder() { 
    // default strength = 10 
    return new BCryptPasswordEncoder(); 
    } 

    /** 
    * Sets security configurations for the authentication manager 
    */ 
    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) 
     throws Exception { 
    auth 
     .userDetailsService(_userService) 
     .passwordEncoder(_passwordEncoder); 
    return; 
    } 

    /** 
    * Configures where Spring Security will be disabled (security = none). 
    * From spring reference: "Typically the requests that are registered [here] 
    * should be that of only static resources. For requests that are dynamic, 
    * consider mapping the request to allow all users instead." 
    */ 
    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring() 
     .antMatchers(
      "/css/**", 
      "/js/**", 
      "/fonts/**", 
      "/resources/**", 
      "/libs/**"); 
     return; 
    } 

    /** 
    * Sets security configurations in the HttpSecurity object. 
    */ 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

    // Set security configurations 
    http 
     .authorizeRequests() 
     // the following urls are allowed for any user (no authentication) 
     .antMatchers(
      "/", 
      "/login", 
      "/menu") 
      .permitAll() 
     // any other url must be authenticated 
     .anyRequest().authenticated() 
     .and() 
     // define the login page url 
     .formLogin() 
     .loginPage("/login") 
     .permitAll() 
     .and() 
     // define the logout url 
     .logout() 
     .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
     .logoutSuccessUrl("/login?logout") 
     .permitAll(); 

    return; 
    } // method configure 

} // class WebSecurityConfig 

Добавление ваших личных конфигураций ... Вы можете попробовать добавить следующий контроллер:

@Controller 
public class HomeController { 

    @RequestMapping("/{officeName}/") 
    public 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 "/"; 
    } 
} 

Если пользователь правильно аутентифицированы он должен получить доступ к URL-адресу в officeName.

+0

Спасибо, Андреа, что, конечно, очищает мою конфигурацию. Однако для этого все еще требуется аутентификация пользователя на странице входа. Я вижу, что HomeController вызывается после попытки входа в систему, но я надеялся, что смогу настроить его таким образом, чтобы URL-адрес был доступен для всех пользователей с чем-то вроде: **. AntMatchers («/», «/ login», «/ wizard ","/menu ","/error "," /{officeName}/").permitAll();** – sonoerin

+0

Попробуйте использовать antMatchers, такие как '.antMatchers ("/","/*/"). allowAll () .anyRequest(). authenticated(); 'разрешить любой URL-адрес, например"/{officeName}/". В вашем контроллере вы можете проверить, не выполнено ли недопустимое имя officeName, а затем перенаправить пользователя. Любой URL-адрес, например «mysite.com/customerA/myaccount/», должен быть аутентифицирован. – Andrea

+0

Спасибо, что сделал именно то, что мне было нужно. Я обновляю свой вопрос с готовым кодом. Это редкий случай использования, по мнению Дэйва, но, возможно, кто-то найдет его полезным когда-нибудь. – sonoerin

Смежные вопросы