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

Spring Boot中Keycloak策略强制执行器对未知API路径返回403而非404的问题求助

Spring Boot中Keycloak策略强制执行器对未知API路径返回403而非404的问题求助

我遇到了一个棘手的问题:当我在Spring Boot应用里请求一个完全不存在的API路径(比如/wrong/url)时,Keycloak策略强制执行器直接返回了403 Forbidden,而不是我预期的404 Not Found。

预期行为

  • 如果请求的路径确实存在,但用户没有授权权限 → 返回403
  • 如果请求的路径不存在,但用户已经通过Spring Boot的授权验证 → 返回404
    但目前的情况是,所有未匹配的路径或者配置错误的路径,哪怕Spring完全没有映射这个路径,都会被Keycloak拦截并返回403。

我尝试过的解决方案

我曾添加了一个自定义的OncePerRequestFilter过滤器,想实现“当没有对应的Spring处理器时,把403响应转换成404”的逻辑,但这个方案根本不起作用——因为对于未知路径,我的过滤器根本不会被触发,Keycloak在更早的请求处理阶段就把请求拦截下来了。

我的Security配置代码片段

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        // CSRF保护配置
        .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
        // 在BearerTokenAuthentication过滤器前添加策略执行器过滤器
        .addFilterBefore(createPolicyEnforcerFilter(), BearerTokenAuthenticationFilter.class)
        .securityMatcher(request -> Arrays.stream(securityDisabled)
            .noneMatch(pathName -> request.getServletPath().matches(pathName.replace("**", ".*"))))
        // 异常处理配置
        .exceptionHandling(exceptionHandling -> exceptionHandling
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport))
        // HTTP headers配置
        .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer
            .referrerPolicy(referrerPolicyConfig -> referrerPolicyConfig
                .policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))
            .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
        // 授权配置
        .authorizeHttpRequests(auth -> {
            // 允许预检请求
            auth.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll();
            // 允许所有禁用安全校验的端点(如果配置了的话)
            if (securityDisabled != null) {
                auth.requestMatchers(securityDisabled).permitAll();
            }
            auth.anyRequest().authenticated();
        })
        .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(
            multitenantAuthenticationManager()));
    return http.build();
}

private ServletPolicyEnforcerFilter createPolicyEnforcerFilter() {
    return new ServletPolicyEnforcerFilter(new ConfigurationResolver() {
        @Override
        @SneakyThrows
        public PolicyEnforcerConfig resolve(HttpRequest request) {
            String token = extractTokenFromRequest(request);
            PolicyEnforcerConfig policyEnforcerConfig = new PolicyEnforcerConfig();
            if (token != null) {
                String realm = realmFromParam(token);
                TenantModel tenantModel = tenantProperties.getConfig().get(realm);
                if (tenantModel == null) {
                    throw new IllegalStateException("No tenant configuration found for realm: " + realm);
                }
                policyEnforcerConfig.setAuthServerUrl(tenantModel.getIssuerUri().split("/realms")[0]);
                policyEnforcerConfig.setRealm(realm);
                policyEnforcerConfig.setResource(tenantModel.getClientId());
                policyEnforcerConfig.setCredentials(Map.of("secret", tenantModel.getClientSecret()));
                policyEnforcerConfig.setHttpMethodAsScope(Boolean.TRUE);
            } else {
                throw new NotAuthorizedException("Unauthorized");
            }
            return policyEnforcerConfig;
        }
    });
}

我现在的需求是:对于不存在的路径,能够返回404,而不是被Keycloak策略强制执行器拦截返回403,请问有没有可行的解决方案?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:59:29