隐式模式

OIDC除了授权码模式,还有隐式模式,即基于token的登录。该模式常结合移动应用或 Web App 使用。

OIDC 隐式模式不会返回授权码 code,而是直接将 access_tokenid_token 通过 URL hash 发送到回调地址前端后端无法获取到这里返回的值,因为 URL hash 不会被直接发送到后端。

OIDC配置

我们仍以授权码模式中提到的这张图为例:

隐式模式不需要配置App Secret,但开启该模式后,需要保证JWKS可用,有两种指定方式:

其中,JWKS URL可以从服务发现地址中获取。

OIDC使用

获取Token

获取Token有两种方式:id_token Flow和登录接口。

区别是:id_token Flow需要依赖OIDC的登录页,而登录接口获取可以自定义登录页!

id_token Flow

以Authing为例,构建如下 id_token flow URL。

访问后,进入登录页,输入账号密码登录。

登录成功后,将跳转到如下链接:

access_token 保存到客户端使用,例如:local storage

登录接口

下面是Authing用账户密码登录的HTTP请求,详情可参考Authing的SDK

不同的OIDC供应商,实现不同!

Fireboom官方也开源一个简单的OIDC服务,当前仅支持隐式模式,详情请查看:fb-oidc

使用Token

假设,有如下OPERATION,使用 @fromClaim 指令修饰,意思是根据当前登录用户的UID,查询待做事项列表:

其将被编译为如下REST API,请求如下:

工作原理

接下来,我们学习下OIDC协议隐式模式的工作原理。

正常流程

隐式模式时序图

该时序图有3个主体:客户端、Fireboom服务器、OIDC供应商 authing。

1.客户端到OIDC(Authing)

在客户端构造下述URL,跳转到Authing授权端点。

2.跳转到OIDC登录页

若用户未登录,则跳转到authing的登录页,支持账户密码、手机验证码,甚至是社交登录,如微信、QQ等。

3.OIDC跳转到客户端

登录成功后,authing再跳转到客户端回调地址上,同时携带授权码access_tokenid_token

和授权码模式不同这里拿到的不是code,且此时未经过飞布服务。

4.客户端保存令牌

客户端保存access_tokenexpires_in ,供下次使用,一般存储到local storage中。

5.客户端获取OIDC用户

客户端使用access_token,访问OIDC的用户信息端点,获得当前用户。

总结一下,1-5步骤,都不需要飞布服务参与,完全可以由客户端和OIDC服务器完成。

和授权码模式最大的不同是,隐式模式不需要client secret,也不需要使用 code 换 token,更无需请求 token 端点,access_token 和 id_token 会直接从授权端点返回。

6.客户端请求Fireboom API

客户端请求Fireboom API时,携带如下请求头 ,示例见 使用Token

7.Fireboom校验令牌

Fireboom 根据 配置的JWK公钥 验签access_token。该过程不需要OIDC服务参与,因此也意味着OIDC中的Token黑名单不会生效。需要使用Fireboom的 网关钩子 自行实现黑名单。

8.客户端获取Fireboom用户

若Fireboom服务未缓存用户信息,则会用access_token请求OIDC用户端点,获得用户,同 隐式模式

9.Fireboom调用钩子

Fireboom 调用授权钩子,在钩子中修改用户信息,返回后,由Fireboom 缓存用户信息,详情见 身份验证钩子,并返回用户信息到客户端。

简化流程

刚刚介绍的,无论是授权码模式还是隐式模式都需要使用OIDC原生的登录页。那如果想自定义登录页,又该如何做呢?

其实只要基于隐式模式稍作调整,就能支持该需求。我们知道,隐式模式的本质是获得access_token,然后用其请求接口。

那如果OIDC服务提供了根据账户密码获得accest_token的接口,是不是就可以供我们在自己编写的界面中直接调用了呢?

隐式模式时序图-简化版

我们仍以authing为例,上述流程图就展示了该过程。

1.调用登录接口

通过post请求,输入账户、密码或手机号、验证码,获得acces_token。不同OIDC供应商有对应实现,详情可参考其文档。例如前文中提到的 登录接口

2.客户端存储令牌

客户端存储 acces_token,供后续使用。

其他流程没有变化,同 正常流程 的步骤6-9。

总结

总结一下,隐式模式的流程更加简洁。

由于其不依赖cookie,所以适用范围更广,不仅支持浏览器,也能支持类似微信小程序或者原生APP。

但缺点是安全性不足,因为其直接将access_token泄露给了客户端。

最后更新于

这有帮助吗?