2016-08-22 131 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

相關問題