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
相关产品推荐
相关产品推荐

