2016-08-22 103 views
0

我正在使用Spring Boot和Spring Security创建一个简单的Web应用程序。我有一个自定义过滤器来检查x-auth-token是否存在并且有效。我有/src/main/resources/static文件夹下的静态内容。但是,指向静态内容的网址也会通过自定义过滤器并导致令牌验证失败。任何人都可以帮助解决我的配置错误吗?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从浏览器没有被服务。

编辑1 我在github中创建了一个示例项目来复制该问题。希望这有助于:

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

时,我打:

  1. http://localhost:8080http://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安全(禁用所有筛选器)。

只是改变:

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

到:

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

记住,你的应用程序映射/src/main/resources/static目录/ URL(有你的资源URL没有/static前缀)。

+0

添加permitAll()不允许我以不安全的方式访问静态内容。我已经编辑了更多的细节问题和一个链接到示例GitHub项目来复制这个问题。谢谢。 – Mithun

+0

请检查我编辑的答案 –

+0

感谢您的支持。有效 :) – Mithun

相关问题