本页面介绍了如何启用和使用安全断言标记语言 (SAML) 属性传播。您可以使用此功能将 SAML 属性从身份提供方传播到受 Identity-Aware Proxy (IAP) 保护的应用。传播 SAML 属性时,您可以指定要传播的属性以及如何传递这些属性。
准备工作
您应熟悉 SAML V2.0 断言和协议规范 (PDF)。
了解数据处理方式
在启用 SAML 属性传播之前,请务必了解Google Cloud 如何管理数据,以及您应该和不应该通过此渠道传递哪些类型的信息。
您可以配置 IAP,使其在向受保护的应用提供的信息中包含一个或多个属性。如果您已通过第三方身份提供方设置单点登录,并且您的身份提供方在 SAML 断言中包含 <AttributeStatement>
,Google Cloud 会暂时存储与用户 Google 账号会话相关联的属性。当 Google 账号会话过期时,异步进程会在一周内永久移除相应信息。您可以配置到期日期。
请勿将 SAML 属性传播用于敏感的个人身份信息 (PII),例如账号凭据、政府身份证号码、持卡人数据、财务账号数据、医疗保健信息或敏感的背景信息。
启用 SAML 属性传播
通过在 Google Workspace 中创建 SSO 配置文件来启用 SAML 属性传播,然后使用 Google Cloud CLI 或 REST API 更新 IAP 设置。
控制台
- 在 Google Cloud 控制台中,前往 IAP 页面。
前往 IAP - 打开资源的设置,然后滚动到属性传播。
- 选择启用属性传播,然后点击保存。
在 SAML 属性标签页中,输入要传播的属性,格式如下:
attribute1, attribute2, attribute3
您还可以使用自定义表达式输入属性。自定义表达式的属性会显示在 SAML 属性标签页中。您必须使用以下表达式格式,才能在 SAML 属性标签页中显示属性:
attributes.saml_attributes.filter(attribute, attribute.name in ['attribute', 'attribute2', 'attribute1'])
对于要传递的凭据类型,请选择至少一种来自 IdP 且要传递给应用的属性格式。
gcloud
运行以下 IAP gcloud CLI 命令以更新 SAML 属性传播设置:
gcloud iap settings set SETTING_FILE [--folder=FOLDER --organization=ORGANIZATION --project=PROJECT> --resource-type=RESOURCE_TYPE --service=SERVICE --version=VERSION] [GCLOUD_WIDE_FLAG …]
替换以下内容:
- FOLDER:应用所在的文件夹。
- ORGANIZATION:应用所在的组织。
- PROJECT:应用所在的 Google Cloud 项目。
- RESOURCE_TYPE:资源类型。
- SERVICE:服务。
- VERSION:版本号。
YAML:
applicationSettings: attributePropagationSettings: expression: CEL_EXPRESSION outputCredentials: ARRAY[OUTPUT_CREDENTIALS] enable: BOOLEAN
JSON:
{ "application_settings":{ "attribute_propagation_settings": { "expression": CEL_EXPRESSION, "output_credentials": ARRAY[OUTPUT_CREDENTIALS] "enable": BOOLEAN } } }
REST API
您可以使用 IapSettings 中的 ApplicationSettings
对象配置要传播的 SAML 属性,如以下示例所示:
{ "csmSettings": { object (CsmSettings) }, "accessDeniedPageSettings": { object (AccessDeniedPageSettings) }, "attributePropagationSettings": { object (AttributePropagationSettings) }, "cookieDomain": string, }
AttributePropagationSettings
{ "expression": string, "output_credentials": array "enable": boolean }
设置输出凭据
使用 SAML 属性传播时,您可以通过设置输出凭据,跨多种媒介(包括 JSON Web 令牌 (JWT) 和标头)发送属性。如需在 API 中设置凭据,您可以指定一个以英文逗号分隔的字符串列表,如以下示例所示:
"output_credentials": ["HEADER", "JWT", "RCTOKEN"]
使用通用表达式语言过滤 SAML 特性
您可以使用通用表达式语言 (CEL) 函数来过滤 SAML 属性。
将 CEL 表达式与 SAML 属性传播结合使用时,存在以下限制:
- 表达式必须返回属性列表。
- 一个表达式最多可以选择 45 个属性。
- 表达式字符串不能超过 1,000 个字符。
以下是使用 IAP SAML 属性传播功能时支持的 CEL 函数。
请注意,这些函数区分大小写,必须完全按照所示方式使用。在链接函数调用时,strict
和 emitAs
函数的顺序无关紧要。
函数 | 示例 | 说明 |
---|---|---|
字段选择 | a.b |
从 proto a 中选择字段 b 。字符 b 可以是另一个 proto、列表或简单的值类型(例如字符串)。 |
过滤列表 | list.Filter(iter_var, condition) |
返回 list 的子集,其中包含满足 condition 的项。 |
列出会员资格 | b :a |
如果值 a 是列表 b 的成员,则返回 true 。 |
selectByName | list.selectByName("name") |
从列表中选择属性,其中 name = "name" 。 |
append | list.append(attribute) |
将指定属性附加到指定列表。 |
strict | attribute.strict() |
使用 HEADERS 作为输出凭据时,会发出不带 x-goog-iap-attr- 前缀的属性。 |
emitAs | attribute.emitAs("new_name") |
将具有名称 "new_name" 的指定属性输出到所有选定的输出凭据。 |
CEL 表达式示例
假设有一个 SAML 断言:
<saml2:AttributeStatement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<saml2:Attribute Name="my_saml_attr_1">
<saml2:AttributeValue xsi:type="xsd:string">value_1</saml2:AttributeValue>
<saml2:AttributeValue xsi:type="xsd:string">value_2</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="my_saml_attr_2">
<saml2:AttributeValue xsi:type="xsd:string">value_3</saml2:AttributeValue>
<saml2:AttributeValue xsi:type="xsd:string">value_4</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="my_saml_attr_3">
<saml2:AttributeValue xsi:type="xsd:string">value_5</saml2:AttributeValue>
<saml2:AttributeValue xsi:type="xsd:string">value_6</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
如需选择 my_saml_attr_1
,请使用以下 CEL 表达式:
attributes.saml_attributes.filter(attribute, attribute.name in ["my_saml_attr_1"])
如需选择 my_saml_attr_1
和 my_saml_attr_2
,请使用以下 CEL 表达式:
attributes.saml_attributes.filter(attribute, attribute.name in ["my_saml_attr_1", "my_saml_attr_2"])
属性格式
所有选定属性都会完全复制到所有选定输出凭据中。
示例:假设 SAML 断言
<saml2:AttributeStatement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<saml2:Attribute Name="my_saml_attr_1">
<saml2:AttributeValue xsi:type="xsd:string">value_1</saml2:AttributeValue>
<saml2:AttributeValue xsi:type="xsd:string">value_2</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
JWT 和 RC 令牌
JWT 令牌通过 additional_claims
字段提供属性。该字段是一个对象,包含属性名称到属性值列表的映射。属性名称与提供的 SAML 断言中的名称相同。
对于示例 SAML 断言,IAP JWT 包含以下内容:
{
"additional_claims": {
"my_saml_attr_1": ["value_1", "value_2"]
}
}
SAML 断言中的标头
在标头中,属性、键和名称的值会根据 RFC 3986 进行网址转义,并以英文逗号连接。例如,header&name: header$value
会变为 x-goog-iap-attr-header%26name: header%24value
。
为了唯一标识 IAP 标头,每个标头都包含 IAP 前缀 x-goog-iap-attr-
。出于安全考虑,负载平衡器会移除所有带有前缀 x-goog-iap-attr
的请求标头。这样可确保应用收到的标头是由 IAP 生成的。
对于示例 SAML 断言,标头如下所示:
"x-goog-iap-attr-my_saml_attr_1": "value_1,value_2"
以下示例演示了 IAP 在标头中传播属性时如何转义特殊字符,例如 value&1
、value$2
和 value,3
:
"x-goog-iap-attr-my_saml_attr_1": "value%261,value%242,value%2C3"
以下示例展示了如何转义标头名称。
标头名称:
"iap,test,3": "iap_test3_value1,iap_test3_value2"
转义后的标头名称:
"X-Goog-IAP-Attr-iap%2Ctest%2C3": "iap_test3_value1,iap_test3_value2"
自定义属性
您可以使用 selectByName
、append
、strict
和 emitas
函数来修改传播的属性名称,指定是否为某些属性使用标头前缀,以及选择新的 IAP 提供的属性。
如果您不需要 SAML 属性传播,但需要在 SM_USER 字段中使用电子邮件地址、设备 ID 或时间戳,则可以从 iap_attributes list
中选择这些属性:attributes.iap_attributes
…
IAP 提供以下属性:user_email
、device_id
和 timestamp
。
示例
以下示例展示了如何使用 selectByName
、append
、strict
和 emitas
函数来自定义属性。
假设存在示例 SAML 断言。
selectByName
使用 selectByName
函数按名称从给定列表中选择单个属性。例如,如需选择 my_saml_attr_1
,请使用以下表达式:
attributes.saml_attributes.selectByName("my_saml_attr_1")
append
使用 append
函数将属性附加到属性列表。您必须从受支持的 IAP 属性列表中选择此属性。例如,如需将 my_saml_attr_2
附加到包含 my_saml_attr_1
的列表,请使用以下表达式:
attributes.saml_attributes.filter(x, x.name in ["my_saml_attr_1"]).append(attributes.saml_attributes.selectByName("my_saml_attr_2"))
您可以将 "my_saml_attr_2"
添加到过滤条件列表中。您还可以添加多个属性,并通过串联追加操作将它们附加到列表中,如下所示:
attributes.saml_attributes.filter(x, x.name in ["my_saml_attr_1"]).append(
attributes.saml_attributes.selectByName("my_saml_attr_2")).append(
attributes.saml_attributes.selectByName("my_saml_attr_3"))
在与 strict
和 emitAs
功能结合使用时,附加单个属性最为有用。
strict
使用 strict
函数标记属性,以便 IAP 不在名称前添加 x-goog-iap-attr-
前缀。当属性名称必须与后端应用完全一致时,此方法非常有用。示例:
attributes.saml_attributes.selectByName("my_saml_attr_1").strict()
emitAs
使用 emitAs
函数可为属性指定新名称。您指定的名称将输出到所有凭据。例如,如需将 my_saml_attr_1
重命名为 custom_name
,请使用以下表达式:
attributes.saml_attributes.selectByName("my_saml_attr_1").emitAs("custom_name")
您可以使用各种函数来针对特定使用情形自定义属性。例如,您可以使用以下表达式将用户的电子邮件从 IAP 属性传播为 "SM_USER"
,以及其他 SAML 属性:
attributes.saml_attributes.filter(x, x.name in ["my_saml_attr_1"]).append(
attributes.iap_attributes.selectByName("user_email").emitAs("SM_USER").strict())
输出标题如下所示:
"x-goog-iap-attr-my_saml_attr_1": "value_1,value_2"
"SM_USER": "email@domain.com"
使用 SAML 属性传播时的限制
在登录时,来自身份提供方的传入属性的 SAML 属性数据大小上限为 2 KB。如果断言超过 2 KB 的上限,系统会拒绝该断言,并导致登录失败。
大多数 Web 服务器的请求大小限制为 8 KB。这会限制传出自定义属性的大小,包括标头中的重复属性。如果属性(名称加值)的大小在复制和编码后超过 5000 字节,IAP 会拒绝相应请求并返回 IAP 错误代码 401。
SAML 属性传播中的 Unicode 字符
此功能不支持 Unicode 和 UTF-8 字符,因此属性值必须是低 ASCII 字符串。如果断言不是低 ASCII,登录会失败。