spring-security - 为什么资源服务器必须知道 Spring OAuth2 中的 client_id?

标签 spring-security oauth-2.0

我正在使用 Spring Boot 实现 OAuth2 授权。我已经有了授权服务器和资源服务器,现在我想使用 client_credentials 授权类型从资源服务器访问资源。

我对此有点困惑,因为在 Resource Server 中我必须添加 client_idclient_secret。但是为什么 Resource Server 真的需要它呢?

据我了解,这个概念客户端应该使用客户端凭据从授权服务器获取他的访问 token 。然后在没有任何客户端凭据的情况下将此访问 token 发送到资源服务器。

那么为什么 Resource Server 还需要一些客户端凭据呢?资源服务器和客户端是两个独立的实体,我不明白为什么资源服务器必须知道 client_idclient_secret

为什么访问 token 不足以进行身份​​验证? check_token 端点可以返回可以使用此 token 访问的资源列表,如果客户端拥有此 token ,则意味着他已经使用客户端凭据进行了身份验证以获取此 token 。

如果我想从多个不同的客户端访问这个资源服务器怎么办?

资源服务器配置:

@Configuration
@RestController
@EnableWebSecurity
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

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

    @Override
    public void configure(ResourceServerSecurityConfigurer resources)  {
        resources
            .resourceId("translate-service");
    }
}

资源服务器属性:

security.oauth2.resource.user-info-uri=http://localhost:8090/user
security.oauth2.resource.token-info-uri=http://localhost:8090/oauth/check_token
security.oauth2.client.client-id=XXXX
security.oauth2.client.client-secret=XXXX

如果我不设置客户端属性,Spring 将记录警告:

Null Client ID or Client Secret detected. Endpoint that requires authentication will reject request with 401 error.

并且身份验证将不起作用。

也许我做错了什么,有一些解决方案可以在资源服务器中不提供 client_id

最佳答案

如果您使用 RemoteTokenServices您的资源服务器也是授权服务器的附加客户端,请参阅 OAuth 2 Developers Guide :

An alternative is the RemoteTokenServices which is a Spring OAuth features (not part of the spec) allowing Resource Servers to decode tokens through an HTTP resource on the Authorization Server (/oauth/check_token). RemoteTokenServices are convenient if there is not a huge volume of traffic in the Resource Servers (every request has to be verified with the Authorization Server), or if you can afford to cache the results. To use the /oauth/check_token endpoint you need to expose it by changing its access rule (default is "denyAll()") in the AuthorizationServerSecurityConfigurer, e.g.

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess(
        "hasAuthority('ROLE_TRUSTED_CLIENT')");
}

In this example we are configuring both the /oauth/check_token endpoint and the /oauth/token_key endpoint (so trusted resources can obtain the public key for JWT verification). These two endpoints are protected by HTTP Basic authentication using client credentials.

OAuth2 Boot :

2.4 How to Configure the Token Info Endpoint

The token info endpoint, also sometimes called the introspection endpoint, likely requires some kind of client authentication, either Basic or Bearer. Generally speaking, the bearer token in the SecurityContext won’t suffice since that is tied to the user. Instead, you’ll need to specify credentials that represent this client, like so:

spring:
  security:
    oauth2:
      client:
        clientId: client-id
        clientSecret: client-secret
      resource:
        tokenInfoUri: https://issuer/oauth2/check_token

By default, this will use Basic authentication, using the configured credentials, to authenticate against the token info endpoint.

关于spring-security - 为什么资源服务器必须知道 Spring OAuth2 中的 client_id?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55548585/

相关文章:

Spring 安全 OAuth 2 : How to get access token and additional data after oauth/token request

oauth-2.0 - 通过 Autofac 4.0 配置 OAuthAuthorizationServerProvider

c# - 无法获取访问 token 和刷新 token

java - 如何在 Spring Boot 2 中保护具有角色的执行器端点?

spring - Spring PermissionEvaluator 中的@Autowired

java - 无法定义以 keycloak 开头的属性

java - 在微服务之间共享用户 ID 的最佳实践是什么?

oauth-2.0 - 使用 keycloak 将自定义键/值添加到 JWT token 负载或用户

oauth - Google 联合登录(OpenID + OAuth 2)

oauth - 可以在授权代码流 OAuth 中拦截访问 token 吗?