You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Webflux实现OIDC后端登出时logout+jwt不支持的问题求助

解决Spring Webflux/Spring Cloud Gateway中OIDC后端登出的logout+jwt类型支持问题

问题根源

抛出的BadJOSEException是因为Nimbus的DefaultJOSEObjectTypeVerifier默认仅允许JWT类型的JOSE令牌,而OIDC后端登出请求携带的JWT使用了logout+jwt类型。目前Spring Security Reactive版本尚未像Servlet版本那样内置对该令牌类型的支持,导致验证失败。

解决方案

通过自定义JWT解码器和后端登出认证管理器,扩展对logout+jwt类型的支持,具体步骤如下:

1. 定制支持logout+jwt的NimbusReactiveJwtDecoder

创建自定义解码器,修改JWT处理器的类型验证规则,同时兼容原有JWT类型和新增的logout+jwt类型:

import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;

import java.util.Set;

public class LogoutJwtSupportingDecoder {
    public static ReactiveJwtDecoder create(ClientRegistration clientRegistration) {
        NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder
                .withJwkSetUri(clientRegistration.getProviderDetails().getJwkSetUri())
                .build();
        
        // 扩展JOSE类型验证器,允许logout+jwt
        decoder.setJwtProcessorCustomizer(jwtProcessor -> {
            if (jwtProcessor instanceof DefaultJWTProcessor<?, ?>) {
                ((DefaultJWTProcessor<?, ?>) jwtProcessor).setJOSEObjectTypeVerifier(
                    new DefaultJOSEObjectTypeVerifier(
                        Set.of(JOSEObjectType.JWT, new JOSEObjectType("logout+jwt"))
                    )
                );
            }
        });
        
        return decoder;
    }
}

2. 自定义OidcBackChannelLogoutReactiveAuthenticationManager

继承默认的后端登出认证管理器,替换其JWT解码器获取逻辑,使用我们定制的解码器:

import org.springframework.security.config.web.server.OidcBackChannelLogoutReactiveAuthenticationManager;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import reactor.core.publisher.Mono;

public class CustomOidcBackChannelLogoutAuthManager extends OidcBackChannelLogoutReactiveAuthenticationManager {
    private final ReactiveClientRegistrationRepository clientRegistrationRepository;

    public CustomOidcBackChannelLogoutAuthManager(ReactiveClientRegistrationRepository clientRegistrationRepository) {
        super(clientRegistrationRepository);
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    @Override
    protected Mono<ReactiveJwtDecoder> getJwtDecoder(String issuer) {
        return this.clientRegistrationRepository.findByRegistrationId(issuer)
                .map(LogoutJwtSupportingDecoder::create);
    }
}

3. 配置HttpSecurity使用自定义认证管理器

修改原有安全配置,替换默认的后端登出认证管理器:

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
public class SecurityConfig {
    private final ReactiveClientRegistrationRepository clientRegistrationRepository;

    public SecurityConfig(ReactiveClientRegistrationRepository clientRegistrationRepository) {
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
                .oidcLogout(oidcLogout -> oidcLogout
                        .clientRegistrationRepository(clientRegistrationRepository)
                        .backChannel(backChannel -> backChannel
                                .authenticationManager(new CustomOidcBackChannelLogoutAuthManager(clientRegistrationRepository))
                        )
                );
        // 补充其他安全配置...
        return http.build();
    }
}

说明

该方案通过扩展Nimbus JWT处理器的验证规则,在不破坏原有逻辑的前提下添加对logout+jwt类型的支持,完全兼容OIDC后端登出规范。待Spring Security Reactive版本官方支持该令牌类型后,可直接替换回默认配置。

内容的提问来源于stack exchange,提问作者Cedric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 02:37:02