亚马逊AWS官方博客

基于 SAML 协议 使用 IAM Identity Center 和企业 Web 应用集成

1. IAM Identity Center 服务功能介绍

Amazon IAM Identity Center(IdC)可以创建企业用户目录,或者同步企业 IdP 用户,集中管理 AWS 账户和应用程序的访问权限,实现单点登录(SSO)。从集成对象划分,IdC 可以用来和 AWS 账户,AWS 托管服务,知名第三方应用,企业内部自定义应用 4 种场景。本文将聚焦在 IdC 如何和企业内部自定义应用集成,介绍在主流的 web 应用场景,如何使用 SAML 协议和 IdC 集成,实现用户登录,访问企业内部应用。

2. IAM Identity Center 和企业应用集成准备工作

和 IdC 集成前,企业可以从以下几个角度进行分析,检查 IdC 是不是最合适的工具:

  • 被集成的应用是面向企业内部人员使用,还是面向消费者人群,通常面向企业内部人员的应用,用户数量和面向消费者的 APP 较少,同时由于是内部员工使用,一般不会需要用户注册,销户等流程,只需要在 IdC 上创建用户,或和企业的 IdP 集成即可。
  • Web 应用开发的框架,以及对应框架有没有比较成熟的 SAML 集成库。主流的 js,python 都有比较成熟的 SAML 库,尽量不要选择偏门,不完善的库进行 SAML 对接。
  • 企业内部是否有三方的 IdP 或 AD 需要和 IdC 集成,如果用户规模不大,可以考虑直接在 IdC 创建用户,但多数场景,IdC 需要和企业的 IdP,AD 等进行对接,完成身份认证,这就要求 IdC 和企业 IdP 或 AD 的对接时,处理 attribute 映射等工作。
  • 最后 IdC 目前支持两种 Instance,Organization Instance 和 Account Instance,Org Instance 支持完整的 IdC 功能,一般可以优先选择,Account Instance 只支持应用集成,由于目前每个 IdC 只支持一个身份源,如果企业有要支持多个身份源的情况,可以考虑使用 Account Instance 支持额外的身份源。注意,目前如果要使用 SAML 协议和企业应用集成,只能使用 Organization Instance。

3. SAML 2.0 协议工作原理

Security Assertion Markup Language,简称 SAML,是一个基于 XML 的开源标准数据格式,它在当事方之间交换身份验证和授权数据,尤其是在身份提供者(IdP)和服务提供者(SP)之间交换。下图是一个简单 SAML 验证流程图(SP Initiated),SAML 需要通过 HTTP Redirect 和 HTTP POST 协议来传递用户信息,通常是使用 HTML FORM 的格式来进行数据提交,对 HTTP 协议有很强依赖性,所以一般会用在企业内部的 Web 应用上。另外用户首先访问 SP(SP Initiated),还是首先访问 IdP 登录页面(IdP Initiated),会导致在登录流程上有所区别。

4. IAM Identity Center 身份源的配置

IAM Identity Center 中的身份源定义了用户和组的管理位置。完成身份源配置后,您可以查找用户或组,然后向其授予单点登录访问 Amazon Web Services 账户和/或应用程序的权限。IdC 支持 3 种用户目录,客户可以选择其中一个作为身份源:

  • IdC 身份中心目录 – 当您首次启用 IAM Identity Center 时,会自动将 Identity Center 目录配置为您的默认身份源。
  • AD 活动目录 –使用 Amazon Directory Service 或 Active Directory (AD) 中的管理您的 Amazon Managed Microsoft AD 目录中的用户。
  • 外部身份提供者 –管理外部身份提供者(IdP)(例如 Okta,Microsoft Entra ID 等)中的用户。

4.1 举例使用 Amazon Managed Microsoft AD 作为 IdC 认证源

AWS Managed Microsoft AD(也称为 AWS Directory Service for Microsoft Active Directory)是 AWS 提供的一项托管服务,旨在让用户在云端使用 Microsoft Active Directory 的功能。AWS Managed Microsoft AD 提供标准版和企业版两个版本,标准版支持最多 30,000 个对象(例如用户、组和计算机),企业版支持最多 500,000 个对象。

参考以下文档安装 Active Directory 管理工具并在 AWS Managed Microsoft AD 中管理用户和组

https://docs.aws.amazon.com/zh_cn/directoryservice/latest/admin-guide/ms_ad_manage_users_groups.html

参考以下文档将 AD 中的管理用户同步到 IAM Identity Center 中

https://docs.amazonaws.cn/singlesignon/latest/userguide/get-started-connect-id-source-ad-idp-specify-user.html#sync-admin-user-from-ad

IAM Identity Center 定期从 Active Directory 源目录读取数据保持更新。默认情况下,IAM Identity Center 每小时从 Active Directory 同步一次数据。根据 Active Directory 的大小,数据同步到 IAM Identity Center 可能需要 30 分钟到 2 小时。IAM Identity Center 会创建或更新在同步范围内的用户和组对象及其成员关系,以映射到 Active Directory 源目录中的相应对象。

属性映射

在 IAM Identity Center 中添加客户托管应用程序时,通常需要通过自定义 SAML 断言来传递有关用户登录的其他数据,比如用户邮箱、用户名等。参考以下文档将应用程序中的属性映射到 IAM Identity Center 中的相应属性:

https://docs.aws.amazon.com/zh_cn/singlesignon/latest/userguide/mapawsssoattributestoapp.html

下表列出了所有支持的 IAM Identity Center 属性,这些属性可以从 AWS Managed Microsoft AD 映射到 IdC。设置应用程序属性映射后,您可以使用这些 IAM Identity Center 属性来映射到该应用程序使用的实际属性。

  • ${user:AD_GUID}
  • ${user:email}
  • ${user:familyName}
  • ${user:givenName}
  • ${user:middleName}
  • ${user:name}
  • ${user:preferredUsername}
  • ${user:subject}
  • ${user:groups}*

* 官方文档并未列出 ${user:groups} 属性

注意:所有在 IAM Identity Center 中配置的应用程序属性映射都需要在 AD 中存在相应属性。例如,我们通常将应用程序中的用户属性 Subject 映射到 IAM Identity Center 中的 ${user:email} 属性,则 AD 中的用户必须设置电子邮件地址。如果属性映射中添加了 IAM Identity Center 中的 ${user:middleName} 属性,因其映射到 AD 中的 ${dir:initials} 属性,那么 AD 中用户的姓名缩写这个属性也不能为空。

用户组属性

IAM Identity Center 中的 ${user:groups} 属性会返回用户所在组的列表。注意:官方文档中并未支持此属性。您如果想利用用户组进行用户身份认证,可以通过以下方式获取 ${user:groups} 的值。

如果选择内置的 IAM Identity Center 目录作为身份源,可以通过 IAM Identity Center 页面一般信息下的ID 获取。

${user:groups} :[“74d8e428-2071-7083-a38c-b8d817b921f9”]

如果选择 Active Directory 作为身份源,您需要通过 AD 域名和组 SID 构造组 ID,格式为“<AD域名>//<组SID>”。
假设您的 AD 域名为 test-ad.example.com,并且此 AD 中有一个组 admin-group,您可以通过在 Windows PowerShell 中执行以下命令获取组 SID。

C:\Users\admin> Get-ADGroup -Identity “admin-group” | Select-Object -ExpandProperty SID

${user:groups} :[“test-ad.example.com//S-1-5-21-1827451404-2841176085-2581059949-2110”]

5. IAM Identity Center 和 web 应用集成示例

下面是 IAM Identity Center 分别使用 Node.js 和 Python 开发的 web 应用集成的示例。假设我们已经在 AWS account 中启用了 IAM Identity Center,按照以下步骤完成 IAM Identity Center 的配置:

  1. 打开 IAM Identity Center 控制台。
  2. 根据所选择的身份源类型,参考 Identity Center 目录Active Directory 的相关文档完成身份源的配置/连接,以及用户和组的添加/同步。
  3. 选择应用程序。
  4. 选择客户托管选项卡。
  5. 选择添加应用程序
  6. 选择应用程序类型页面,选择设置首选项下的我想设置应用程序
  7. 应用程序类型下,选择 SAML 2.0,然后选择下一步
  8. 配置应用程序页面,输入应用程序的显示名称描述
  9. IAM Identity Center 元数据下,下载 IAM Identity Center SAML 元数据文件IAM Identity Center 证书,并记录 IAM Identity Center 登录 URL IAM Identity Center 注销 URL,以备后续配置使用。
  10. 应用程序元数据下,选择手动输入元数据值。您需要根据不同的应用程序提供相对应的应用程序 ACS URL 应用程序 SAML 受众的值,在这一步可以暂时填写符合规则的 ACS URL 和 SAML 受众,例如 https://example.comidc-example
  11. 选择提交。您将进入刚刚添加的应用程序的详细信息页面。
  12. 选择分配用户和组,选择允许访问应用程序的用户及组,选择指定用户
  13. 在应用程序的详细信息页面上,选择操作,然后选择编辑属性映射
  14. 在第一条默认属性 Subject 的第二个文本框中,输入${user:email},保持格式选择 unspecified 不变。通过这个配置,应用程序中的用户属性 Subject 将会映射到 IAM Identity Center 中的用户属性${user:email}
  15. 选择新增属性映射
  16. 在第一个文本框中,输入应用程序属性 name,在第二个文本框中,输入${user:name}格式选择 unspecified
  17. 重复上述两步,添加 email groups 属性映射
    1. email${user:email} — unspecified
    2. groups${user:groups} — unspecified
  18. 选择保存更改

5.1 Node.js web 应用

在这个示例中,我们将创建一个基于 Express 框架的 Node.js web 应用,并使用 @node-saml/passport-saml 库将此 web 应用和 IAM Identity Center 集成。

  1. passport-saml 提供了一个示例项目 passport-saml-example,将此项目克隆到本地,并按照项目使用说明安装依赖。
  2. 将之前下载的 IAM Identity Center 证书 (例如 pem)保存到项目根目录下
  3. 编辑 /config/config.js 文件
    1. 替换 entryPoint 中的 https://openidp.feide.no/simplesaml/saml2/idp/SSOService.phpIAM Identity Center 登录 URL,例如:
      entryPoint: process.env.SAML_ENTRY_POINT || 'https://portal.sso.us-east-1.amazonaws.com/saml/assertion/MDEyODcw............'
    2. 修改 cert 为 cert:env.SAML_CERT || require('fs').readFileSync('./app_certificate.pem', 'utf8')
  4. 编辑 /config/passport.js 文件
    passport.use(new SamlStrategy(
        config.passport.saml,
        function (profile, done) {
          return done(null,
            {
              email: profile.email,
              displayName: profile.name,
              groups: profile.groups,
            });
        })
      );
    
  5. 编辑 /app/views/profile.jade 文件
    extends layout
    
    block content
        h1 Profile
    
        dl
            dt Display Name
            dd #{user.displayName}
            dt Email
            dd #{user.email}
            dt Groups
            dd #{user.groups}
    
        a(href="/logout") Logout
    
  6. 打开 IAM Identity Center 控制台
  7. 在 IAM Idengtity Center 应用程序中选择刚刚创建的应用程序
  8. 在应用程序的详细信息页面上,选择操作,然后选择编辑配置
  9. 应用程序元数据
    1. 应用程序 ACS URL 文本框中输入 http://localhost:3000/login/callback
    2. 应用程序 SAML 受众文本框中输入 passport-saml
  10. 选择提交
  11. 编译项目,访问 http://localhost:3000/

5.2 Python web 应用

在这个示例中,我们将创建一个基于 Flask 框架的 Python web 应用,并使用 python3-saml 库将此 web 应用和 IAM Identity Center 集成。

  1. 将 python3-saml 项目克隆到本地,此项目中已经包含了多种框架的 demo 代码
  2. 编辑 /demo-flask/saml/settings.json 文件
    • sp.entityId:任意字符串,比如 "http://localhost:8000/metadata/",需要和 IAM Identity Center 应用程序 SAML 受众保持一致
    • sp.assertionConsumerService.url:"http://localhost:8000/?acs"
    • sp.singleLogoutService.url:"http://localhost:8000/?sls"
    • NameIDFormat:一定要设置成 SAML:1.1,注意这里不要设置成 2.0,是因为 IdC 目前只支持 NameIDFormat SAML1:1 否则会影响 IdC 的认证流程
    • entityId:IAM Identity Center登录 URL
    • idp.singleSignOnService.url:IAM Identity Center 登录 URL
    • idp.singleLogoutService.url:IAM Identity Center 注销 URL
    • x509cert:复制 IAM Identity Center SAML 元数据文件<ds:X509Certificate> 和 </ds:X509Certificate> 标签之间的内容
  1. 打开 IAM Identity Center 控制台
  2. 在 IAM Idengtity Center 应用程序中选择刚刚创建的应用程序
  3. 在应用程序的详细信息页面上,选择操作,然后选择编辑配置
  4. 应用程序元数据
    1. 应用程序 ACS URL 文本框中输入 http://localhost:8000/?acs
    2. 应用程序 SAML 受众文本框中输入 http://localhost:8000/metadata/
  5. 选择提交
  6. 编译项目,访问 http://localhost:8000/

6. 验证

可以通过浏览器进行访问程序 login 路径进行测试:

程序正常跳转至 IdC 的登录 Portal:

输入账号,密码后,同时可以使用浏览器插件,进行 SAML 认证跟踪:

服务器端验证完 SAML 断言,跳转回程序欢迎页面:

总结

Amazon IAM Identity Center 已于 2023 年 11 月在中国区部署,本文基于 SAML 协议,为客户提供了一种快速便捷方法,完成 IdC 和企业自定义 web 应用集成,使用这个方法可以大大简化企业应用在身份认证模块的开发工作量,加速企业应用部署速度,欢迎大家使用更多亚马逊云科技服务,构建自己的企业应用。

本篇作者

余扬

亚马逊云科技安全解决方案架构师,负责为客户提供云上安全端到端整体解决方案;在身份认证管理,威胁检测,云安全防护等方面有丰富的经验。

李晶楠

亚马逊云科技解决方案架构师,目前负责零售电商行业云端应用的架构设计和开发。在成为解决方案架构师之前,在亚马逊从事近十年的软件前后端开发工作,涉及多领域,如大数据、Alexa、AWS service 开发等。