抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

OAuth2其他模式

简化模式

简化模式适用于纯静态页面应用。所谓纯静态页面应用,也就是应用没有在服务器上执行代码的权限(通常是把代码托管在别人的服务器上),只有前端 JS 代码的控制权。

授权流程

  1. 客户端重定向用户到认证服务器
  2. 用户选择是否授权给客户端
  3. 用户授权,授权服务器根据客户端请求参数uri重定向到客户端,并将token放入url的hash部分
  4. 资源服务返回一个页面,可以获取hash值
  5. 浏览器执行脚本获取令牌
  6. 浏览器叫令牌发送给客户端

使用场景

  1. 适用于所有无Server端配合的应用
  2. 如手机/桌面客户端程序、浏览器插件。
  3. 基于JavaScript等脚本客户端脚本语言实现的应用。

注意:因为Access token是附着在 redirect_uri 上面被返回的,所以这个 Access token就可能会暴露给资源所有者或者设置内的其它方(对资源所有者来说,可以看到redirect_uri,对其它方来说,可以通过监测浏览器的地址变化来得到 Access token)。

图解

  • 简化模式,顾名思义,就是简化了的模式。
  • 简化的就是授权码这个步骤

授权代码示例

授权服务端

跟授权码类型,只需要变化一下授权方式

将 authorizedGrantTypes 类找改为 implicit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("order-server")//用于标识用户ID
//支持 授权码、密码两种授权模式,支持刷新token功能
.authorizedGrantTypes("implicit")//授权方式
.resourceIds("order-server")
.authorities("authorization_code")
//跳转客户端地址
.redirectUris("http://baidu.com")
.scopes("test")//授权范围
//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"))
.accessTokenValiditySeconds(1200)
.refreshTokenValiditySeconds(50000);


}
测试
获取Token

入参

参数 描述
localhost 8080这里是我服务的地址以及端口,根据每个人的情况是不同的
/oauth/authorize 这个是Spring Security OAuth2默认提供的接口
response_type 表示授权类型,必选项,此处的值固定为”token”
client_id 表示客户端的ID,必选项。这里使用的是项目启动时,控制台输出的security.oauth2.client.clientId,当然该值可以在配置文件中自定义
redirect_uri 表示重定向URI,可选项。即用户授权成功后,会跳转的地方,通常是第三方应用自己的地址
scope 表示申请的权限范围,可选项。这一项用于服务提供商区分提供哪些服务数据
state 表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。这里没有使用到该值

身份认证

输入地址如果没有登录需要进行身份认证

1
http://127.0.0.1:9988/oauth/authorize?response_type=token&client_id=order-server&redirect_uri=http://baidu.com

获取Token

登录成功后就会出现回调地址页面,token在参数里面

1

Token已随着回调地址传到客户端了

校验授权码

验证token有效性

1
http://127.0.0.1:9988/oauth/check_token?token=560877ad-0f4d-41de-8cb2-56826a25fc74

客户端服务器

客户端沿用 授权码的代码即可不需要任何变更

测试
1
http://127.0.0.1:8083/order/createorder/1?access_token=560877ad-0f4d-41de-8cb2-56826a25fc74

密码模式

请求步骤

  • 用户向客户端提供用户名和密码
  • 客户端将用户名和密码发送给认证服务器去认证授权
  • 认证服务器验证无误,返回给客户端令牌

使用场景

  1. 这种模式适用于用户对应用程序高度信任的情况。比如是用户操作系统的一部分。
  2. 认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

图解

  • 密码模式其实就是进一步再去简化了简化模式。
  • 不仅仅没有了授权码模式下的授权码,也没了简化模式下的授权请求。
  • 直接就请求了令牌码

授权代码示例

授权服务端

跟授权码类型,只需要变化一下授权方式

将 authorizedGrantTypes 类找改为 password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("order-server")//用于标识用户ID
//支持 授权码、密码两种授权模式,支持刷新token功能
.authorizedGrantTypes("password")//授权方式
.resourceIds("order-server")
.authorities("authorization_code")
//跳转客户端地址
.redirectUris("http://baidu.com")
.scopes("test")//授权范围
//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"))
.accessTokenValiditySeconds(1200)
.refreshTokenValiditySeconds(50000);


}
测试
获取Token

入参

参数 描述
grant_type 表示授权类型,必选项,此处的值固定为”password”
username 用户名
password 密码
client_id 表示客户端的ID,必选项。这里使用的是项目启动时,控制台输出的security.oauth2.client.clientId,当然该值可以在配置文件中自定义
client_secret 平台给应用分配的密钥
scope 表示申请的权限范围,可选项。这一项用于服务提供商区分提供哪些服务数据
state 表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。这里没有使用到该值

获取Token

输入地址如果没有登录需要进行身份认证

1
http://127.0.0.1:9988/oauth/token?grant_type=password&username=admin&password=admin&client_id=order-server&client_secret=123456

校验授权码

验证token有效性

1
http://127.0.0.1:9988/oauth/check_token?token=560877ad-0f4d-41de-8cb2-56826a25fc74

客户端服务器

客户端沿用 授权码的代码即可不需要任何变更

测试

客户端模式

请求步骤

  • 客户端直接向授权服务器发起授权认证,获取令牌
  • 授权服务器校验通过,颁发令牌

使用场景

  1. 客户端模式应用于应用程序想要以自己的名义与授权服务器以及资源服务器进行互动。
  2. 例如使用了第三方的静态文件服务

图解

  • 客户端模式可是最简化的了。
  • 什么都不问,直接请求!简单粗暴给我令牌!

授权代码示例

授权服务端

跟授权码类型,只需要变化一下授权方式

将 authorizedGrantTypes 类找改为 client_credentials

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("order-server")//用于标识用户ID
//支持 授权码、密码两种授权模式,支持刷新token功能
.authorizedGrantTypes("client_credentials")//授权方式
.resourceIds("order-server")
//跳转客户端地址
.redirectUris("http://baidu.com")
.scopes("test")//授权范围
//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"))
.accessTokenValiditySeconds(1200)
.refreshTokenValiditySeconds(50000);


}
测试
获取Token

入参

参数 描述
grant_type 表示授权类型,必选项,此处的值固定为”client_credentials”
username 用户名
password 密码
client_id 表示客户端的ID,必选项。这里使用的是项目启动时,控制台输出的security.oauth2.client.clientId,当然该值可以在配置文件中自定义
client_secret 平台给应用分配的密钥
scope 表示申请的权限范围,可选项。这一项用于服务提供商区分提供哪些服务数据
state 表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。这里没有使用到该值

获取Token

输入地址如果没有登录需要进行身份认证

1
http://127.0.0.1:9988/oauth/token?grant_type=client_credentials&client_id=order-server&client_secret=123456

校验授权码

验证token有效性

1
http://127.0.0.1:9988/oauth/check_token?token=560877ad-0f4d-41de-8cb2-56826a25fc74

客户端服务器

客户端沿用 授权码的代码即可不需要任何变更

测试

刷新令牌

使用场景

在上述第三方应用获取到访问令牌后,一般会同时得到一个过期时间以及刷新令牌,以在访问令牌失效时可以由第三方应用自动获取新的访问令牌,而不是由微信用户a再次授权一遍。

当访问令牌过期时,由第三方应用调用微信授权服务器的刷新令牌接口,传递以下参数即可。

图解

第三方已存在令牌码为前提进行更新令牌

授权服务端

以授权码模式为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("order-server")//用于标识用户ID
//支持 授权码、密码两种授权模式,支持刷新token功能
.authorizedGrantTypes("authorization_code","refresh_token")//授权方式
.resourceIds("order-server")
//跳转客户端地址
.redirectUris("http://baidu.com")
.scopes("test")//授权范围
//客户端安全码,secret密码配置从 Spring Security 5.0开始必须以 {bcrypt}+加密后的密码 这种格式填写;
.secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"))
.accessTokenValiditySeconds(1200)
.refreshTokenValiditySeconds(50000);


}

测试

获取Token

以授权码模式为例,步骤同授权码模式,取得授权码后,去取token时,返回

1
2
3
4
5
6
7
{
"access_token": "560877ad-0f4d-41de-8cb2-56826a25fc74",
"token_type": "bearer",
"refresh_token": "ac8a2ff7-be4b-4d22-8dc6-93ddbfc9d5ce",
"expires_in": 19763,
"scope": "test"
}
刷新Token

调用刷新令牌

1
http://localhost:9988/oauth/token?grant_type=refresh_token&refresh_token=ac8a2ff7-be4b-4d22-8dc6-93ddbfc9d5ce&client_id=order-server&client_secret=123456

这样就可以拿新的access_token继续调用了

建议将access_token和refresh_token的过期时间保存下来,每次调用平台方的业务api前先对access_token和refresh_token进行一下时间判断,如果过期则执行刷新access_token或重新授权操作。refersh_token如果过期就只能让用户重新授权。

总结

授权模式 授权终点 令牌终点
授权码模式 使用 使用
简化模式 使用 不使用
密码模式 不使用 使用
客户端模式 不使用 使用
刷新令牌 不使用 使用

其实授权终点就是授权请求和响应,令牌终点就是令牌的请求和响应

评论