WebApp 托管一组 Oauth API 调用和控制访问

WebApp hosting set of Oauth API calls and controlling access

我计划创建一个 war 文件 (webapp),它将托管对不同后端系统的各种 API 调用。我将使用 OAuth2 通过 client_credentials 授权来控制访问。我计划向各种应用程序所有者发布 clientId/secrets 以控制应用程序对我的安全 APIs 的访问。

  1. 是否可以将我的 spring 安全配置配置为 只允许某些 clientId 访问特定的 API 并阻止 他们使用别人? 例如,client123 有权从 apiA 调用 GET,但不能调用 PUT 到 apiB。
  2. 我考虑过使用范围,但似乎 我的 CAS OAuth 服务器可能不支持 client_credentials.
  3. 的范围

是的,Spring安全支持多种模式,但您认为范围是首选方法是正确的。

我可能会建议您仍然在 Spring 安全方面使用范围,即使该表示仅存在于您的 API 中,以便随着 CAS 的成熟,或者如果您能够将来更改为范围,资源服务器将保持不变。

所以,假设您有一个使用 JWT 的 Spring 安全 OAuth 2.0 资源服务器:

@Override
protected void configure(HttpSecurity http) {
    http
        .oauth2ResourceServer()
            .jwt();
}

Jwt 转换为 GrantedAuthorityCollection 的钩子是 Converter<Jwt, Collection<GrantedAuthority>>。您的实施可能类似于:

public class ByClientIdJwtGrantedAuthoritiesConverter
    implements Converter<Jwt, Collection<GrantedAuthority>> {

    @Override
    public Collection<GrantedAuthority> convert(Jwt jwt) {
        // manually infer scopes from client ids
        String clientId = jwt.getSubject();
        if ("abc".equals(clientId)) {
            return Arrays.asList(new SimpleGrantedAuthority("SCOPE_read"));
        }
        // ... etc.
    }
}

然后你可以连接它:

@Override
protected void configure(HttpSecurity http) {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(new ByClientIdJwtGrantedAuthoritiesConverter());
    http
        .oauth2ResourceServer()
            .jwt()
                .jwtAuthenticationConverter(converter);
}

我做了几个假设,包括如何从令牌派生客户端,但总体思路是这样的。

Spring Security 5.2 GA 将在几周内发布,并将支持不透明令牌,以防 OAuth2 CAS 不支持 JWT。在那种情况下,你会做类似的事情,只是用 opaqueToken() DSL 代替。

此后,您可以按照与其他身份验证机制相同的方式通过路径配置 Spring 安全性:

@Override
protected void configure(HttpSecurity http) {
    http
        .authorizeRequests()
            .antMatchers("/apiA/**").hasAuthority("SCOPE_apiA")
            .antMatchers(HttpMethod.GET, "/apiB/**").hasAuthority("SCOPE_apiB:read")
            .and()
       .oauth2ResourceServer()
            .jwt()
                .jwtAuthenticationConverter(...);
}