更多详细信息

单点登录

所有 OAuth2 SSO 和资源服务器功能已在 Spring Boot 1.3 版本中迁移至 Spring Boot。您可以在 Spring Boot 用户指南 中找到相关文档。

Token 中继

Tokens中继是指一个OAuth2消费者充当客户端,并将传入的Tokens转发到传出的资源请求。该消费者可以是纯客户端(如SSO应用程序)或资源服务器。spring-doc.cadn.net.cn

在 Spring Cloud Gateway 中使用客户端Tokens中继

如果您的应用程序还嵌入了 Spring Cloud Gateway 嵌入式反向代理,那么您可以要求它将OAuth2访问Tokens转发到下游服务。因此,上述SSO应用可以简单地通过这种方式进行增强:spring-doc.cadn.net.cn

App.java
@Autowired
private TokenRelayGatewayFilterFactory filterFactory;

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("resource", r -> r.path("/resource")
                    .filters(f -> f.filter(filterFactory.apply()))
                    .uri("http://localhost:9000"))
            .build();
}
application.yaml
spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

并且它会(除记录用户登录并获取Tokens外) 将身份验证Tokens传递给下游服务(在这种情况下 /resource)。spring-doc.cadn.net.cn

要为 Spring Cloud Gateway 启用此功能,请添加以下依赖项spring-doc.cadn.net.cn

它是如何工作的?过滤器从当前认证的用户中提取访问Tokens,并将其放入请求头中,以便在下游请求中使用。spring-doc.cadn.net.cn

有关完整的工作示例,请参阅此项目spring-doc.cadn.net.cn

ReactiveOAuth2AuthorizedClientService 的默认实现由 TokenRelayGatewayFilterFactory 使用内存中的数据存储。如果您需要更强大的解决方案, 则必须提供自己的实现 ReactiveOAuth2AuthorizedClientService

客户端Tokens中继

如果您的应用程序是一个面向用户的 OAuth2 客户端(即已声明 @EnableOAuth2Sso@EnableOAuth2Client),则它在请求作用域中将拥有一个 OAuth2ClientContext,由 Spring Boot 提供。您可以从此上下文中创建自己的 OAuth2RestTemplate,并结合一个自动注入的 OAuth2ProtectedResourceDetails,之后该上下文将始终将访问Tokens转发至下游服务,并在访问Tokens过期时自动刷新它。(这些功能属于 Spring Security 和 Spring Boot。)spring-doc.cadn.net.cn

Sprint Boot(1.4.1)在使用 client_credentials Tokens时不会自动创建一个 OAuth2ProtectedResourceDetails。 在这种情况下,您需要创建自己的 ClientCredentialsResourceDetails 并用 @ConfigurationProperties("security.oauth2.client") 进行配置。

在Zuul代理中进行客户端Tokens传递

如果您的应用程序还具有嵌入式反向代理(使用@EnableZuulProxy)的Spring Cloud Zuul,则可以要求它将OAuth2访问Tokens转发到下游服务。因此,上述SSO应用可以通过以下方式简单增强:spring-doc.cadn.net.cn

app.groovy
@Controller
@EnableOAuth2Sso
@EnableZuulProxy
class Application {

}

此外,它还会将身份验证Tokens传递给下游的 /proxy/* 服务。如果这些服务是使用 @EnableResourceServer 实现的,那么它们将在正确的标头中获得有效的Tokens。spring-doc.cadn.net.cn

它是如何工作的?@EnableOAuth2Sso 注解会导入spring-cloud-starter-security(您可以在传统应用程序中手动完成),这又触发了对ZuulFilter 的一些自动配置,而它本身因为Zuul在类路径上(通过@EnableZuulProxy)被激活。该过滤器仅从当前已认证用户提取访问Tokens,并将其放入下游请求的请求头中。spring-doc.cadn.net.cn

Sprint Boot 不会自动生成所需的 OAuth2RestOperations,因此在这种情况下,您需要创建自己的 OAuth2RestOperations,以便在需要时让 OAuth2TokenRelayFilter 刷新Tokens。

资源服务器Tokens中继

如果您的应用程序具有 @EnableResourceServer,您可能希望将传入的Tokens下游传递给其他服务。如果您使用 RestTemplate 与下游服务进行通信,则只需如何创建带有正确上下文的模板即可。spring-doc.cadn.net.cn

如果您的服务使用UserInfoTokenServices来验证传入的Tokens(即它正在使用security.oauth2.user-info-uri配置),那么您可以简单地创建一个OAuth2RestTemplate,并使用自动装配的OAuth2ClientContext(在到达后端代码之前,会由认证过程填充)。等效地(使用Spring Boot 1.4),您可以注入一个UserInfoRestTemplateFactory并在配置中获取其OAuth2RestTemplate。例如:spring-doc.cadn.net.cn

MyConfiguration.java
@Bean
public OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) {
    return factory.getUserInfoRestTemplate();
}

此 REST 模板将具有与身份验证过滤器相同的 OAuth2ClientContext(请求作用域),因此您可以使用它以相同的访问Tokens发送请求。spring-doc.cadn.net.cn

如果您的应用程序未使用 UserInfoTokenServices,但仍是一个客户端(即声明了 @EnableOAuth2Client@EnableOAuth2Sso),那么在 Spring Security Cloud 中,用户从一个 @Autowired OAuth2Context 创建任何 OAuth2RestOperations 时也会转发Tokens。此功能默认通过 MVC 处理程序拦截器实现,因此仅适用于 Spring MVC。如果不使用 MVC,可以使用自定义过滤器或包装 AccessTokenContextRelay 的 AOP 拦截器来提供相同的功能。spring-doc.cadn.net.cn

以下是一个基本示例,展示了如何使用在其他地方创建的自动注入的 REST 模板(“foo.com” 是一个资源服务器,接受与周围应用程序相同的Tokens):spring-doc.cadn.net.cn

MyController.java
@Autowired
private OAuth2RestOperations restTemplate;

@RequestMapping("/relay")
public String relay() {
    ResponseEntity<String> response =
      restTemplate.getForEntity("https://foo.com/bar", String.class);
    return "Success! (" + response.getBody() + ")";
}

如果您不想转发Tokens(这当然是一种合理的选择,因为您可能希望以自身身份行事,而非代表发送Tokens的客户端),那么您只需创建自己的 OAuth2Context,而无需自动装配默认的那一个。spring-doc.cadn.net.cn

Feign 客户端也会拾取一个拦截器,该拦截器在可用时使用 OAuth2ClientContext,因此它们也应在任何需要进行 RestTemplate Tokens中继的地方执行Tokens中继。spring-doc.cadn.net.cn