Spring Boot + Keycloak 策略执行器:在 403 之前处理 401 丢失令牌

问题描述 投票:0回答:1

我使用 Spring Boot 作为资源服务器,并使用 Keycloak 进行身份验证和授权。我的设置包括用于处理 JWT 令牌的 spring-oauth2-resource-server 和用于端点访问控制的 keycloak-policy-enforcer。这是所需的行为:

  • 如果请求缺少令牌或具有无效令牌,则应返回 401 Unauthorized。
  • 如果用户拥有令牌但缺乏权限,则应返回 403 Forbidden。

但是,在我当前的设置下,没有令牌的请求会到达策略执行器,策略执行器会响应 403 而不是 401。

当前配置

这是我的 Spring Security 配置:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.csrf(AbstractHttpConfigurer::disable);
    http.cors(Customizer.withDefaults());
    http.anonymous(AbstractHttpConfigurer::disable);
    http.oauth2ResourceServer(t -> t.jwt(Customizer.withDefaults()));
    http.sessionManagement(t -> t.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    http.authorizeHttpRequests(httpMatcher -> httpMatcher.requestMatchers(whiteList).permitAll().anyRequest().authenticated());
    http.exceptionHandling((exceptions) -> exceptions.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()).accessDeniedHandler(new BearerTokenAccessDeniedHandler()));
    http.addFilterAfter(createPolicyEnforcerFilter(), BearerTokenAuthenticationFilter.class);
    return http.build();
}

private ServletPolicyEnforcerFilter createPolicyEnforcerFilter() {
    return new ServletPolicyEnforcerFilter(new ConfigurationResolver() {
        @Override
        public PolicyEnforcerConfig resolve(HttpRequest request) {
            try {
                PolicyEnforcerConfig config = JsonSerialization.readValue(getClass().getResourceAsStream("/policy-enforcer.json"), PolicyEnforcerConfig.class);
                config.setAuthServerUrl(serverUrl);
                config.setRealm(realM);
                config.setResource(clientId);
                config.setCredentials(Map.of("secret", clientSecret));

                return config;
            } catch (IOException e) {
                System.out.println(e.getMessage());
                throw new RuntimeException(e);
            }
        }
    });
}

我尝试过的 我已尝试调整过滤器顺序,但仍然看到没有令牌的请求的 403 响应。有人对如何确保没有令牌的请求在到达策略执行者之前返回 401 有建议吗?

预先感谢您的任何见解!

java spring spring-boot spring-security keycloak
1个回答
0
投票

看来您的问题主要与春季安全过滤器订单有关。 我创建了一个示例存储库,展示了如何使用 Keycloak 保护应用程序并调用它,您可以在here查看。

与您的具体过滤器问题相关,您可以通过检查我的配置方式来了解如何确保顺序合适此处。主要部分是确保过滤器添加在

AuthorizationFilter
之前。 Spring Security 文档中有更详细的解释。

在您的情况下,您正在过滤器内执行策略。在这种情况下,您需要按照

文档
中的指定抛出
AccessDeniedException
(对于 403)或 AuthenticationException(对于 401)。

Spring Security 非常庞大,有时很难找到东西,但如果您搜索足够长的时间或只是阅读全部内容,那么它们都可以在文档中找到。但希望这能解释您正在寻找的内容。

© www.soinside.com 2019 - 2024. All rights reserved.