亚马逊AWS官方博客

Keycloak 与 Amazon Web Services Console 中国区实现基于 SAML 的 SSO 集成

概览

很多企业希望通企业自己的 IDP 以 SSO 方式登录 Amazon Web Services Console。IdP 产品有很多,具体的配置方式会有差异,但大致步骤是类似的。Keycloak 是一个被广泛使用的开源 IdP 产品,此文章介绍如何实现 Keycloak 与 Amazon Web Services Console 基于 SAML 协议的 SSO 集成。本文是基于 Keycloak 21.1 版本和 Amazon Web Services 中国区做的测试,如果是与 Amazon Web Services 全球区域集成整体过程基本相同,只是要注意所需的 metadata 文件是不同的。

请同时参考 Amazon Web Services 中国区官方文档Amazon Web Services 全球区域文档了解更多细节信息。

实现步骤

在进入具体配置之前需要先部署 Keyclock,这部分可参考 Keycloak 安装文档,不在此赘述。我们直接假设 Keycloak 已经部署完成并可以通过 https://idp-domain-name.cn 进行访问,当然这个域名实际上并不存在。访问 Keycloak console 可以看到如下的界面。

Figure 1 Keycloak Admin Console

接下来进入具体的配置:

  1. 点击“Administration Console”并输入登录信息,进入管理控制页面。Keycloak 建议不要使用默认的 master realm,而是创建自己的 Realm。在此步骤创建新的名为 MyIdP 的 Realm。

Figure 2 Create Realm

  1. 在新建的 MyIdP Realm 中点击左侧菜单栏中的 Realm settings,在页面下方点击导出 SAML 2.0 Identity Provider Metadata 到指定的文件中,我将文件保存为 keycloak_saml.xml。
  2. 登录到要做集成的 Amazon Web Services Console,选择 IAM 服务,然后按如下方式创建 Provider,这里需要将上一步导出的文件上传。

Figure 3 Create Provider

  1. 点击打开刚建好的 IdP provider 并记录下 ARN,将在后面配置中用到。然后点击右上角的“Assign role”按钮。可根据自己需求选择新建 Role 或者使用已存在的 Role。最重要的是在 Role 的 Trust relationships 中增加如下配置,如果是新建 Role 则下面这段配置会被自动增加到 Role 中,如果是更新已有的 Role 则可以将 Statement 中括号中的内容合并到已有的 Statement 中。保存后记录下此 Role 的 ARN,可重复此步骤创建更多需要的 Role。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated":"arn:aws-cn:iam::11111111111:saml-provider/MyIdP"
            },
            "Action": "sts:AssumeRoleWithSAML"
        }
    ]
}

完成以上步骤后,在 Amazon Web Services Console 中所需的配置就完成了,接下来将回到 Keycloak 中继续做配置。

  1. 下载 Service Provider 的 metadata 文件:https://signin.amazonaws.cn/static/saml-metadata.xml (如果是全球区域可通过 https://signin.aws.amazon.com/static/saml-metadata.xml 下载 metadata)。
  2. 在 Keycloak 的 MyIdP Realm 中导入新的 Client。注意要选择“Import client”而不是“Create client”,因为基于上一步导出的 metadata 文件一导入方式建立新的 client 要方便很多。导入后只要填写 Name 就可以保存了。

Figure 4 Import Client

  1. 保存后页面会自动刷新,然后需要填写更多的内容。

Home URL : /realms/MyIdP/protocol/saml/clients/amazon-aws

IDP-Initiated SSO URL name : amazon-aws

Login theme : keycloak  这一项不是必须的,只是为了登录页面更友好一些

  1. 打开刚刚建好的 Client 的 Roles 页面创建新的 Role,要注意 Role name 的格式是由 Amazon Web Services 中的 Role 的 ARN 和 IdP Provider 的 ARN 以逗号分隔组成的,这两个 ARN 都在第 4 步中记录过。下面是个例子:
arn:aws-cn:iam::11111111111:role/AdminRole,arn:aws-cn:iam::11111111111:saml-provider/MyIdP
  1. Role 创建好了,还需要与 Role 关联的 User。

Figure 5 Create User

  1. 为 User 设置密码

Figure 6 Set password

  1. 为 User 创建一个 displayname 属性,将用于在 Amazon Web Services Console 中显示。

Figure 7 Set user attribute

  1. 切换到 User 的 Role mapping 页面将 User 与 Role 关联,注意选择“Filter by clients”才能找到前面创建的 Role,注意与此 Role 关联后删除掉 Keycloak 默认关联的 Role。

Figure 8 User Role mapping

观察从 https://signin.amazonaws.cn/static/saml-metadata.xml 导出的文件,其中前两个属性是必须提供的,接下来需要配置这两个属性所需的 Client scope。

Figure 9 SAML Attribute

  1. 创建新的 Client scope AmazonRoleList,然后为 client scope 设置 mapper, 点击“Configure a new mapper”。

Figure 10 Create AmazonRoleList client scope

Figure 11 Add mapper for AmazonRoleList client scope

  1. 类似上述步骤,创建 RoleSessionName client scope,参考下图。

Figure 12 Create RoleSessionName client scope


Figure 13 Add mapper for RoleSessionName client scope

  1. 进入新建的 Client 中为 Client 增加上述两个 client scope 并移除不需要的 client scope,配置后的结果如下:

Figure 14 Configure client scope

现在所有必要的配置就完成了。进入 client 页面,点击“urn:amazon:webservices:cn-north-1”client 对应的 Home URL 会打开 Keycloak 的登录页面。

Figure 15 Keycloak Login Page

登陆后可以看到已经跳转到了,选择所需的角色即可登录进 Amazon Web Services Console。

Figure 16 Login to Amazon Web Services Console

问题调试

整个配置过程并不复杂,但配置后仍有可能遇到登录失败的问题,这种情况下就需要做 troubleshooting 了。其中最大的一个可能性就是 Keycloak 生成的 SAML Response 中的 saml:AttributeStatement 部分不正确,针对这种情况一个有效的方式是将 IdP 生成的 SAML response 从浏览器中提取出来和正确的 SAML response 做对比。浏览器中提取出的 response 需要 decode 才可读,这里推荐一个做 decode 的网页工具:https://www.samltool.com/decode.php

另外为了方便对比,在这里提供一个正确的 SAML Response 的 saml:AttributeStatement 部分供参考。因为其他部分基本都是默认生成的,和配置关系不大,在此忽略。

<saml:AttributeStatement>
            <saml:Attribute Name="SAML:aud" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">https://cn-north-1.signin.amazonaws.cn/saml</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">JackZhang</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="http://aws.amazon.com/SAML/Attributes/Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">arn:aws-cn:iam::1111111111:role/AdminRole,arn:aws-cn:iam::1111111111:saml-provider/MyIdP</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>

总结

Keycloak 版本更新较快,具体的配置方式可能在不同版本中有所区别,但基本上只要在跳转到 Amazon Web Services Console 时提供的 SAML response 正确就不会有太大问题。除了上面用到的必要属性外,Amazon Web Services 也支持更多属性来实现更细粒度的控制,例如可以通过设置 SessionDuration 属性来控制 session 的有效时长,以及更多属性来控制权限等。可参考官方文档做具体调整来满足更多需求场景。

本篇作者

王崇

亚马逊解决方案架构师,负责企业架构设计,解决方案设计,协助企业加速上云流程和数字化转型。