为什么资源服务器必须知道 Spring OAuth2 中的 client_id? [英] Why Resource Server has to know client_id in Spring OAuth2?

查看:665
本文介绍了为什么资源服务器必须知道 Spring OAuth2 中的 client_id?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

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

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.

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

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?

资源服务器配置:

@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 将记录警告:

If I wont set client properties Spring will log warning:

检测到空客户端 ID 或客户端密钥.需要身份验证的端点将拒绝请求并显示 401 错误.

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

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

And authentication will not work.

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

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

推荐答案

如果你使用 RemoteTokenServices 你的资源服务器也是授权服务器的附加客户端,见OAuth 2 开发者指南:

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

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

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

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 启动:

2.4 如何配置令牌信息端点

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

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 OAuth2 中的 client_id?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆