Spring Boot& Spring Security不提供/ static文件夹中的内容

时间:2016-08-22 18:02:13

标签: spring spring-security spring-boot

我正在使用Spring Boot和Spring Security创建一个简单的Web应用程序。我有一个自定义过滤器来检查x-auth-token是否存在且有效。我在/src/main/resources/static文件夹下有静态内容。但是,指向静态内容的URL也会通过自定义筛选器并且无法通过令牌验证。任何人都可以通过我的配置帮助搞清楚错误吗?

@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错误

1 个答案:

答案 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目录映射到/个网址(资源网址中没有/static前缀)。