SpringCloud-技术专区-Gateway基于OAuth2.0 的身份认证

请求转发

  Spring Cloud Gateway 可以通过代码或者配置文件指定路由,我还是习惯在配置文件里面操作。这里简单配置将所有 /api/** 的请求都转发到 api-service 进行处理。
spring:
cloud.gateway.routes:
- id: api-service-route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- StripPrefix=1

  这个例子中,如果访问 http://localhost:8082/api/hello,gateway-service 会把对应的请求转到 http://localhost:8080/hello,实际进行处理的是 api-service。

  StripPrefix 是 Spring Cloud Gateway 提供的 Gateway Filter,Spring Cloud Gateway 提供了众多预设的 Filters,你可以在 Spring Cloud Gateway 官方文档 中进行查询,可以根据自己的需求使用已有的 Filters 进行快速开发,当然也可以参考这些 Filters 的源码

  自己封装自定义的 Filter。

负载均衡

  我们的后端服务通常是需要实现高可用的,将 user-service 和 gateway-service 注册到注册中心(我们使用 Consul),spring.cloud.gateway.discovery.locator.enabled = true 启用服务发现,并搭配 lb:// 使用负载均衡(load balancer)。在 Spring Cloud Gateway 中,LoadBalancerClientFilter 负责处理 lb 请求并获取到真实请求地址。

spring.cloud.gateway:
discovery.locator.enabled: true
routes:
- id: api-service-route
uri: lb://api-service
predicates:
- Path=/api/**
filters:
- StripPrefix=1

身份认证

 认证中心是基于 Spring Security 实现标准 OAuth2.0 认证服务,我们依然使用 spring-security-oauth2-resource-server 将 Gateway 作为 oauth2 client 进行集成。

  用户的访问基本上都是需要携带 JWT Token 的,gateway-service 在接收到请求之后,会向鉴权服务发送鉴权请求,获得授权之后可以得到当前访问的用户详细信息;如果检测到请求未

经授权,那么 gateway-service 直接会返回未授权错误,保护内部服务访问安全。

  理论上鉴权也可以通过自定义 gateway filter 来实现,不过我们希望可以尽可能多使用 spring-security 提供的能力,毕竟自己封装需要实现的东西还是有点多的。

  Spring Cloud Gateway 只支持搭配 webflux 使用,所以我们后续使用了 @EnableWebFluxSecurity 注解。

  我们将 gateway 作为一个 resource server 进行配置,毕竟 spring-security 帮我们做了很多事情,所以需要我们自己配置的代码很少。

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated();
     http.oauth2ResourceServer().jwt();
 return http.build();
}

  因为我们的 authorization server 使用了 jwt token,jwt 很适合在纯 RESTful API 中作为无状态的认证凭证进行使用,搭配 spring security oauth2 的话,简单且好用。当然如果在某些场景下需要撤销某个 jwt token,也可以搭配 redis 进行管理。

  我们在上面代码中声明了 gateway-service 作为一个简单的 resource server 并启用了 jwt,jwt token 通过公钥来验证有效性。因此我们需要指定 jwt 鉴权的公钥地址。

spring.security.oauth2.resourceserver.jwt:
jwk-set-uri: 'http://localhost:8081/.well-known/jwks.json'

  经过上面这些配置之后,我们就已经实现了一个比较简单的微服务架构下的网关服务了。

 

posted @ 2020-03-14 15:43  洛神灬殇  阅读(12549)  评论(1编辑  收藏  举报