仅使用承载保护 Spring Cloud Gateway

Posted

技术标签:

【中文标题】仅使用承载保护 Spring Cloud Gateway【英文标题】:Securing Spring Cloud Gateway with bearer-only 【发布时间】:2021-11-04 22:01:20 【问题描述】:

我目前想使用 Spring Cloud Gateway 来保护我的微服务架构。前端向 Keycloak 服务器进行身份验证,然后在每个请求中发送令牌。 现在的情况是只有网关应该暴露给外部,而各个服务将无法从外部访问。

如何在 keycloak 服务器上验证不记名令牌?

我已经在互联网上搜索了一段时间,但还没有找到任何已验证令牌的地方。在任何地方都通过网关完成身份验证,然后由各个服务验证令牌。但是,当我将网关声明为 OAuth2 资源服务器时,整个事情就不起作用了。

【问题讨论】:

在您的情况下,我认为应该是验证令牌的服务(您的实际资源服务器),而不是网关。在更传统的spring oauth2(授权代码流)场景中,网关应该负责用keycloak生成令牌并在需要时刷新 @LeoG。但是为什么我需要在实际资源服务器未公开公开时对其进行验证,以及当没有活动用户时如何管理这些服务之间的请求,例如当我有每 10 分钟运行一次任务并需要数据的服务时来自不同的服务。 通常是资源服务器的角色来验证和验证用户:oauth.com/oauth2-servers/the-resource-server 但是有了网关,责任确实更难确定。服务到服务的通信可以通过客户端凭证流完成:oauth.com/oauth2-servers/access-tokens/client-credentials Spring Oauth2 支持,您可以在 SO 上找到一些示例 @LeoG。谢谢,我今天晚些时候会查看链接并报告 @LeoG。所以我明白了这个概念,但我目前并不知道如何实现它。我找到的每个教程都使用网关进行身份验证。但就我而言,前端已经完成了身份验证。你有我的场景的教程吗 【参考方案1】:

我设法让它工作。

我的安全配置如下:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig 
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) 
        http.authorizeExchange(exchanges -> exchanges.anyExchange().authenticated())
                .oauth2ResourceServer().jwt();
        http.csrf().disable();
        return http.build();
    


此外,我添加了一个 CorsFilter:

@Configuration
public class PreFlightCorsConfiguration 

    @Bean
    public CorsWebFilter corsFilter() 
        return new CorsWebFilter(corsConfigurationSource());
    

    @Bean
    CorsConfigurationSource corsConfigurationSource() 
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
        config.addAllowedMethod( HttpMethod.GET);
        config.addAllowedMethod( HttpMethod.PUT);
        config.addAllowedMethod( HttpMethod.POST);
        config.addAllowedMethod( HttpMethod.OPTIONS);
        config.addAllowedMethod(HttpMethod.DELETE);
        source.registerCorsConfiguration("/**", config);
        return source;
    

而我使用的安全依赖是:

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-oauth2-client</artifactId>
  </dependency>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
  </dependency>
  <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-security</artifactId>
     <version>2.2.5.RELEASE</version>
  </dependency>

【讨论】:

是的,这也是我选择的方向。出于好奇,您如何管理对特定端点的基于角色的访问?因为我认为不使用 keycloak-spring-boot-starter,所以 Spring Security 假定授予的权限是包含在令牌内的“范围”内的权限。 实际上,这个答案和它上面的答案为映射到授予权限提供了一个很好的解决方案:***.com/a/65898374/5468652

以上是关于仅使用承载保护 Spring Cloud Gateway的主要内容,如果未能解决你的问题,请参考以下文章

尽管设置了承载令牌,但 Spring Cloud Gateway 重定向到 Keycloak 登录页面

Node.js API 受 Keycloak 保护,访问类型为“仅承载”

将 Keycloak 授权服务与 Spring Boot(资源服务器)一起使用

Spring Cloud入门 - Spring Cloud保护机制

Keycloak + Spring Cloud Gateway + Angular 9

如何保护 Spring Cloud Config Server