资源服务器 - wzz-code/cloud-security-sample GitHub Wiki

@EnableOAuth2Resource 注解将保护您的API端点,如果您具有与SSO客户端相同的环境设置,除了它不需要 tokenUriauthorizationUri,并且它不需要 clientIdclientSecret ,如果它不使用 tokenInfoUri(即,如果它有 jwt.*userInfoUri )。

默认情况下,所有的端点都受到保护(即 "/**"),但您可以通过添加 ResourceServerConfigurerAdapter(标准Spring OAuth特性)进行选择。只保护 "/api/**" 资源

Application.java
@RestController
@EnableOAuth2Resource
class Application extends ResourceServerConfigurerAdapter {

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.requestMatchers()
      .antMatchers("/api/**")
      .and()
      .authorizeRequests()
      .anyRequest().authenticated();
  }

  @RequestMapping("/api")
  public String home() {
    return "Hello World";
  }

}

自定义JWT令牌转换器

在资源服务器接受访问令牌作为JWT时,它必须将其转换为身份验证,以便 Spring Security 可以执行其访问决策。不同的令牌提供者可以支持具有不同内容的JWT令牌,所以Spring OAuth2 具有将令牌转换为安全域对象(AccessTokenConverter)的抽象。您可以通过提供类型为 JwtAccessTokenConverterConfigurer@Bean 来轻松修改默认行为,例如。

@Component
public class JwtCustomization extends DefaultAccessTokenConverter implements
        JwtAccessTokenConverterConfigurer {

    @Override
    public void configure(JwtAccessTokenConverter converter) {
        converter.setAccessTokenConverter(this);
    }

    ... // implement custom AccessTokenConverter here

}

令牌中继

令牌中继是OAuth2消费者充当客户端,并将传入令牌转发到外发资源请求。消费者可以是纯客户端(如SSO应用程序)或资源服务器。

客户端令牌接力

如果您的应用程序具有 Spring Cloud Zuul 嵌入式反向代理(使用@EnableZuulProxy),则可以要求它将OAuth2访问令牌转发到其代理的服务。因此,上面的SSO应用程序可以简单地像这样:

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

}

并且(除了将用户登录并获取令牌之外)将认证令牌向下传递到 /proxy/* 服务。如果这些服务是通过 @EnableOAuth2Resource 实现的,那么他们将在正确的头信息中获取一个有效的标记。

它是如何工作的? @EnableOAuth2Sso 注释引入了 spring-cloud-starter-security (您可以在传统应用程序中手动执行), 这反过来又触发了 ZuulFilter 的一些自动配置, ZuulFilter 自身被激活,因为Zuul位于类路径上(通过 @EnableZuulProxy)。 该过滤器仅从当前已认证的用户提取访问令牌,并将其放入下游请求头中。

资源服务器令牌中继

如果您的应用程序具有 @EnableOAuth2Resource,并且还是一个客户端(即它有一个 spring.oauth2.client.clientId ,即使它不使用它 ), 那么 Spring Cloud提供给 @Autowired 用户的 OAuth2RestOperations (它被声明为 @Primary)也将转发令牌。如果你不想转发令牌(这是一个有效的选择,因为你可能想要像你一样,而不是向您发送令牌的客户端),那么您只需要创建自己的 OAuth2RestOperations,而不是自动连接默认的。这是一个基本示例,显示了使用自动连线的休息模板(“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() + ")";
}
⚠️ **GitHub.com Fallback** ⚠️