# 前言

OIDC 的教程来了😁

在阿里云,OIDC 一般不用于登录 WEB 控制台,而是用于程序化访问,例如 CLI、SDK 或自定义应用程序,工作流程完全由 API 驱动,不过可以通过构造免登录 URL 来进行登录。

OIDC 复杂很多,这里仅按照最基础的能完成授权的流程写,具体项目请根据具体实际情况设置。
部分 Authentik 操作这里不详细写了,可以去看看之前写的阿里云角色 SSO 对接 authentik 进行单点登录

# 创建 Authentik Provider

在 Authentik 的控制台侧边栏 Applications -> Providers 中创建 provider,类型选 OAuth2/OpenID Provider

名称 :自填
授权流程 :自选或者自定义

客户端 ID客户端 Secret 自动生成,记不记无所谓,后面也看得到

重定向 URI/Origin(正则) :这里因为并不需要使用到重定向,填个 http://localhost 就行

签名密钥 :这里用 Authentik 默认的或者自己生成都行,生成操作看之前的文章

高级协议设置

作用域 :同样是先不用管,待会再回来映射

然后点击完成创建。

# 创建 Authentik Application

其实 OIDC 创不创建都无所谓,没啥用,不是授权入口,只是创建一个 provider 不会显示警告而已

在同级菜单下的 Applications 中点击 创建名称slug 随便取,用不到

提供程序选择刚刚创建的 provider 即可

# 创建身份提供商

打开阿里云控制台,进入 RAM 访问控制

找到 集成管理 -> SSO管理

选择 角色SSOOIDC

身份提供商名称 :顾名思义,按照下面灰色字要求填就行

然后回到 Authentik,点击创建的 provider,可以在右边看到一系列 URL 以及左边的 客户端 ID

这里我们需要 客户端 ID 以及 OpenID 配置颁发者 的值

回到阿里云, 颁发者 URL 填写 OpenID 配置颁发者 的值, 客户端 ID 就填 客户端 ID 的值

填完后会有个 获取指纹 按钮,这个获取的是你 OIDC Endpoint 的 SSL 证书的 CA 的指纹,正式环境请仔细对比

完成创建即可

# 创建角色

和前面那篇文章一样,想要扮演什么角色就创建什么角色,角色创建这里不重复写了,详情参考前面的文章,只是在 身份提供商类型 选项那里从 SAML 换成 OIDC 即可

然后选择刚刚创建的身份提供商

完成创建后会自动生成好信任策略,当然如果你有自定义的验证需求,可以自定义,这里就采用默认

# 添加映射

阿里云要求 Id Token 中包含 audiss

aud :客户端 ID 的值
iss :颁发者 URL(OpenID 配置颁发者)的值

来到 Authentik 的 Customization -> Property Mappings ,创建两个 map 用来映射这俩值,类型都选择 Scope Mapping

名称 :自填
作用域名称 :aud 或者 iss
表达式 :python 语言,我这里为了简单就直接返回了这俩值,自己可以根据官方文档表达式章节自定义怎么返回

1
2
#xxx为返回的值
return "xxxxxxxxxxx"

然后回到 provider,编辑一下,在作用域中将自定义的两个 map 添加进去,默认的 openid 和 email 什么的可以留着

# 小插曲:大致流程

从 Authentik 获取 Id Token,用 Id Token 在阿里云拿到 STS Token,然后用 STS Token 换 SigninToken,用 SigninToken 进行登录

# 获取 Id Token

这里就是标准的 OAuth2 流程,本教程采用 Authorization code 授权流程,其他流程请自行探索

首先构造授权请求页面 URL

在 provider 中可以看到 授权 URL

这个就是 Base Url

给 Base Url 拼接下面几个参数

response_type :固定值 code (为 Authorization code 授权流程的固定值)
client_id :顾名思义,客户端 ID
redirect_uri :和创建 provider 时填的保持一致,上文填的是 http://localhost 这里就拼这个值
state :防重放攻击的,可选,自己去查阅相关资料

拼接完成后访问该 url 即进入授权页面,完成登录后页面将重定向到 redirect_uri 所填的值

这里就是 http://localhost ,后面会接 codestate ,这里我们需要使用 code 来换取 Id Token

这里就需要使用 POST 请求,请求地址在 provider 中可以看到,名叫 令牌 URL

然后向该地址 POST 如下参数

Tips:Content-Type 必须是 application/x-www-form-urlencoded

grant_type :该流程中为 authorization_code
code :上面的 code 值
redirect_uri :同理,之前填的 redirect_uri 值
client_id :客户端 ID
client_secret :客户端 Secret(编辑一下 provider 就看得到了)

发起 POST 请求后,会返回一个 json,包含 access_token ,和 id_token

正常情况下我们会需要使用 access_token ,而 id_token 是给本地客户端用的,但是这里阿里云正是需要鉴别用户身份,因此需要使用 Id Token 而不是 access_token

# 获取 STS Token

这里暂时没找到阿里云的 Endpoint,貌似只用用阿里云的 SDK 请求?

文档 ->AssumeRoleWithOIDC - OIDC 角色 SSO 时获取扮演角色的临时身份凭证

文档里面有个调试按钮,可以方便进行请求

OIDCProviderArnRoleArn 文档也写了在哪看,找不到也可以去看看之前的那篇文章

OIDCToken 就是上文的 Id Token

RoleSessionName 用来让阿里云记录是谁在访问,用于日志审计,可以填用户邮箱之类的

然后就是发起调用

返回示例阿里云文档里有,这里就不展示了

# 获取 SigninToken

这里同样是构造 URL

Base Url 为:https://signin.aliyun.com/federation

拼接下面参数:

Action :固定值 GetSigninToken
AccessKeyIdAccessKeySecretSecurityToken :上文返回的 json 里有

发起 Get 请求后就会返回一个包含 SigninToken 的 json

# 拼接免登录 URL

Base URL 同样是 https://signin.aliyun.com/federation

拼接下面参数:

Action :固定值 Login
LoginUrl :登录失效跳转的地址
Destination :实际要访问的目标页面
SigninToken :上文 json 中

Tips:LoginUrl、Destination 和 SigninToken 都需要使用 encodeURL 进行编码处理

访问该拼接的 URL 即可进入 Web 控制台

# 后记

一般获取到 STS Token 后就可以对阿里云资源进行操作了,只是说要登录的话需要多一步获取 SigninToken

终于是写完了,累死我了。。。