通配符的spring安全性映射

时间:2014-11-17 02:26:49

标签: spring-security spring-boot

使用 Spring-Boot 1.1.17,Spring-MVC Spring-Security:

我有几个子域,我想允许未经身份验证的用户(访问者)访问。例如:

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

如果尝试了无效的客户站点,那么我的控制器会抛出异常或重定向回/(mysite.com/)自然地,域的其他部分(mysite.com/customerA/myaccount)将需要登录。< / p>

我还没有真正弄清楚如何使用spring security和spring-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 "/";
}

当我尝试访问该网址时,出现以下错误:

 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 

我尝试添加此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;
}

但是,如果应用程序在启动时知道客户,而不是在客户注册时动态地知道客户,那么这似乎才有效。

有没有办法配置它来处理这些类型的通配符?

1 个答案:

答案 0 :(得分: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 "/";
  }
}

如果用户被正确认证,他应该访问officeName的URL。