前言

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不会显示警告而已

这里可以通过给application授权指定组来实现权限控制(当然你也可以自己写策略),非该组内用户访问会出现Request has been denied.

如果不做权限控制,任何人都可以通过构造认证链接发起请求

在同级菜单下的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

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