Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring安全性:添加自定义筛选器时无法允许访问资源_Java_Spring Security_Servlet Filters - Fatal编程技术网

Java Spring安全性:添加自定义筛选器时无法允许访问资源

Java Spring安全性:添加自定义筛选器时无法允许访问资源,java,spring-security,servlet-filters,Java,Spring Security,Servlet Filters,我的spring security有以下配置 http // if I gonna comment adding filter it's gonna work as expected .addFilterBefore(tokenAuthenticationFilter, BasicAuthenticationFilter.class) .authorizeRequests() .antMatchers("/rest/_health"

我的spring security有以下配置

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);
    }
}
有什么建议吗?

在我的配置(扩展了WebSecurity配置适配器)中,我是这样做的:

        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*");
}

可能并不完美,但它可以工作。

在端点检查之前执行过滤器。在您的情况下,未成功的身份验证将中止筛选器链,并让访问点处理其余部分。因此,您根本不允许匿名访问。您需要将身份验证设置为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);

对我来说没有预期的效果,兄弟,事实上,除了登录和注销,我的配置几乎相同