我正在开发一个Sping Boot Webflux应用程序,它有一个自定义的WebFilter,可以根据从请求中派生的Principal对象进行即时用户创建。
WebFilter适用于需要身份验证的端点。但是对于不需要身份验证的端点,任何匹配以下模式的内容都将返回HTTP 200 -即使该端点不存在。此外,似乎没有调用端点。
我的安全配置:
@Bean
public SecurityWebFilterChain securityWebFilterChain(
ServerHttpSecurity http) {
return http.cors(cors -> cors.configurationSource(swx -> corsConfiguration()))
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.securityMatcher(new NegatedServerWebExchangeMatcher(
ServerWebExchangeMatchers.pathMatchers("/actuator/**")))
.authorizeExchange((authorize) -> authorize
.pathMatchers("/foo/**")
.permitAll()
.anyExchange()
.authenticated()
)
.oauth2ResourceServer(ors -> ors.jwt(jwt -> {}))
.build();
}
字符串
我的网络过滤器:
@Component
public class JITUserFilter implements WebFilter {
private static final Logger logger = LoggerFactory.getLogger(JITUserFilter.class);
private final UserService userService;
public JITUserFilter(UserService userService) {
this.userService = userService;
}
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange,
WebFilterChain webFilterChain) {
return serverWebExchange.getPrincipal().flatMap(p -> {
Optional<String> email = Optional.empty();
if (p instanceof JwtAuthenticationToken) {
email = Optional.of(((JwtAuthenticationToken)p).getToken().getClaimAsString("https://my-app.example.com/email"));
}
Optional<User> userOpt = userService.findUserByExternalId(p.getName());
if (userOpt.isEmpty()) {
logger.info("No existing user found; creating new with externalId {}", p.getName());
User user = new User();
user.setExternalId(p.getName());
user.setEmail(email.orElse(null));
userService.createUser(user);
}
return webFilterChain.filter(serverWebExchange);
});
}
}
型
我在/foo/bar
上有一个POST端点,我希望记录一些消息,并在命中时返回一个虚拟响应,但在向该端点发布时,我得到的只是一个200 OK响应。为什么?为什么?
1条答案
按热度按时间ukdjmx9f1#
事实证明,这里发生的事情是,如果没有传递
Authentication
头,那么web过滤器中的serverWebExchange.getPrincipal()
就是空的Mono
。如果是这种情况,整个块将被跳过,这将导致HTTP 200
响应。解决方案是在结尾添加:
字符串
从而过滤器链的其余部分继续。