首页 > 解决方案 > MDCFilter 和 Spring webflux 使用 reactor netty 和 spring security oauth

问题描述

我有以下代码,它是一个 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());
        }
    }
}

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

标签: spring-bootspring-securityspring-security-oauth2spring-webfluxreactor-netty

解决方案


推荐阅读