Spring Webflux中如何修改BearerTokenServerAuthenticationEntryPoint的响应?
解决方案:复用默认BearerTokenServerAuthenticationEntryPoint并添加响应体
在Webflux场景下,你可以通过包装默认的BearerTokenServerAuthenticationEntryPoint实例的方式,在保留其原有功能的前提下添加自定义响应体,无需创建新的自定义类。具体实现可以在Security配置中通过Lambda表达式完成:
import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.oauth2.server.resource.web.server.BearerTokenServerAuthenticationEntryPoint; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.core.io.buffer.DataBuffer; import java.nio.charset.StandardCharsets; import reactor.core.publisher.Mono; @EnableWebFluxSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { // 实例化默认的BearerTokenServerAuthenticationEntryPoint,复用其原有逻辑 BearerTokenServerAuthenticationEntryPoint defaultEntryPoint = new BearerTokenServerAuthenticationEntryPoint(); http .authorizeExchange(exchanges -> exchanges .anyExchange().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .authenticationEntryPoint((exchange, authException) -> { // 先执行默认entryPoint的逻辑(设置401状态码、WWW-Authenticate响应头等) return defaultEntryPoint.commence(exchange, authException) .then(Mono.defer(() -> { // 自定义JSON格式的响应体 String errorBody = String.format( "{\"error\":\"Unauthorized\",\"message\":\"%s\",\"status\":401}", authException.getMessage() ); // 设置响应头 exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON); // 写入响应体 DataBuffer buffer = exchange.getResponse() .bufferFactory().wrap(errorBody.getBytes(StandardCharsets.UTF_8)); return exchange.getResponse().writeWith(Mono.just(buffer)); })); }) ); return http.build(); } }
核心逻辑说明
- 先实例化默认的
BearerTokenServerAuthenticationEntryPoint,保留它处理401响应的核心逻辑(比如设置WWW-Authenticate头、状态码等)。 - 在
authenticationEntryPoint配置中使用Lambda表达式,先调用默认实例的commence方法完成基础响应配置,再通过then操作符追加自定义响应体的写入逻辑。 - 这种方式完全复用了原有组件的功能,仅扩展了响应体内容,无需编写新的自定义类。
如果需要更统一的错误格式,可以将响应体的生成逻辑抽成一个工具方法(无需自定义类),直接在Lambda中调用即可。
内容的提问来源于stack exchange,提问作者user2820906
相关产品推荐
相关产品推荐

