Spring安全性:添加定制过滤器时,不允许访问资源

时间:2018-09-05 10:36:35

标签: java spring-security servlet-filters

我的弹簧安全性具有以下配置

http
    // if I gonna comment adding filter it's gonna work as expected
    .addFilterBefore(tokenAuthenticationFilter, BasicAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/rest/_health")
            .permitAll()

            .anyRequest()
            .authenticated()

            .and()
            .csrf()
            .disable();

因此,如果没有自定义过滤器,一切都会按预期工作-我可以访问/ rest / _health,但不能访问其他所有内容。

但是,当我添加此过滤器时-匹配器不起作用,即使对'permitAll'资源也无法使用过滤器。

我的过滤器中的代码如下:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    try {
        String token = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);

        Authentication authentication = authenticationManager.authenticate(
                new TokenBasedAuthentication(token)
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);

        chain.doFilter(request, response);
    } catch (AuthenticationException ex) {
        authenticationEntryPoint.commence(httpRequest, httpResponse, ex);
    }
}

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

在我的配置(扩展了WebSecurityConfigurerAdapter)中,我是通过以下方式完成的:

        http.csrf().disable().
            addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/login*", "/logout*").permitAll().anyRequest()
            .authenticated()
        .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/secured/index")
                .failureUrl("/login?error=true").permitAll()
        .and()
            .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .deleteCookies("JSESSIONID")
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll();

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/**", "/webjars/**", "/error*");
}

也许并不完美,但是可以。

答案 1 :(得分:0)

在对端点进行检查之前执行过滤器。在您的情况下,不成功的身份验证将中止筛选器链,并让访问点处理其余部分。您根本不允许匿名访问。您需要将Authentication设置为null,以指示匿名用户正在访问端点。

尝试以下操作:

    Authentication authentication = null;
    String token = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);
    //check if not anonymous and preceed with authentication
    if (token != null && !token.isEmpty()) {
        try {

            authentication = authenticationManager.authenticate(
                new TokenBasedAuthentication(token));

        } catch (AuthenticationException ex) {
            //illigal access atempt
            authenticationEntryPoint.commence(httpRequest, httpResponse, ex);
        }
    }
    SecurityContextHolder.getContext().setAuthentication(authentication);
    chain.doFilter(request, response);