OAuth2授权(Client Credentials)

OAuth2客户端模式详解与应用案例
OAuth2授权中的客户端模式(Client Credentials)主要用于信任的客户端获取访问令牌,适用于访问只读资源或开放API。本文介绍了如何使用客户端证书交换访问令牌,并通过环信IM和淘宝开放平台等案例分析了OAuth2在国内的应用。

OAuth 2.0定义了四种授权方式。

1.授权码模式(authorization code)
2.简化模式(implicit)
3.密码模式(resource owner password credentials)
4.客户端模式(client credentials)

ClientCredentials客户端模式:
Client使用自己的 client证书(如 client_id及client_secret组成的 http basic验证码)来获取 access token,只能用于信任的client
场景:

认证服务器不提供像用户数据这样的重要资源,仅仅是有限的只读资源或者一些开放的API。例如使用了第三方的静态文件服务,如Google Storage或Amazon S3。这样,你的应用需要通过外部API调用并以应用本身而不是单个用户的身份来读取或修改这些资源。这样的场景就很适合使用客户端证书授权。

1. 用客户端证书交换访问令牌

应用程序需要向认证服务器申请访问令牌,而该请求则需要客户端证书进行认证。

假设现在我们正在折腾环信IM,其认证URL为:

https://a1.easemob.com/pair/pair/token

这里需要使用POST请求并附带以下参数:

grant_type

这里为“client_credentials”

client_id

应用注册时获得的client id

client_secret

应用注册时获得的client secret

以下是一个通过命令行HTTP客户端curl发起的请求示例:

curl -d "grant_type=client_credentials\
&client_id=2016273333331117128396\
&client_secret=904b98aaaaaaac1c92381d2" \
https://a1.easemob.com/pair/pair/token
 POST /token HTTP/1.1
 Host: a1.easemob.com/pair/pair/token
 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
 Content-Type: application/x-www-form-urlencoded;charset=UTF-8
 grant_type=client_credentials

其中Authorization是client_id及client_secret组成的http_basic验证串。grant_type必须为client_credentials!

如果认证成功,服务器将会返回令牌access_token:

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "example_parameter":"example_value"
     }

2.国内一些OAUTH2案例分析(以下案例摘抄自网络)

标准的 oauth2中,使用 access token来向资源服务器发出请求,取得资源。这里的资源服务器需要使用 https协议,否则access token极可能被其它方获取。比如环信注册用户

GET /resource/1 HTTP/1.1
Host: a1.easemob.com/pair/pair/users
Authorization: Bearer 7Fjfp0ZBr1KtDRbnfVdmIw

bearer是指 token类型,后面的字符串就是access token。

还有一种 mac类型的 token(目前v20版本的草稿里还没有文档),如:

GET /resource/1 HTTP/1.1
Host: example.com
Authorization: MAC id="h480djs93hd8",
                   nonce="274312:dj83hs9s",
                   mac="kDZvddkndxvhGRXZhvuDjEWhGeE="

,因为 https速度相较http慢,而且并非所有服务器或客户都支持https,所以国内一些网站采用一种http也可访问资源的方式。

淘宝开放平台的方式
:应用通过用户授权获取的AccessToken的值即等同于Sessionkey,应用凭借AccessToken调用taobao API即可。查看淘宝SDK,可以看到 其使用应用的app_secret作用密码钥来进行签名,参数里面包含了 这个Sessionkey,这样淘宝在收到这个请求的时候,根据 app_id来判断是哪个应用,根本sessionkey的值来判断是哪个用户,如果不传这个 sessionkey就用 app_id查得app_id所属的淘宝用户就行了。也就是说 sessionkey必须配合 这个 client自己的授权资料appkey appsrecet来访问资源。

百度开放平台方式、人人网方式、还有腾讯也类似:在返回 access token的同时返回 sessionKey及sessionSecret。如:

{
    "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
    "expires_in": 86400,
    "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
    "scope": "basic email",
    "session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",
    "session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",
}

在调用资源API的时候,如下:

GET /rest/2.0/passport/users/getInfo?session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A%3D&timestamp=2011-06-21+17%3A18%3A09&format=json&uid=67411167&sign=d24dd357a95a2579c410b3a92495f009 HTTP/1.1
Host: api.example.com

这里参数里面的 session_key,传给服务器后,用户查询 session_secret,sign使用session_secret作为密钥来加密的。可以看到这里调用的时候没有使用 client_id或client_secret信息,所以对于任何获取

"session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",
"session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",

的一方都可以调用到API。降低系统耦合度。

OAuth2 的 `client_credentials` 模式是一种适用于服务间通信的授权流程,常用于后端服务之间通过客户端凭证(如 `client-id` 和 `client-secret`)获取访问令牌(access token)并验证其有效性。以下将从配置、实现和验证三个方面展开说明。 ### 1. 配置 OAuth2 客户端属性 在 Spring Boot 应用中,使用 `client_credentials` 模式时,需在 `application.yml` 或 `application.properties` 文件中配置客户端注册信息。以下是一个典型的配置示例: ```yaml spring: application: name: client-app security: oauth2: client: registration: client-app: client-id: testClient client-secret: testPassword authorization-grant-type: client_credentials scope: read,write provider: auth-server: token-uri: http://localhost:8080/oauth/token ``` 此配置指定了客户端的 `client-id` 和 `client-secret`,并指定了授权类型为 `client_credentials`,同时定义了 OAuth2 提供者的 `token-uri` 用于获取令牌[^1]。 ### 2. 实现 OAuth2 客户端凭证模式的访问逻辑 在 Java 应用中,可以通过 `OAuth2RestTemplate` 或 `WebClient` 来实现基于客户端凭证的令牌获取和资源访问。以下是使用 `OAuth2RestTemplate` 的示例代码: ```java import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; import org.springframework.stereotype.Service; @Service public class OAuth2ClientService { private final OAuth2RestTemplate oAuth2RestTemplate; public OAuth2ClientService(ClientCredentialsResourceDetails resourceDetails) { this.oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails); } public String fetchProtectedResource() { String resourceUrl = "http://localhost:8080/api/protected"; return oAuth2RestTemplate.getForObject(resourceUrl, String.class); } } ``` 该代码首先初始化了一个 `OAuth2RestTemplate`,并通过 `ClientCredentialsResourceDetails` 提供客户端凭证信息。调用 `getForObject` 方法时会自动向 `token-uri` 发起请求以获取令牌,并将令牌附加到请求头中进行受保护资源的访问。 ### 3. 令牌验证机制 在 `client_credentials` 模式下,获取到的访问令牌通常为 JWT(JSON Web Token),服务端可以通过以下方式验证令牌的有效性: - **本地验证**:服务端通过解析 JWT 的签名和声明(claims)来验证令牌的合法性。 - **远程验证**:服务端将令牌发送至 OAuth2 提供者的 `/introspect` 或 `/check_token` 接口进行验证。 以下是一个使用 `@EnableResourceServer` 的配置类,用于在 Spring Security 中启用资源服务器并验证令牌: ```java import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/**") .authorizeRequests() .anyRequest().authenticated(); } } ``` 此配置确保所有对 `/api/**` 路径的请求都必须携带有效的 OAuth2 令牌,并由 Spring Security 自动验证令牌的签名和作用域[^3]。 ### 4. 安全增强与常见问题处理 在实际部署中,应确保以下安全措施: - 使用 HTTPS 传输令牌,防止中间人攻击。 - 合理设置令牌的过期时间,避免长期有效的凭证暴露。 - 在客户端和服务端启用令牌刷新机制,提升用户体验与安全性。 如果遇到 `401 Unauthorized` 错误,应检查以下几点: - 客户端凭证(`client-id` 和 `client-secret`)是否正确。 - 令牌是否已过期或未正确附加到请求头。 - OAuth2 提供者的 `/token` 接口是否正常运行,并返回了有效的令牌。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值