Spring boot 使用反应堆网络和弹簧安全oauth的带弹簧webflux的MDC过滤器

Spring boot 使用反应堆网络和弹簧安全oauth的带弹簧webflux的MDC过滤器,spring-boot,spring-security,spring-security-oauth2,spring-webflux,reactor-netty,Spring Boot,Spring Security,Spring Security Oauth2,Spring Webflux,Reactor Netty,我有以下代码,它是一个MDCFilter import org.slf4j.MDC; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; import org.springframework.web.s

我有以下代码,它是一个MDCFilter

import org.slf4j.MDC;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

public class NettyMDCFilter implements WebFilter {

    public static final String USER_AND_APPLICATION_KEY = "user";
    public static final String APPLICATION_KEY = "application";
    public static final String USERNAME_KEY = "username";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return exchange.<OAuth2Authentication>getPrincipal()
            .doOnNext(this::logWithContext)
            .map(auth -> exchange)
            .switchIfEmpty(Mono.just(exchange))
            .flatMap(chain::filter)
            .doFinally(signalType -> removeMDCKeys());
    }

    private void logWithContext(OAuth2Authentication authentication) {
        MDC.put(USER_AND_APPLICATION_KEY, userKey(authentication));
        if (authentication.isClientOnly()) {
            MDC.put(APPLICATION_KEY, authentication.getName());
        } else {
            MDC.put(APPLICATION_KEY, authentication.getOAuth2Request().getClientId());
            MDC.put(USERNAME_KEY, authentication.getName());
        }
    }

    private void removeMDCKeys() {
        MDC.remove(USER_AND_APPLICATION_KEY);
        MDC.remove(USERNAME_KEY);
        MDC.remove(APPLICATION_KEY);
    }

    private String userKey(OAuth2Authentication authentication) {
        if (authentication.isClientOnly()) {
            return authentication.getName();
        } else {
            return String.format("%s:%s", authentication.getOAuth2Request().getClientId(), authentication.getName());
        }
    }
}
import org.slf4j.MDC;
导入org.springframework.security.oauth2.provider.OAuth2Authentication;
导入org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
导入org.springframework.web.server.ServerWebExchange;
导入org.springframework.web.server.WebFilter;
导入org.springframework.web.server.WebFilterChain;
导入reactor.core.publisher.Mono;
公共类NettyMDCFilter实现WebFilter{
公共静态最终字符串USER\u和应用程序\u KEY=“USER”;
公共静态最终字符串应用程序\u KEY=“APPLICATION”;
公共静态最终字符串USERNAME\u KEY=“USERNAME”;
@凌驾
公共Mono筛选器(服务器WebExchange exchange、WebFilterChain链){
返回exchange.getPrincipal()
.doOnNext(this::logWithContext)
.map(身份验证->交换)
.switchIfEmpty(Mono.just(交换))
.flatMap(链::过滤器)
.doFinally(signalType->removeMDCKeys());
}
私有void logWithContext(OAuth2Authentication身份验证){
put(用户和应用程序密钥,用户密钥(身份验证));
if(authentication.iscliently()){
put(应用程序密钥,authentication.getName());
}否则{
put(应用程序密钥,身份验证.getOAuth2Request().getClientId());
put(USERNAME\u KEY,authentication.getName());
}
}
私有void removeMDCKeys(){
删除(用户和应用程序密钥);
MDC.remove(用户名\ U键);
MDC.remove(应用程序密钥);
}
私有字符串用户密钥(OAuth2Authentication身份验证){
if(authentication.iscliently()){
返回authentication.getName();
}否则{
返回String.format(“%s:%s”,authentication.getOAuth2Request().getClientId(),authentication.getName());
}
}
}

在上一个实现中,是使用类实现的,该类属于该项目的项目,但该项目现在处于维护模式下,如您所见。在我的代码中,我想在过滤器中检查令牌是否属于客户端应用程序或用户,但我不知道如何在的新版本中做到这一点,即使阅读文档,我也不清楚应该做什么,因为没有从spring-security-oauth2项目迁移到内置支持oauth2的spring-security项目新版本的迁移教程。我在谷歌上搜索过,但找不到具体的教程来帮助我解决这个问题。

你不能使用MDC,你必须使用被动上下文。你需要使用上下文-