spring-security 如何在过滤器链中不使用UsernamePasswordAuthenticationFilter?

vshtjzan  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(488)

我正在开发一个Sping Boot 应用程序,在其中添加了一个自定义过滤器和addFilterBefore方法。
这是我的配置配置方法:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.cors().and().authorizeRequests()
                .anyRequest().authenticated();
        http.addFilterBefore(btoBSecurityFilter,UsernamePasswordAuthenticationFilter.class);

        http.httpBasic();
    }

以下是我的自定义筛选器:

@Component
public class BtoBSecurityFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
       //I dont want to use this as I dont want to use UsernamePasswordAuthenticationFilter.  
        SecurityContextHolder.getContext().setAuthentication(getAuthentication(7312L,"tokenlelo"));
        filterChain.doFilter(httpServletRequest,httpServletResponse);
        logger.info("hey aaya");
    }

    // dont want to use this.
    public Authentication getAuthentication(Long userId, String token) {
        UserDetails userDetails = org.springframework.security.core.userdetails.User
                .withUsername("")
                .password("")
                .build();
        return new UsernamePasswordAuthenticationToken("", "", userDetails.getAuthorities());
    }

}

现在上面的代码可以工作了,但是我不希望UsernamePasswordAuthenticationFilter在我的情况下发生,我只希望我的customFilter为我过滤掉请求。
我该怎么做?我不能使用addFilter方法,因为它会给出订单错误。我只想运行我的自定义过滤器,而不想SecurityContext设置或保存任何内容。
有人能帮我吗?

7rfyedvj

7rfyedvj1#

使用UsernamePasswordAuthenticationToken并不能保证UsernamePasswordAuthenticationFilter会过滤您的请求。
如果您查看源代码(使用IDEA或github),特别是AbstractAuthenticationProcessingFilter方法boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response)UsernamePasswordAuthenticationFilter构造函数,您会发现UsernamePasswordAuthenticationFilter只过滤与身份验证请求匹配的请求(默认为POST请求到“/login”)。
当您在UsernamePasswordAuthenticationFilter之前设置自定义过滤器时,除非您在自定义过滤器代码中跳过filterChain.doFilter(httpServletRequest,httpServletResponse)方法,否则无论如何都会在自定义过滤器之后调用此过滤器。
但是,正如我之前所说的,这并不意味着UsernamePasswordAuthenticationFilter会过滤您的请求。
因此,它并不依赖于使用UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken只是Authentication的实现之一,可用于您的情况。当您使用此类的公共构造函数和GrantedAuthority的集合时,您将创建一个受信任的(即isAuthenticated()= true)身份验证令牌。因此,安全上下文将知道该请求已通过身份验证。
顺便说一句,您使用的构造函数只能由AuthenticationManagerAuthenticationProvider调用--这在javadoc中有说明。为了安全使用,请尝试静态工厂方法:

return UsernamePasswordAuthenticationToken.authenticated(principal, credentials, userDetails.getAuthorities());

相关问题