2016-08-22 4 views
0

Я создаю простое веб-приложение с использованием Spring Boot и Spring Security. У меня есть настраиваемый фильтр, чтобы проверить наличие и действительность x-auth-token. У меня есть статический контент под папкой /src/main/resources/static. Но URL-адрес, указывающий на статический контент, также проходит через настраиваемый фильтр и не позволяет проверить маркер. Может ли кто-нибудь помочь в выяснении ошибки с моей конфигурацией?Spring Boot & Spring Security не обслуживает содержимое из/статической папки

@Configuration 
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private StatelessAuthenticationFilter statelessAuthenticationFilter; 

    @Autowired 
    private UserDetailsService userDetailsService; 

    public SpringSecurityConfig() { 
     super(true); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() 
      .anyRequest().authenticated().and() 

      // Custom Token based authentication based on the header 
      .addFilterBefore(statelessAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService()); 
    } 

    @Override 
    public UserDetailsService userDetailsService() { 
     return userDetailsService; 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/auth"); 
    } 

    @Bean 
    public FilterRegistrationBean filterRegistrationBean() { 
     FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 
     filterRegistrationBean.setEnabled(false); 
     filterRegistrationBean.setFilter(statelessAuthenticationFilter); 
     return filterRegistrationBean; 
    } 
} 

Пользовательский фильтр:

@Component 
public class StatelessAuthenticationFilter extends GenericFilterBean { 

    @Value("${security.token.secret:asdfasdfasdf}") 
    private String tokenSecret; 

    @Autowired 
    private UserRepository userRepository; 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
          throws IOException, ServletException { 
     System.out.println("stateless authentication filter"); 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 

     try { 

      String token = httpRequest.getHeader(Constants.X_AUTH_TOKEN_HEADER_NAME); 
      if(!StringUtils.hasText(token)) { 
       throw new AuthenticationException(AirlineError.AUTHENTICATION_AUTH_TOKEN_MISSING); 
      } 

      JWTPayload jwtPayload = new JWTPayload(); 
      byte[] secret = tokenSecret.getBytes(); 
      DefaultJwtParser defaultJwtParser = new DefaultJwtParser(); 
      defaultJwtParser.setSigningKey(secret); 

      Claims claims = defaultJwtParser.parseClaimsJws(token).getBody(); 
      jwtPayload.setEmail((String) claims.get("email")); 
      jwtPayload.setExp((Long) claims.get("exp")); 

      if (new DateTime(jwtPayload.getExp()).isBeforeNow()) { 
       throw new AuthenticationException(AirlineError.AUTHENTICATION_AUTH_TOKEN_EXPIRED); 
      } 

      User user = userRepository.findOne(jwtPayload.getEmail()); 
      SecurityContextHolder.getContext().setAuthentication(new UserAuthentication(user.getEmail())); 
      chain.doFilter(request, response); 
     } catch(Exception e) { 
      httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     } 
    } 

} 

index.html находится в /src/main/resources/static папке, но оно не подается, когда я открываю http://localhost:8080 из браузера.

EDIT 1 Я создал образец проекта в github, чтобы воспроизвести проблему. Надеюсь, что это помогает:

https://github.com/mgooty/spring-boot-security

, когда я ударил:

  1. http://localhost:8080 или http://localhost:8080/index.html я An Authentication object was not found in the SecurityContext
  2. http://localhost:8080/static/index.html Я получаю 404 ошибку
+0

Вы хотите, чтобы весь статический контент был защищен? –

ответ

0

Если вы хотите разрешить любой доступ на ваш статический контент, а затем просто настройте его в своей конфигурации безопасности:

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() 
      .antMatchers("/index.html").permitAll() 
      .anyRequest().authenticated().and() 

      // Custom Token based authentication based on the header 
      .addFilterBefore(statelessAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); 
    } 

Однако, это не будет работать в вашем случае из-за ошибок в пользовательских фильтрах безопасности. Но вы все равно можете отключить всю веб-безопасность (отключить все финтеры) для файла index.html или других статических ресурсов.

Просто изменение:

web.ignoring().antMatchers("/auth"); 

к:

web.ignoring().antMatchers("/auth", "/index.html"); 

Помните, что ваше приложение отображает /src/main/resources/static каталога для / URL (нет /static префикса в вашем URL-адресах ресурсов).

+0

Добавление allowAll() не позволило мне получить доступ к статическому содержимому в незащищенном виде. Я отредактировал вопрос с более подробной информацией и ссылку на образец проекта GitHub, чтобы воспроизвести проблему. Спасибо. – Mithun

+0

Пожалуйста, уточните мой отредактированный ответ –

+0

Благодарим вас за поддержку. Это сработало :) – Mithun

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