84. 更多细节

84.1 单点登录

所有 OAuth2 SSO 和资源服务器 features 都在 version 1.3 中移动到 Spring Boot。您可以在Spring Boot 用户指南中找到文档。

84.2 令牌中继

令牌中继是 OAuth2 consumer 充当 Client 并将传入令牌转发到传出资源请求的位置。 consumer 可以是纯 Client(如 SSO application)或资源服务器。

84.2.1 Client Token Relay

如果您的应用是面向 OAuth2 client 的用户(i.e.已声明@EnableOAuth2Sso@EnableOAuth2Client),那么它在 Spring Boot 的请求范围内具有OAuth2ClientContext。您可以从此 context 和自动装配的OAuth2ProtectedResourceDetails创建自己的OAuth2RestTemplate,然后 context 将始终将访问令牌转发到下游,并在访问令牌过期时自动刷新访问令牌。 (这些是 Spring Security 和 Spring Boot.)的 features

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

Zuul 代理中的 84.2.2 Client 令牌中继

如果您的应用程序还具有Spring Cloud Zuul嵌入式反向代理(使用@EnableZuulProxy),那么您可以要求它将 OAuth2 访问令牌下游转发到它所代理的服务。因此,上面的 SSO 应用程序可以简单地增强,如下所示:

app.groovy.

@Controller
@EnableOAuth2Sso
@EnableZuulProxy
class Application {

}

它将(除了 logging 用户并获取令牌)将身份验证令牌传递到/proxy/*服务的下游。如果使用@EnableResourceServer实现这些服务,那么它们将在正确的标头中获得有效的标记。

它是如何工作的? @EnableOAuth2Sso annotation 拉入spring-cloud-starter-security(你可以在传统的应用程序中手动完成),然后它会触发ZuulFilter的一些自动配置,它本身被激活,因为 Zuul 在 classpath(通过@EnableZuulProxy)。 过滤只从当前经过身份验证的用户中提取访问令牌,并将其放入下游请求的请求标头中。

84.2.3 资源服务器令牌中继

如果您的应用程序具有@EnableResourceServer,您可能希望将传入令牌中继到其他服务。如果您使用RestTemplate来联系下游服务,那么这只是如何使用正确的 context 创建模板的问题。

如果您的服务使用UserInfoTokenServices来验证传入的令牌(i.e.它使用的是security.oauth2.user-info-uri configuration),那么您只需使用自动装配的OAuth2ClientContext创建一个OAuth2RestTemplate(它将在它到达后端 code 之前由身份验证 process 填充)。等效地(使用 Spring Boot 1.4),您可以在 configuration 中注入UserInfoRestTemplateFactory和 grab OAuth2RestTemplate。例如:

MyConfiguration.java.

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

然后,此 rest template 将具有与身份验证筛选器相同的OAuth2ClientContext(request-scoped),因此您可以使用它来发送具有相同访问令牌的请求。

如果您的应用程序未使用UserInfoTokenServices但仍然是 client(i.e.它声明@EnableOAuth2Client@EnableOAuth2Sso),那么使用 Spring Security Cloud,用户从@Autowired @OAuth2Context创建的任何OAuth2RestOperations也将转发令牌。此 feature 默认实现为 MVC 处理程序拦截器,因此它仅适用于 Spring MVC。如果您不使用 MVC,可以使用自定义过滤器或 AOP 拦截器包装AccessTokenContextRelay以提供相同的 feature。

这是一个基本的 example,显示了在其他地方创建的 autowired rest template 的使用(“foo.com”是一个资源服务器接受与周围应用程序相同的标记):

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() + ")";
}

如果您不想转发令牌(这是一个有效的选择,因为您可能想要自己行动,而不是向您发送令牌的 client),那么您只需创建自己的OAuth2Context而不是自动装配默认一个。

Feign clients 也会选择一个使用OAuth2ClientContext的拦截器(如果可用),所以他们也应该在RestTemplate所在的任何地方进行令牌转发。