spring-security 从WebFilter中的ReactiveSecurityContextHolder获取SecurityContext时出现问题

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

在我的Webflux应用程序中,我尝试使用JWT令牌来进行Spring Security的无状态会话。我有两个WebFilter,一个生成令牌,一个验证令牌。我的令牌生成过滤器工作正常,但验证过滤器出现故障。它的过滤器方法如下所示:

@Override
protected Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    final String jwt = exchange.getRequest().getHeaders().getFirst(authHeader);

    try {
        SecretKey key = Keys.hmacShaKeyFor(signingKey);

        Claims claims = Jwts.parserBuilder().setSigningKey(key)
                .build().parseClaimsJws(jwt).getBody();

        var authorities = Toolkit.getAuthorities(String.valueOf(claims.get("authorities")));
        String user = String.valueOf(claims.get("username"));

        return ReactiveSecurityContextHolder.getContext().flatMap((context) -> {
            context.setAuthentication(
                    new UsernamePasswordAuthenticationToken(
                            user, null, authorities));

            return chain.filter(exchange);
        });

    } catch (Exception e) {
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);

        e.printStackTrace();
        return exchange.getResponse().setComplete();
    }
}

ReactiveSecurityContextHolder.getContext().flatMap()中的所有内容都不会被调用,这导致了过滤器链的中断,因为chain.filter()是在flatMap()中调用的。有人知道是什么原因导致了这种情况吗?

zfycwa2u

zfycwa2u1#

通过更改

return ReactiveSecurityContextHolder.getContext().flatMap((context) -> {
        context.setAuthentication(
                new UsernamePasswordAuthenticationToken(
                        user, null, authorities));

        return chain.filter(exchange);
});

Context context = ReactiveSecurityContextHolder.withAuthentication(new UsernamePasswordAuthenticationToken(
                user, null, authorities));

return chain.filter(exchange).contextWrite(context);

从我所看到的来看,前者不起作用,因为它没有关联的身份验证对象。

相关问题