基于OIDC实现Authentik与阿里云RAM角色的联合身份认证
前言
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管理
选择角色SSO
,OIDC
身份提供商名称
:顾名思义,按照下面灰色字要求填就行
然后回到Authentik,点击创建的provider,可以在右边看到一系列URL以及左边的客户端 ID
这里我们需要客户端 ID
以及OpenID 配置颁发者
的值
回到阿里云,颁发者 URL
填写OpenID 配置颁发者
的值,客户端 ID
就填客户端 ID
的值
填完后会有个获取指纹
按钮,这个获取的是你OIDC Endpoint的SSL证书的CA的指纹,正式环境请仔细对比
完成创建即可
创建角色
和前面那篇文章一样,想要扮演什么角色就创建什么角色,角色创建这里不重复写了,详情参考前面的文章,只是在身份提供商类型
选项那里从SAML换成OIDC即可
然后选择刚刚创建的身份提供商
完成创建后会自动生成好信任策略,当然如果你有自定义的验证需求,可以自定义,这里就采用默认
添加映射
阿里云要求Id Token中包含aud
和iss
aud
:客户端ID的值
iss
:颁发者 URL(OpenID 配置颁发者)的值
来到Authentik的Customization
->Property Mappings
,创建两个map用来映射这俩值,类型都选择Scope Mapping
名称
:自填
作用域名称
:aud或者iss
表达式
:python语言,我这里为了简单就直接返回了这俩值,自己可以根据官方文档表达式章节自定义怎么返回
1 | #xxx为返回的值 |
然后回到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
,后面会接code
和state
,这里我们需要使用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时获取扮演角色的临时身份凭证
文档里面有个调试按钮,可以方便进行请求
OIDCProviderArn
和RoleArn
文档也写了在哪看,找不到也可以去看看之前的那篇文章
OIDCToken
就是上文的Id Token
RoleSessionName
用来让阿里云记录是谁在访问,用于日志审计,可以填用户邮箱之类的
然后就是发起调用
返回示例阿里云文档里有,这里就不展示了
获取SigninToken
这里同样是构造URL
Base Url为:https://signin.aliyun.com/federation
拼接下面参数:
Action
:固定值GetSigninToken
AccessKeyId
、AccessKeySecret
、SecurityToken
:上文返回的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
终于是写完了,累死我了。。。
Use this card to join MyBlog and participate in a pleasant discussion together .
Welcome to GoodBoyboy 's Blog,wish you a nice day .