客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
具体步骤:
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=s6BhdRkqt3
&client_secret=123456&scope=test
本节在Spring Security Oauth2-授权码模式(Finchley版本)做很小的修改就可以实现客户端模式。客户端模式为后台api服务消费者设计,不支持refresh token。
修改授权服务配置类AuthorizationServerConfiguration
,在客户端详情配置中新增客户端模式配置:
/** * 配置客户端详情服务 * 客户端详细信息在这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息 * @param clients * @throws Exception */
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client1")//用于标识用户ID
.authorizedGrantTypes("authorization_code","client_credentials","refresh_token")//授权方式
.scopes("test")//授权范围
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"));//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
}
其它地方无需修改
启动授权服务和资源服务。
{
"access_token":"69b10f69-0a99-4925-b81d-f83c6f79d32a",
"token_type":"bearer",
"expires_in":42600,
"scope":"test"
}
http://localhost:8088/user?access_token=69b10f69-0a99-4925-b81d-f83c6f79d32a
返回结果如下:{
"authorities": [],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null,
"tokenValue": "69b10f69-0a99-4925-b81d-f83c6f79d32a",
"tokenType": "Bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": null,
"principal": "client1",
"credentials": "",
"clientOnly": true,
"oauth2Request": {
"clientId": "client1",
"scope": [
"test"
],
"requestParameters": {
"client_id": "client1"
},
"resourceIds": [],
"authorities": [],
"approved": true,
"refresh": false,
"redirectUri": null,
"responseTypes": [],
"extensions": {},
"grantType": null,
"refreshTokenRequest": null
},
"name": "client1"
}
源代码下载
密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
具体步骤如下:
整个过程中,客户端不得保存用户的密码。
本节在Spring Security Oauth2-授权码模式(Finchley版本)做很小的修改就可以实现客户端模式。密码模式为为遗留系统设计,支持refresh token。
修改授权服务配置类AuthorizationServerConfiguration
,在客户端详情配置中新增密码模式配置:
/** * 配置客户端详情服务 * 客户端详细信息在这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息 * @param clients * @throws Exception */
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client1")//用于标识用户ID
.authorizedGrantTypes("authorization_code","client_credentials","password","refresh_token")//授权方式
.scopes("test")//授权范围
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"));//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
}
其它地方无需修改
启动授权服务和资源服务。
{
"access_token": "9411d111-141f-441f-83d2-af7be239509c",
"token_type": "bearer",
"refresh_token": "196fc388-3d46-4133-966d-e840063f426a",
"expires_in": 43179,
"scope": "test"
}
http://localhost:8088/user?access_token=9411d111-141f-441f-83d2-af7be239509c
返回结果如下:{
"authorities": [
{
"authority": "USER"
}
],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null,
"tokenValue": "9411d111-141f-441f-83d2-af7be239509c",
"tokenType": "Bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": {
"authorities": [
{
"authority": "USER"
}
],
"details": null,
"authenticated": true,
"principal": "admin",
"credentials": "N/A",
"name": "admin"
},
"principal": "admin",
"credentials": "",
"clientOnly": false,
"oauth2Request": {
"clientId": "client1",
"scope": [
"test"
],
"requestParameters": {
"client_id": "client1"
},
"resourceIds": [],
"authorities": [],
"approved": true,
"refresh": false,
"redirectUri": null,
"responseTypes": [],
"extensions": {},
"grantType": null,
"refreshTokenRequest": null
},
"name": "admin"
}
源代码下载
简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
具体步骤如下:
本节在Spring Security Oauth2-授权码模式(Finchley版本)做很小的修改就可以实现客户端模式。简化模式为web浏览器应用设计,支持refresh token,比授权码模式少了code环节,回调url直接携带token,基于安全性考虑,建议把token时效设置短一些。
修改授权服务配置类AuthorizationServerConfiguration
,在客户端详情配置中新增简化模式配置:
/** * 配置客户端详情服务 * 客户端详细信息在这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息 * @param clients * @throws Exception */
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client1")//用于标识用户ID
.authorizedGrantTypes("authorization_code","client_credentials","password","implicit","refresh_token")//授权方式
.scopes("test")//授权范围
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"));//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
}
其它地方无需修改
启动授权服务和资源服务。
http://localhost:8080/oauth/authorize?response_type=token&client_id=client1&redirect_uri=https://screenshot.net/zh/free-image-uploader.html
,用户输入密码并授权后浏览器的重定向地址为https://screenshot.net/zh/free-image-uploader.html#access_token=ab7b3a82-9b0d-4346-8603-da35891c26f2&token_type=bearer&expires_in=42111&scope=test
,其中包含了tokenhttp://localhost:8088/user?access_token=ab7b3a82-9b0d-4346-8603-da35891c26f2
返回结果如下:{
"authorities": [
{
"authority": "USER"
}
],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null,
"tokenValue": "ab7b3a82-9b0d-4346-8603-da35891c26f2",
"tokenType": "Bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": {
"authorities": [
{
"authority": "USER"
}
],
"details": null,
"authenticated": true,
"principal": "admin",
"credentials": "N/A",
"name": "admin"
},
"principal": "admin",
"credentials": "",
"clientOnly": false,
"oauth2Request": {
"clientId": "client1",
"scope": [
"test"
],
"requestParameters": {
"client_id": "client1"
},
"resourceIds": [],
"authorities": [],
"approved": true,
"refresh": false,
"redirectUri": null,
"responseTypes": [],
"extensions": {},
"grantType": null,
"refreshTokenRequest": null
},
"name": "admin"
}
源代码下载