Why Resource Server has to know client_id in Spring OAuth2?

ada*_*ski 3 spring-security oauth-2.0

I'm implementing OAuth2 authorization using Spring Boot. I have already Authorization Server and Resource Server, now I want to access resources from Resource Server using client_credentials grant type.

I'm little confused about it, because in Resource Server I have to add client_id and client_secret. But why Resource Server really need it?

As I understand this concept client should get from Authorization Server using client credentials his access token. And then send this access token to Resource Server without any client credentials.

So why Resource Server also need some client credentials? Resource Server and client are two separeted entities, I don't understand why Resource Server has to know about client_id and client_secret.

Why access token is not enough to authenticate? check_token endpoint can return list of resources that can be accessed with this token and if client has this token, this means that he is already authenticated with client credentials to get this token.

What if I want to access from multiple different clients to this Resource Server?

Resource Server config:

@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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Resource server properties:

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
Run Code Online (Sandbox Code Playgroud)

If I wont set client properties Spring will log warning:

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

And authentication will not work.

Maybe I doing something wrong and there is some solution to not provide client_id in Resource Server?

dur*_*dur 6

如果您使用RemoteTokenServices的资源服务器也是授权服务器的附加客户端,请参阅OAuth 2 开发人员指南

另一种选择是RemoteTokenServicesSpring OAuth 功能(不是规范的一部分),允许资源服务器通过授权服务器上的 HTTP 资源解码令牌 ( /oauth/check_token)。RemoteTokenServices如果资源服务器中的流量不是很大(每个请求都必须通过授权服务器进行验证),或者您可以负担得起缓存结果,那么这很方便。要使用/oauth/check_token端点,您需要通过更改其访问规则(默认为“denyAll()”)来公开它AuthorizationServerSecurityConfigurer,例如

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

在这个例子中,我们同时配置了/oauth/check_token端点和/oauth/token_key端点(因此受信任的资源可以获得用于 JWT 验证的公钥)。这两个端点由使用客户端凭据的 HTTP 基本身份验证保护。

OAuth2 启动

2.4 如何配置令牌信息端点

令牌信息端点,有时也称为自省端点,可能需要某种客户端身份验证,基本或承载。一般来说,不记名令牌是SecurityContext不够的,因为它与用户相关联。相反,您需要指定代表此客户端的凭据,如下所示:

spring:
  security:
    oauth2:
      client:
        clientId: client-id
        clientSecret: client-secret
      resource:
        tokenInfoUri: https://issuer/oauth2/check_token
Run Code Online (Sandbox Code Playgroud)

默认情况下,这将使用基本身份验证,使用配置的凭据,对令牌信息端点进行身份验证。