跳转到内容
搜索文档

通用 SAML 应用程序

最后更新 查看 MarkdownAgent 设置

本页面提供了使用 SAML 身份验证协议在 Cloudflare Access 中设置 SaaS 应用程序的通用说明。

前提条件

  • 在 Cloudflare One 中配置的身份提供商
  • 对 SaaS 应用程序账户的管理员访问权限

1. 获取 SaaS 应用程序 URL

从您的 SaaS 应用程序账户中获取以下 URL:

  • Entity ID(实体 ID):为您的 SaaS 应用程序签发的唯一 URL,例如 https://<your-domain>.my.salesforce.com
  • Assertion Consumer Service URL(断言使用者服务 URL):服务提供商用于接收和解析 SAML 断言的端点。

2. 将您的应用程序添加到 Access

  1. Cloudflare 仪表板中,转到 Zero Trust > Access controls(访问控制)> Applications(应用程序)

  2. 选择 Create new application(创建新应用程序)

  3. 选择 SaaS application(SaaS 应用程序)

  4. 从下拉菜单中选择您的 Application(应用程序)。如果您的应用程序未列出,请在 Application(应用程序) 字段中输入自定义名称,并选择下方出现的文本框。

  5. 选择 SAML

  6. 选择 Add application(添加应用程序)

  7. 输入从您的 SaaS 应用程序账户中获取的 **Entity ID(实体 ID)**和 Assertion Consumer Service URL(断言使用者服务 URL)

  8. 选择您的 SaaS 应用程序所预期的 Name ID format(名称 ID 格式)(通常是 Email

  9. (可选)配置您的 SaaS 应用程序所需的任何其他 SAML 属性声明

  10. 复制 SSO endpoint(SSO 端点)、**Access Entity ID or Issuer(Access 实体 ID 或签发者)**和 Public key(公钥)

  1. Access policies 下,添加现有策略或创建新策略,以控制哪些用户可以连接到您的应用程序。所有 Access 应用程序默认均为拒绝状态——用户必须匹配 Allow 策略才能被授予访问权限。

  2. 配置用户的身份验证方式:

    1. 选择您希望为应用程序启用的身份提供商

    2. (推荐)如果您计划仅允许通过单一 IdP 进行访问,请开启 Apply instant authentication。最终用户将不会看到 Cloudflare Access 登录页面,Cloudflare 将直接将用户重定向到您的 SSO 登录事件。

    3. (可选)开启 Authenticate with Cloudflare One Client,允许用户使用其 Cloudflare One Client 会话身份对应用程序进行身份验证。
  3. (可选)转到 **Additional settings(其他设置)**以自定义应用程序体验:

    • App Launcher customization(应用启动器自定义):配置此应用程序在应用启动器中对用户的显示方式。
    • 自定义拦截页面:选择用户被拒绝访问应用程序时将看到的内容。

      • Cloudflare default(Cloudflare 默认):重新加载登录页面,并在 Cloudflare Access 徽标下方显示拦截消息。默认消息为 That account does not have access,您也可以输入自定义消息。
      • Redirect URL(重定向 URL):重定向到指定网站。
      • Custom page template(自定义页面模板):显示托管在 Cloudflare One 中的自定义拦截页面
  4. 选择 Create(创建)

3. 在您的 SaaS 应用程序中配置 SSO

接下来,配置您的 SaaS 应用程序以要求用户通过 Cloudflare Access 进行登录。有关如何配置第三方 SAML SSO 提供商的说明,请参阅您的 SaaS 应用程序文档。您将需要来自 Cloudflare One 的以下值:

  • SSO endpoint(SSO 端点)
  • Access Entity ID or Issuer(Access 实体 ID 或签发者)
  • Public key(公钥)

您可以手动将此数据输入到您的 SaaS 应用程序中,也可以上传元数据 XML 文件。元数据位于以下 URL:<SSO endpoint>/saml-metadata

验证 SAML 响应

当充当 SAML 身份提供商时,Cloudflare 将使用 SHA-256 算法对 SAML Response 和 SAML Assertion 进行签名。SaaS 应用程序可以使用您上传到 SaaS 应用程序的 **Public key(公钥)**来验证该签名。

4. 测试集成

打开无痕/隐私浏览器窗口,并转到 SaaS 应用程序的登录 URL。您将被重定向到 Cloudflare Access 登录页面,并被提示使用您的身份提供商进行登录。

SAML 属性

SAML 属性是指在成功身份验证后,Cloudflare Access 与您的 SAML SaaS 应用程序共享的用户身份特征。默认情况下,Cloudflare Access 会向 SaaS 应用程序传递以下属性(如果可用):

  • id - 用户的 Access 身份的 UUID
  • name - 用户的全名(例如,John Doe
  • email - 用户的电子邮件地址
  • groups - 身份提供商的组成员身份

在 Access for SaaS 中,您可以添加其他 SAML 属性或自定义发送给 SaaS 应用程序的 SAML 声明。这允许您集成具有特定 SAML 属性要求的 SaaS 应用程序。

SAML 属性声明

要向您的 SaaS 应用程序发送其他 SAML 属性,请为每个属性配置以下字段:

  • Name(名称):SAML 属性名称
  • SAML friendly name(SAML 友好名称):(可选)SAML 属性的人类可读名称
  • Name format(名称格式):指定 SaaS 应用程序预期的 **Name(名称)**格式:
    • Unspecified:(默认)不需要特定格式。
    • URI:名称采用诸如 urn:ietf:params:scim:schemas:core:2.0:User:userNameurn:oid:2.5.4.42 的格式。
    • Basic:名称是普通字符串,例如 userName
  • IdP claim(IdP 声明):应该映射到此 SAML 属性的身份提供商值。您可以选择在 Cloudflare One IdP 集成中配置的任何 SAML 属性OIDC 声明
  • Required(必需):如果某个属性被标记为必需,但 IdP 未提供,Cloudflare 将导致身份验证请求失败并显示错误页面。
  • Add per IdP claim(按 IdP 声明添加):(可选)如果您为该 SaaS 应用程序启用了多个身份提供商,您可以为每个 IdP 选择不同的属性映射。这些值将覆盖父级 IdP claim(IdP 声明)

JSONata 属性转换

Advanced settings(高级设置)> **Transformation(转换)**中,您可以输入一个 JSONata 脚本来修改 User Registry identity(用户注册表身份)的副本。这对于设置默认值、排除电子邮件地址或确保用户名符合任意标准非常有用。Access 将把修改后的用户身份作为 SAML 属性发送给 SaaS 应用程序。

这对应于 Access 应用程序 API 中的 saml_attribute_transform_jsonata 字段。

例如,以下 JSONata 脚本将组名合并到一个列表中,并添加一个映射到用户电子邮件的 eduPersonPrincipalName 字段。

JSONata 表达式txt
$merge([$, {"groups": groups.name, 'eduPersonPrincipalName': email}])

以下是应用 JSONata 转换前用户身份的示例:

应用 JSONata 转换前用户身份json
{
  "account_id": "699d98642c564d2e855e9661899b7252",
  "amr": [
    "pwd"
  ],
  "auth_status": "NONE",
  "common_name": "",
  "device_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "device_sessions": {
    "49e653db-991e-11ee-af26-2243bf8c3428": {
      "last_authenticated": 1703004275
    }
  },
  "devicePosture": {
    "8534a230-e85e-4183-8964-a4b7dcf72986": {
      "rule_name": "Warp",
      "success": true,
      "type": "warp"
    }
  },
  "email": "[email protected]",
  "gateway_account_id": "bTSquyUGwLQjYJn8cI8S1h6M6wU",
  "geo": {
    "country": "US"
  },
  "groups": [
    {
      "id": "12fdf91a-fb23-41b3-995a-de2f72c61d0e",
      "name": "IdentityProtection-RiskyUser-RiskLevel-low"
    },
    {
      "id": "12348f47-8234-4860-a03f-c2a1513f267b",
      "name": "Global Administrator"
    },
    {
      "id": "11235980-87d7-4917-b0aa-74c01914c40e",
      "name": "Application Administrator"
    }
  ],
  "iat": 1659474397,
  "id": "OidHvkPt-I-13IBSnd77UJ8cHgsrUpjs3W6_4t6ES7M",
  "idp": {
    "id": "b08e8c0c-a75d-4b3f-8e7b-cd427b7c7b47",
    "type": "azureAD"
  }
}

应用示例 JSONata 脚本后的结果:

{
  "account_id": "699d98642c564d2e855e9661899b7252",
  "amr": [
    "pwd"
  ],
  "auth_status": "NONE",
  "common_name": "",
  "device_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "device_sessions": {
    "49e653db-991e-11ee-af26-2243bf8c3428": {
      "last_authenticated": 1703004275
    }
  },
  "devicePosture": {
    "8534a230-e85e-4183-8964-a4b7dcf72986": {
      "rule_name": "Warp",
      "success": true,
      "type": "warp"
    }
  },
  "email": "[email protected]",
  "gateway_account_id": "bTSquyUGwLQjYJn8cI8S1h6M6wU",
  "geo": {
    "country": "US"
  },
  "groups": [
    "IdentityProtection-RiskyUser-RiskLevel-low",
    "Global Administrator",
    "Application Administrator"
  ],
  "iat": 1659474397,
  "id": "OidHvkPt-I-13IBSnd77UJ8cHgsrUpjs3W6_4t6ES7M",
  "idp": {
    "id": "b08e8c0c-a75d-4b3f-8e7b-cd427b7c7b47",
    "type": "azureAD"
  },
  "eduPersonPrincipalName": "[email protected]"
}

有关更多 JSONata 转换用例,请参阅以下示例。

删除 groups 属性

以下 JSONata 脚本删除 groups SAML 属性。如果您的 SaaS 应用程序不需要接收用户组信息,这会很有用。

JSONata 表达式txt
$ ~> |$|{}, ['groups']|

应用 JSONata 转换后的结果:

{
  "account_id": "699d98642c564d2e855e9661899b7252",
  "amr": [
    "pwd"
  ],
  "auth_status": "NONE",
  "common_name": "",
  "device_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "device_sessions": {
    "49e653db-991e-11ee-af26-2243bf8c3428": {
      "last_authenticated": 1703004275
    }
  },
  "devicePosture": {
    "8534a230-e85e-4183-8964-a4b7dcf72986": {
      "rule_name": "Warp",
      "success": true,
      "type": "warp"
    }
  },
  "email": "[email protected]",
  "gateway_account_id": "bTSquyUGwLQjYJn8cI8S1h6M6wU",
  "geo": {
    "country": "US"
  },
  "iat": 1659474397,
  "id": "OidHvkPt-I-13IBSnd77UJ8cHgsrUpjs3W6_4t6ES7M",
  "idp": {
    "id": "b08e8c0c-a75d-4b3f-8e7b-cd427b7c7b47",
    "type": "azureAD"
  }
}

重命名 groups 字段并删除组 ID

以下 JSONata 脚本将 groups.name 字段从 name 更改为 group_name,并删除 groups.id 字段:

JSONata 表达式txt
{
  "account_id": account_id,
  "amr": amr,
  "auth_status": auth_status,
  "common_name": common_name,
  "devicePosture": devicePosture,
  "device_id": device_id,
  "device_sessions": device_sessions,
  "email": email,
  "gateway_account_id": gateway_account_id,
  "geo": geo,
	"groups": $map($.groups, function($group) {
    {"group_name": $group.name}}),
  "iat": iat,
  "id": id,
  "idp": idp
}

应用 JSONata 转换后的结果:

{
  "account_id": "699d98642c564d2e855e9661899b7252",
  "amr": [
    "pwd"
  ],
  "auth_status": "NONE",
  "common_name": "",
  "devicePosture": {
    "8534a230-e85e-4183-8964-a4b7dcf72986": {
      "rule_name": "Warp",
      "success": true,
      "type": "warp"
    }
  },
  "device_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "device_sessions": {
    "49e653db-991e-11ee-af26-2210bf8c3428": {
      "last_authenticated": 1703004275
    }
  },
  "email": "[email protected]",
  "gateway_account_id": "bTSquyUGwLQjYJn8cI8S1h6M6wU",
  "geo": {
    "country": "US"
  },
  "groups": [
    {
      "group_name": "IdentityProtection-RiskyUser-RiskLevel-low"
    },
    {
      "group_name": "Global Administrator"
    },
    {
      "group_name": "Application Administrator"
    }
  ],
  "iat": 1659474397,
  "id": "OidHvkPt-I-13IBSnd77UJ8cHgsrUpjs3W6_4t6ES7M",
  "idp": {
    "id": "b08e8c0c-a75d-4b3f-8e7b-cd427b7c7b47",
    "type": "azureAD"
  }
}

按名称过滤组

以下 JSONata 脚本将组过滤为与正则表达式匹配的组。

JSONata 表达式txt
$merge([$, { "groups": $filter(groups, function($v) { $contains($v.name, /Administrator/) }) }])

应用 JSONata 转换后的结果:

{
  "account_id": "699d98642c564d2e855e9661899b7252",
  "amr": [
    "pwd"
  ],
  "auth_status": "NONE",
  "common_name": "",
  "device_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "device_sessions": {
    "49e653db-991e-11ee-af26-2243bf8c3428": {
      "last_authenticated": 1703004275
    }
  },
  "devicePosture": {
    "8534a230-e85e-4183-8964-a4b7dcf72986": {
      "rule_name": "Warp",
      "success": true,
      "type": "warp"
    }
  },
  "email": "[email protected]",
  "gateway_account_id": "bTSquyUGwLQjYJn8cI8S1h6M6wU",
  "geo": {
    "country": "US"
  },
  "groups": [
    {
      "id": "12348f47-8234-4860-a03f-c2a1513f267b",
      "name": "Global Administrator"
    },
    {
      "id": "11235980-87d7-4917-b0aa-74c01914c40e",
      "name": "Application Administrator"
    }
  ],
  "iat": 1659474397,
  "id": "OidHvkPt-I-13IBSnd77UJ8cHgsrUpjs3W6_4t6ES7M",
  "idp": {
    "id": "b08e8c0c-a75d-4b3f-8e7b-cd427b7c7b47",
    "type": "azureAD"
  }
}

NameID 转换

默认情况下,Access 将用户的电子邮件地址作为 SAML NameID 发送。某些 SaaS 应用程序需要不同的值,例如员工 ID、修改后的电子邮件地址或来自旧系统的用户名。

您可以通过 Access 应用程序 API,在 SaaS 应用程序上设置 name_id_transform_jsonata 字段来自定义 NameID。该字段接受针对用户身份进行评估的 JSONata 表达式,并且必须返回单个字符串值。该结果将替换 SAML 断言中的默认 NameID

例如,修改用户的电子邮件使其包含 +sandbox 后缀(当连接同一 SaaS 应用的多个实例时很有用):

通过 API 设置 NameID 转换bash
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/apps/{app_id} \
--header "Authorization: Bearer {api_token}" \
--header "Content-Type: application/json" \
--data '{
  "saas_app": {
    "auth_type": "saml",
    "name_id_transform_jsonata": "$substringBefore(email, '\''@'\'') & '\''+sandbox@'\'' & $substringAfter(email, '\''@'\'')"
  }
}'

对于电子邮件为 [email protected] 的用户,此表达式产生的 NameID[email protected]

使用员工 ID 作为 NameID

要发送非电子邮件属性(例如员工 ID),请在 JSONata 表达式中直接引用该属性名称。该属性必须在来自 IdP 的用户身份中可用。

将 employee_id 设置为 NameIDbash
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/apps/{app_id} \
--header "Authorization: Bearer {api_token}" \
--header "Content-Type: application/json" \
--data '{
  "saas_app": {
    "auth_type": "saml",
    "name_id_transform_jsonata": "employee_id"
  }
}'

对于包含 "employee_id": "efgh5678" 的用户身份,在 SAML 断言中发送的 NameID 将是 efgh5678

删除 NameID 转换

要恢复到默认行为(将用户的电子邮件作为 NameID 发送),请将该字段设置为空字符串:

删除 NameID 转换bash
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/apps/{app_id} \
--header "Authorization: Bearer {api_token}" \
--header "Content-Type: application/json" \
--data '{
  "saas_app": {
    "auth_type": "saml",
    "name_id_transform_jsonata": ""
  }
}'

这篇文档对您有帮助吗?