高级概念

思杰网关 和 微软 Azure 多重身份验证

Citrix Gateway 将所有托管的 SaaS、Web、企业和移动应用程序呈现给任何设备和任何浏览器上的用户。它使用 nFactor 身份验证针对本地 Microsoft AD 对用户进行身份验证,并利用 Microsoft AD FS 进行 Azure 多重身份验证 (MFA)。

思杰网关

Citrix Gateway 为用户提供一个访问点和单点登录 (SSO),以访问部署在数据中心和云中的业务应用程序和数据。它以 SaaS 形式通过各种设备(笔记本电脑、台式机、瘦客户端、平板电脑和智能手机)交付。Citrix Gateway 实现了整合,有助于减少远程访问基础设施的占用空间,降低成本,并提供易于管理和更好的最终用户体验。Citrix Gateway 有助于 IT 部门向混合云和 SaaS 环境过渡。

  • 联合和单点登录

Citrix Gateway 提供联合身份,并支持 SAML 2.0、OAuth 和 OpenID,以实现所有应用程序(无论是 Web、VDI、企业还是 SaaS 应用程序)的单点登录。

  • 本地用户目录

Citrix Gateway 为 Office 365 和 Salesforce 等 SaaS 应用程序提供 SSO,并将其用户目录保留在本地。它可以作为 IdP 或代理,用于微软活动目录联合身份验证服务 (AD FS)。

  • 多重 (nFactor) 身份验证

Citrix Gateway 提供 nFactor 身份验证机制,并允许对谁访问网络、访问什么以及如何和何时访问进行精细控制。它支持所有身份验证机制,例如 RADIUS、TACACS、NTLM、Diameter、SAML 2.0、OAuth 2.0 和 OpenID 2.0。

  • 上下文访问控制策略

Citrix Gateway 允许根据最终用户设备、用户、用户位置和其他数据的状态对业务应用程序进行精细访问控制。IT 管理员可以创建、管理和实施策略,以在应用程序环境中安全地访问数据。这些策略可以应用于 VDI、Web、移动、企业和 SaaS 应用程序。

  • 可见性和监控

Citrix Application Delivery Management 包含 Gateway Insight,它提供通过 Citrix Gateway 访问的所有应用程序的端到端用户体验可见性。它为应用程序支持团队提供信息,以排查身份验证失败(包括 EPA 检查失败和单点登录失败)相关问题。

应用程序

支持的应用

微软 Azure 多重身份验证

人们正在以日益复杂的场景连接到组织资源。人们使用智能手机、平板电脑、PC 和笔记本电脑,通常在多个平台上,从组织拥有的、个人和公共设备连接到公司网络内外。在这个始终连接、多设备、多平台的世界中,用户帐户的安全性比以往任何时候都更加重要。密码,无论其复杂程度如何,在设备、网络和平台之间使用时,已不足以确保用户帐户的安全性,尤其是在用户倾向于跨帐户重复使用密码的情况下。复杂的网络钓鱼和其他社会工程攻击可能导致用户名和密码在暗网中被发布和出售。

两步验证过程的安全性在于其分层方法。破坏多个身份验证因素对攻击者来说是一个重大挑战。即使攻击者设法获取了用户的密码,如果没有额外的身份验证方法,该密码也毫无用处。它通过要求以下两种或更多身份验证方法来工作:

  • 您知道的东西(通常是密码)
  • 您拥有的东西(不易复制的受信任设备,例如手机)
  • 您本身(生物识别)

Azure 多重身份验证有助于保护对数据和应用程序的访问。它使用第二种身份验证形式提供额外的安全层。组织可以使用条件访问来使解决方案适应其特定需求。

Microsoft Azure 多重身份验证部署方法

有多种方法可以将 Azure MFA 用作第二重身份验证。下面简要解释了这些方法的优缺点。

Azure 多重身份验证服务器

Microsoft Azure 多重身份验证服务器是最初的方法,它将被弃用。不应将其用于任何新的实施,因为

  • Microsoft 今后不会再对这种方法进行投资。
  • 它不与 SSPR 和基于云的 Azure MFA 集成。
  • 没有从 MFA 服务器到基于云的 MFA 解决方案的无缝迁移工具。

Azure MFA 网络策略服务器扩展

Azure MFA 的网络策略服务器 (NPS) 扩展是一种受支持的解决方案,它使用 NPS 适配器连接到基于云的 Azure MFA。它可以作为本地 RADIUS 服务器使用。

  • NPS 适配器 (RADIUS) 将提供网络位置,在 MFA 规则内部/外部或启用/禁用。
  • 它与 Azure AD 条件访问策略不兼容,类似于 SAML 集成方法。条件访问策略具有更丰富、更好的用户体验。
  • 用户在使用 NPS 适配器之前必须在 MFA 中注册。与基于云的 Azure MFA 和条件访问不同,如果用户未注册,则 NPS 扩展无法对用户进行身份验证,这会导致更多求助台呼叫。
  • 当 NPS 适配器调用 MFA 时,它会命中用户注册的默认选项。用户没有收到 MFA 已请求并即将到来的视觉通知。在门控过程中,用户没有用于更改 MFA 方法的 UI。如果用户没有随身携带其默认设备,则会失败。用户必须返回自助服务门户并重置默认选项,然后再次尝试连接。

Microsoft 活动目录联合身份验证服务和 Azure 多重身份验证

如果您的组织与 Azure AD 联合,但密码哈希未与 Azure AD 同步,则可以使用本地 AD 进行轻量级目录访问协议 (LDAP),并将 Azure MFA 作为 AD FS 依赖方上的访问策略的一部分启用。从 Windows Server 2016 开始,您现在可以为主要身份验证配置 Azure MFA。

  • Azure 多重身份验证适配器内置于 Windows Server 2016 中,无需额外安装。
  • Azure MFA 适配器直接与 Azure AD 集成,并且不需要本地 Azure MFA 服务器。
  • 如果用户未注册 MFA,他们将在下次登录时获得流程指导。这确保了更少的求助台呼叫和更好的用户流程。
  • 用户会收到 MFA 已请求并即将到来的视觉通知。用户可以在 UI 中的门控过程中更改网关选项。

Azure 活动目录和 Azure 多重身份验证

如果您的组织正在将密码哈希同步到 Azure AD,可以通过条件访问策略利用 Azure MFA 以要求用户进行第二因素身份验证。

  • 此方法不需要在本地进行任何额外的安装。
  • 如果用户未注册 MFA,他们将在下次登录时被引导完成该过程。这确保了对帮助台的呼叫减少,并为用户提供了更好的流程。
  • 用户会收到视觉通知,告知 MFA 是必需的且即将推出。用户可以在 UI 中受控过程中更改网关选项。

Azure AD 直通身份验证和 Azure 多重身份验证

Azure AD 直通身份验证 (PTA) 允许用户使用相同的密码登录本地和基于云的应用程序。当用户使用 Azure AD 登录时,此功能会直接根据本地 Active Directory 验证用户的密码。Azure AD PTA 是 Azure AD 密码哈希同步的替代方案,它为组织提供了相同的云身份验证优势。

  • Azure AD PTA 需要在本地安装一个轻量级代理。
  • Azure AD PTA 通过与 Azure AD 条件访问策略(包括 Azure MFA)无缝协作来保护用户帐户。
  • 用户可以在云中完成自助密码管理任务。
  • 本地密码绝不会以任何形式存储在云中。
  • 代理只从您的网络内部建立出站连接。因此,无需在边界网络(也称为 DMZ)中安装代理。

目前的状况

具有以下特征的环境需要利用 Azure MFA 作为第二重身份验证因素:

  • 已配置带有 Azure AD 同步的本地 AD。
  • Azure AD 密码哈希同步已禁用。
  • 需要访问 O365 应用程序。
  • 需要访问本地部署的 Citrix 虚拟应用和桌面™。
  • 访问使用现代身份验证方法(SAML、OAuth)的应用程序是必需的。
  • 访问使用传统身份验证方法的应用程序是必需的。

设计要点

以下是建议解决方案的设计要点:

  • 需要通过单个门户安全地访问托管、SaaS、企业和 Web 应用程序。
  • 用户在进行身份验证的过程中,只被要求输入一次他们的凭据。
  • 必须为所有托管、SaaS、企业和 Web 应用程序提供单点登录。

建议解决方案

概述

所提出的解决方案基于以下组件:

  • 本地 思杰网关
  • 本地 微软活动目录
  • 本地部署的 微软 AD FS
  • 本地部署的 思杰 ADC 作为 AD FS 代理
  • 微软 Azure 多重身份验证

Citrix Gateway 正在利用身份验证、授权和审计功能 (Citrix ADC AAA) 和 nFactor 身份验证机制,通过 LDAP 策略对用户进行身份验证,并利用 AD FS 中继方上的访问策略触发 Azure MFA 验证过程。在 Azure MFA 验证用户后,AD FS 会生成 SAML 断言(SAML 响应)并将用户重定向回 Citrix Gateway。此时,用户已通过身份验证,Citrix Gateway 会显示用户有权使用的所有应用程序。

该解决方案需要两个公共 DNS 记录和两个公共 IP 地址:

详细说明
思杰网关 完全限定域名 access.ctxdemos.com
Citrix 身份验证、授权和审计 FQDN aaa.ctxdemos.com

该解决方案使用一个公共 SSL 证书:

Description
通用名称 access.ctxdemos.com
主题备用名称 sts.ctxdemos.com
主题备用名称 aaa.ctxdemos.com

该解决方案还使用了由内部 Microsoft 证书颁发机构服务颁发的通配符 SSL 证书:

详细说明
通用名称 *.ctxdemos.com

身份验证流程

序列示意图

以下序列图显示了该解决方案的身份验证流程:

序列图

身份验证步骤

身份验证步骤如下:

  1. 用户导航到 https://access.ctxdemos.com
  2. Citrix Gateway 将用户重定向到第一个 Citrix ADC AAA 虚拟 IP 地址(不可寻址)。
  3. 第一个 Citrix ADC AAA VIP 使用无架构登录,该登录配置了单点登录。然后它开始处理高级身份验证策略。
  4. 第一个身份验证策略是 SAML SP 到一个不可寻址的 LB VIP,用于生成身份验证 Cookie。
  5. 辅助 LB VIP 配置为使用第二个 Citrix ADC AAA VIP(可寻址)进行身份验证。因此,它将用户重定向到第二个身份验证、授权和审计 VIP。
  6. 第二个 Citrix ADC AAA VIP 使用 Username Only 登录架构,该架构提示用户输入用户名。然后它开始处理高级身份验证策略。
  7. 第一个身份验证策略是组提取,它在本地 AD 中查询用户名并验证用户是否属于 AzureMFACAUsers 安全组。验证成功后,它开始处理下一个身份验证因素,即 LDAP 策略。
  8. LDAP 策略使用 UsernameAndPassword 登录架构和一个预填充的用户名字段,并提示用户输入 AD 密码。
  9. 当第二个 Citrix ADC AAA VIP 上的身份验证成功完成后,它返回到辅助 LB VIP,该 VIP 为第一个身份验证、授权和审计 VIP 生成 SAML 响应。
  10. 第一个 Citrix ADC AAA VIP 开始处理下一个因素,即组提取,以确保用户的组从 AD 中提取并存储在身份验证、授权和审计变量中,以便在后续过程中使用。
  11. 第一个 Citrix ADC AAA 虚拟 IP 地址开始处理下一个因素,即 Citrix ADC 上的 SAML SP 到 AD FS 代理虚拟 IP 地址。

    注意:

    Citrix ADC 与 AD FS 场联合。详细步骤将在后续章节中解释。

  12. AD FS 代理 VIP 验证身份验证 Cookie (NSC_TMAA 和 NSC_TMAS) 是否已设置。然后它将 SAML 请求发送到后端 AD FS 服务器(后端 AD FS 服务器应在内部 Citrix ADC 上进行负载均衡,以实现服务的高可用性和弹性)。
  13. AD FS 服务器处理 SAML 请求。由于信赖方上的访问策略设置为“允许所有用户并要求 MFA 进行身份验证”,因此它会触发 Azure MFA 身份验证过程。
  14. Azure MFA 处理用户名。如果已注册,它会使用配置的方法向用户发起质询。如果未注册,它会提示用户注册并设置主要和辅助身份验证方法。
  15. Azure 多重身份验证过程成功完成后,AD FS 会为 Citrix 网关(第一个 Citrix ADC AAA 虚拟 IP)生成 SAML 响应。
  16. 第一个 Citrix ADC AAA VIP 接收 SAML 响应,并确认用户的身份验证过程已完成。
  17. Citrix Gateway 将身份验证信息发送到 Citrix StoreFront™,后者枚举用户有权使用的所有应用程序和桌面。此外,它还会处理用户的组成员身份,以在 Citrix Gateway 上显示已发布的书签。

身份验证屏幕

上述大多数步骤对用户来说是无缝的,因为它们在 Citrix ADC 上的各种 VIP 之间内部发生。用户体验如下所示:

Citrix Gateway 登录页面用户名 Citrix Gateway 登录页面用户名和密码 验证码

实施方法

微软活动目录联合服务

证书配置要求

联合服务器需要满足下表所列的证书要求:

证书类型 详细说明 部署前需要了解的信息
安全套接字层 (SSL) 证书 这是一种标准的 Secure Sockets Layer (SSL) 证书,用于保护联合服务器和客户端之间的通信。 此证书必须绑定到联合服务器或联合服务器代理的 Internet Information Services (IIS) 中的默认网站。对于联合服务器代理,必须在成功运行联合服务器代理配置向导之前在 IIS 中配置绑定。建议:由于此证书必须受 AD FS 客户端信任,因此请使用由公共(第三方)证书颁发机构 (CA) 颁发的服务器身份验证证书。例如,Verisign。提示:此证书的主题名称用于表示您部署的每个 AD FS 实例的联合服务名称。因此,您可能需要考虑在任何新的 CA 颁发证书上选择一个最能代表您的公司或组织名称的主题名称,以供合作伙伴使用。
用于服务通信的证书 此证书启用 WCF 消息安全,以保护联合服务器之间的通信。 默认情况下,SSL 证书用作服务通信证书。可以使用 AD FS 管理控制台更改此设置。
用于令牌签名的证书 这是一个标准的 X509 证书,用于安全地签署联合服务器颁发的所有令牌。 令牌签名证书必须包含私钥,并且应链接到联合服务中的受信任根。默认情况下,AD FS 会创建一个自签名证书。但是,您可以根据组织的需要,稍后使用 AD FS 管理单元将其更改为 CA 颁发的证书。
用于令牌解密的证书 这是一个标准的 SSL 证书,用于解密由合作伙伴联合服务器加密的任何传入令牌。它也发布在联合元数据中。 默认情况下,AD FS 会创建一个自签名证书。但是,您可以根据组织的需要,稍后使用 AD FS 管理单元将其更改为 CA 颁发的证书。

演示环境配置说明

证书类型 演示环境配置说明
安全套接字层 (SSL) 证书 由 AD FS 服务器上的内部颁发 CA 颁发的内部证书。Citrix ADC 上的公共受信任证书。
用于服务通信的证书 由 AHS 内部颁发证书颁发机构颁发的内部证书。
用于令牌签名的证书 由 AD FS 服务自动生成。
用于令牌解密的证书 由 AD FS 服务自动生成。

在演示环境中,通配符证书已注册并安装在服务器上。

证书颁发机构(/zh-cn/advanced-concepts/media/wildcard-certificate-issued-by-internal-certificate-authority.png)

服务账户的各项要求

您可以创建服务账户,也可以利用组托管服务账户 (gMSA)。要使用 gMSA,您需要创建密钥分发服务根密钥。因此,启动 PowerShell 并运行以下命令:

Add-KdsRootKey -EffectiveTime ((get-date).addhours(-10))
<!--NeedCopy-->

此命令创建存储在 Active Directory 中的密钥分发服务根密钥,它允许您创建组托管服务账户 (gMSA) 作为您稍后创建的 AD FS 服务账户。请使用域管理员权限运行此命令。

根密钥(/zh-cn/advanced-concepts/media/create-key-distribution-service-root-key-for-gmsa.png)

DNS 记录要求

您需要为您的 AD FS 联合服务名称提供内部和外部的 DNS A 记录。在演示环境中,内部 DNS 记录指向 AD FS 服务器 IP,外部 DNS 记录指向 Citrix Gateway 公共 IP。

记录名称 范围 类型 IP 地址
sts.ctxdemox.com 内部 A 22.22.22.6
sts.ctxdemox.com 外部 A 40.85.225.175

添加 AD FS 角色并配置 AD FS 场

添加 AD FS 角色

To add the AD FS role to Windows Server 2016 launch PowerShell and run the following command:

Install-WindowsFeature AD FS-Federation -IncludeManagementTools
<!--NeedCopy-->

PowerShell command

配置 AD FS 场

现在您可以从服务器管理器开始 AD FS 部署后配置。单击“在此服务器上配置联合身份验证服务”。

部署后配置

在“欢迎”页面上,选择“在联合身份验证服务器场中创建第一个联合身份验证服务器”,然后单击“下一步”。

创建第一个联合身份验证服务器

在“连接到 Active Directory 域服务”页面上,确保指定了域管理员帐户,然后单击“下一步”。

连接到 活动目录 域服务

在“指定服务属性”页面上,完成以下步骤,然后单击“下一步”:

  • 选择在先前步骤中已安装到服务器上的证书。
  • 联合身份验证服务名称将根据证书的主题名称自动进行填充。
  • 输入联合身份验证服务的显示名称。例如,CTXDEMOS STS

指定服务属性

在“指定服务帐户”页面上,选择“创建组托管服务帐户”,并为此帐户输入一个唯一的名称。组托管服务帐户在 Windows Server 2012 及更高版本中受支持,并附带严格、复杂的密码,这些密码每 30 天自动更改一次。单击“下一步”。

创建组托管服务帐户

在“指定配置数据库”页面上,选择指定 SQL Server 数据库的位置。单击“下一步”。

指定配置数据库

在“审查选项”页面上,验证您的配置选择,然后单击“下一步”。

审查选项

在“先决条件检查”页面上,验证所有先决条件检查均已成功完成,然后单击“配置”。

先决条件检查

在“结果”页面上,确保安装成功。单击“关闭”以退出向导。

部署后配置结果

注意:

要完成以下步骤,您将需要您的 Azure 租户 ID。

您可以通过遵循 Microsoft 文档文章中的步骤获取 Azure 租户 ID,获取 AzureID 租户详细信息

微软文档也提供了有关 Azure MFA 客户端 GUID 的信息,请参阅 配置 AD FS 2016 和 Azure MFA

配置 AD FS 场 - 自动化

您可以运行以下 PowerShell 脚本:

#
# Windows PowerShell script for AD FS Deployment
#
Import-Module ADFS
Install-AdfsFarm `
-CertificateThumbprint:"BD02F30D90A96EEE4A5934F2EA979E7A052584AE" `
-FederationServiceDisplayName:"CTXDEMOS STS" `
-FederationServiceName:"adfs.ctxdemos.com" `
-GroupServiceAccountIdentifier:"C
<!--NeedCopy-->

配置 AD FS 与 Azure 多重身份验证

配置 AD FS 服务器

在您的每个 AD FS 服务器上,启动 PowerShell 并运行以下命令:

# Install Windows PowerShell MSOnline Module
Install-Module MSOnline

# Import Windows PowerShell MSOnline Module
Import-Module MSOnline

# Get the Azure Global Administrator credential
$credential = Get-Credential

# Sign in to your Azure Active Directory environment
Connect-MsolService -Credential $credential

# Set a variable for the Azure Tenant name
$azureTenantID = "ctxdemos.onmicrosoft.com"

# Set a variable for the Azure MFA Client GUID
$azureMFAClientGUID = "981f26a1-7f43-403b-a875-f8b09b8cd720"

# Generate a certificate for the Azure MFA on AD FS server
$azureMFACertificate = New-AdfsAzureMfaTenantCertificate -TenantId $azureTenantID

# Add the new credentials to the Azure MFA Client Service Principal
New-MsolServicePrincipalCredential -AppPrincipalId $azureMFAClientGUID -Type asymmetric -Usage verify -
Value $azureMFACertificate
<!--NeedCopy-->

配置 AD FS 场

仅在其中一台 AD FS 服务器上,运行以下命令:

Set-AdfsAzureMfaTenant -TenantId $azureTenantID -ClientId $azureMFAClientGUID
<!--NeedCopy-->

在每台服务器上重新启动 AD FS 服务。然后您将看到 Azure MFA 可用作内部网和外部网使用的主要和多重身份验证方法。

主要身份验证方法

多重身份验证方法

配置 AD FS 与 Citrix 应用交付控制器

您需要在 AD FS 和 Citrix ADC 之间创建联合信任。在 AD FS 管理控制台中,导航到 信赖方信任 并选择 添加信赖方信任

添加信赖方信任

选择 手动输入有关信赖方的数据 并单击 下一步

输入有关信赖方的数据

输入描述性显示名称和可选备注。单击 下一步

可选备注

单击 下一步

配置证书

选择 启用对 SAML 2.0 WebSSO 协议的支持 并输入 https://CitrixGatewayFQDN/cgi/samlauth。在演示环境中,它是 https://access.ctxdemos.com/cgi/samlauth。单击 下一步

配置网址

为信赖方信任输入一个唯一的标识符字符串。在演示环境中,它是 https://access.ctxdemos.com。此标识符将用作 Citrix ADC SAML 配置文件中的颁发者 URL。单击“下一步”。

配置标识符(/zh-cn/advanced-concepts/media/adfs-add-relying-party-trust-configure-identifiers.png)

在“选择访问控制策略”页面上,选择“允许所有人并要求 MFA”。单击“下一步”。

访问控制策略(/zh-cn/advanced-concepts/media/adfs-add-relying-party-trust-choose-access-control-policy.png)

单击“下一步”。

添加信任(/zh-cn/advanced-concepts/media/adfs-add-relying-party-trust-ready-to-add-trust.png)

在“完成”页面上,选择“为此应用程序配置声明颁发策略”。单击“关闭”。

完成(/zh-cn/advanced-concepts/media/adfs-add-relying-party-trust-finish.png)

在“颁发转换规则”页面上,单击“添加规则”。

添加规则(/zh-cn/advanced-concepts/media/adfs-issuance-transform-rules-start.png)

单击“下一步”。

选择模板(/zh-cn/advanced-concepts/media/adfs-issuance-transform-rules-select-rule-template.png)

在“声明规则名称”字段中输入描述性名称。在“属性存储”下,选择“Active Directory”。然后选择以下项:“LDAP 属性”和“传出声明类型”。

配置规则(/zh-cn/advanced-concepts/media/adfs-issuance-transform-rules-configure-rule.png)

创建新规则,并使用发送使用自定义规则的声明作为声明规则模板。为声明规则名称输入一个描述性名称,并为自定义规则输入以下字符串:

=> issue(Type = "logoutURL", Value = "https://access.ctxdemos.com/cgi/tmlogout", Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");
<!--NeedCopy-->

配置规则

创建声明颁发策略后,单击确定

右键单击信赖方信任 > Citrix ADC,然后选择属性。选择端点并通过单击添加 SAML 以注销来添加端点。从端点类型列表中,选择SAML 注销。对于绑定,选择POST,对于受信任的 URL,输入 https://sts.ctxdemos.com/adfs/ls/?wa=wsignout1.0。这将作为从 Citrix ADC 注销时的注销 URL。单击确定

SAML 协议注销

右键单击信赖方信任 > Citrix ADC,然后选择属性。选择加密并添加安装在 Citrix Gateway 上的公共 SSL 证书。此证书将用于解密来自 Citrix ADC 的传入 SML 请求。在签名选项卡上重复相同的操作。此证书将用于检查传入 SAML 请求的签名。单击确定

启用 IdP 发起的登录页面

您可以启用 AD FS IdP 发起的登录页面。您将使用 IdP 发起的登录向未注册的 MFA 用户显示自定义错误页面。要启用,请运行以下命令:

Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
<!--NeedCopy-->

测试 AD FS 场

打开 Web 浏览器并导航到:

思杰 ADC 和 思杰 网关

配置 思杰网关

您可以通过向导配置 Citrix Gateway。登录到 Citrix ADC 管理 GUI,导航到 统一网关,然后单击 创建新网关。然后单击 继续

单一公共访问(/zh-cn/advanced-concepts/media/adfs-single-public-access.png)

输入 统一网关 的名称、IP 和 FQDN,然后单击 继续

思杰网关配置(/zh-cn/advanced-concepts/media/adfs-gateway-configuration.png)

选择公共 SSL 证书,然后单击 Continue

服务器证书(/zh-cn/advanced-concepts/media/adfs-server-certificate.png)

创建基本 LDAP 策略并将其绑定到 统一网关。单击 继续

身份验证(/zh-cn/advanced-concepts/media/adfs-authentication.png)

创建一个基于 RfWebUI 的门户主题并将其绑定到 Unified Gateway。单击 继续

门户主题(/zh-cn/advanced-concepts/media/adfs-portal-theme.png)

选择应用程序前面的加号 (+) 以将 Citrix Gateway 与 StoreFront 集成。

将 网关 与 StoreFront 进行集成(/zh-cn/advanced-concepts/media/adfs-applications.png)

将 思杰 StoreFront 集成到 思杰 网关 中

在“应用程序”页面上,选择 XenApp & XenDesktop®,然后从 选择集成点 列表中选择 StoreFront。单击 继续

选择多个设置(/zh-cn/advanced-concepts/media/adfs-storefront.png)

输入 StoreFront URL,然后点击 检索存储。接着输入 默认 Active Directory 域安全票证颁发机构 URL 设置。点击 测试 STA 连接,然后点击 继续

测试连接

点击 完成,然后点击 继续

继续

Configure Citrix Gateway and integrate with StoreFront – CLI

# Create Session Policy and Action for Citrix Receiver
add vpn sessionAction AC_OS_22.22.44.50 -transparentInterception OFF -defaultAuthorizationAction ALLOW -SSO ON -icaProxy ON -wihome "https://access.ctxdemos.com/Citrix/ExternalWeb" -ClientChoices OFF -ntDomain CTXDEMOS -clientlessVpnMode OFF -storefronturl "https://access.ctxdemos.com"
add vpn sessionPolicy PL_OS_22.22.44.50 "HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"CitrixReceiver\") && HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"CitrixVPN\").NOT && HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"NSGiOSplugin\").NOT" AC_OS_22.22.44.50

# Create Session Policy and Action for Citrix Web Client
add vpn sessionAction AC_WB_22.22.44.50 -transparentInterception ON -defaultAuthorizationAction ALLOW -forceCleanup cookie -SSO ON -ssoCredential PRIMARY -icaProxy OFF -wihome "https://storefront.ctxdemos.com/Citrix/ExternalWeb" -wiPortalMode COMPACT -ClientChoices OFF -ntDomain CTXDEMOS -clientlessVpnMode ON -clientlessPersistentCookie ALLOW
add vpn sessionPolicy PL_WB_22.22.44.50 "HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"CitrixReceiver\").NOT" AC_WB_22.22.44.50

# Create Session Policy and Action for Citrix Gateway Client
add vpn sessionAction UG_VPN_SAct_22.22.44.50 -transparentInterception ON -defaultAuthorizationAction ALLOW -SSO ON -ClientChoices ON -clientlessVpnMode ON
add vpn sessionPolicy UG_VPN_SPol_22.22.44.50 true UG_VPN_SAct_22.22.44.50

# Create Responder Policy and Action for Gateway Logout
add responder action RESACT_GATEWAY_LOGOFF_REDIRECT redirect "\"https://\" + HTTP.REQ.HOSTNAME.HTTP_URL_SAFE" -responseStatusCode 302
add responder policy RESPOL_GATEWAY_LOGOFF_REDIRECT "HTTP.REQ.URL.CONTAINS(\"/cgi/logout\")" RESACT_GATEWAY_LOGOFF_REDIRECT

# Create Citrix Gateway vServer
add vpn vserver UGVS_VPN_UGCTXDEMOS SSL 0.0.0.0 -loginOnce ON -Listenpolicy NONE -vserverFqdn access.ctxdemos.com
set ssl vserver UGVS_VPN_UGCTXDEMOS -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind ssl vserver UGVS_VPN_UGCTXDEMOS -certkeyName CTXDEMOS_PUBLIC_CERT
bind ssl vserver UGVS_VPN_UGCTXDEMOS -cipherName CTXDEMOS_FRONTEND_APLUS
bind vpn vserver UGVS_VPN_UGCTXDEMOS -portaltheme CTXDEMOS_PORTAL
bind vpn vserver UGVS_VPN_UGCTXDEMOS -staServer "https://wsctxdc01.ctxdemos.com"
bind vpn vserver UGVS_VPN_UGCTXDEMOS -policy RESPOL_GATEWAY_LOGOFF_REDIRECT -priority 100 -gotoPriorityExpression END -type REQUEST
bind vpn vserver UGVS_VPN_UGCTXDEMOS -policy PL_OS_22.22.44.50 -priority 100 -gotoPriorityExpression NEXT -type REQUEST
bind vpn vserver UGVS_VPN_UGCTXDEMOS -policy PL_WB_22.22.44.50 -priority 110 -gotoPriorityExpression NEXT -type REQUEST
bind vpn vserver UGVS_VPN_UGCTXDEMOS -policy UG_VPN_SPol_22.22.44.50 -priority 58000 -gotoPriorityExpression NEXT -type REQUEST

# Create Content Switching Policy and Action for Citrix Gateway
add cs action CSACT_UGCTXDEMOS -targetVserver UGVS_VPN_UGCTXDEMOS
add cs policy CSPOL_UGCTXDEMOS -rule "is_vpn_url  ||  HTTP.REQ.URL.PATH.SET_TEXT_MODE(IGNORECASE).STARTSWITH(\"/Citrix/External\")" -action CSACT_UGCTXDEMOS

# Create Content Switching vServer for Citrix Gateway
add cs vserver CSVS_UGCTXDEMOS SSL 22.22.44.50 443 -cltTimeout 180
set ssl vserver CSVS_UGCTXDEMOS -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind ssl vserver CSVS_UGCTXDEMOS -certkeyName CTXDEMOS_PUBLIC_CERT
bind ssl vserver CSVS_UGCTXDEMOS -cipherName CTXDEMOS_FRONTEND_APLUS
bind cs vserver CSVS_UGCTXDEMOS -policyName CSPOL_UGCTXDEMOS -priority 63000

# Create Responder Policy and Action for HTTP to HTTPS Redirection
add responder action RESACT_HTTP_TO_HTTPS redirect "\"https://\" + HTTP.REQ.HOSTNAME.HTTP_URL_SAFE + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE" -responseStatusCode 301
add responder policy RESPOL_HTTP_TO_HTTPS HTTP.REQ.IS_VALID RESACT_HTTP_TO_HTTPS

# Create Always On Server and Service
add server LBSRV_ALWAYS_UP 127.0.0.1
add service LBSVC_ALWAYS_UP LBSRV_ALWAYS_UP HTTP 80 -gslb NONE -maxClient 0 -maxReq 0 -cip ENABLED cip-header -usip YES -useproxyport YES -sp OFF -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP NO

# Create Always On vServer for Citrix Gateway
add lb vserver CSVS_UGCTXDEMOS_REDIRECT_HTTP_TO_HTTPS HTTP 22.22.44.50 80 -persistenceType NONE -cltTimeout 180
bind lb vserver CSVS_UGCTXDEMOS_REDIRECT_HTTP_TO_HTTPS LBSVC_ALWAYS_UP
bind lb vserver CSVS_UGCTXDEMOS_REDIRECT_HTTP_TO_HTTPS -policyName RESPOL_HTTP_TO_HTTPS -priority 100 -gotoPriorityExpression END -type REQUEST
<!--NeedCopy-->

配置第一个身份验证服务器

# Create Initialization SAML SP Policy and Action and Bind it to Citrix ADC AAA Authentication vServer
add authentication samlAction AUTH_ACT_SAML_SP_VPN_TO_LB -samlIdPCertName CTXDEMOS_PUBLIC_CERT -samlSigningCertName CTXDEMOS_PUBLIC_CERT -samlRedirectUrl "https://access.ctxdemos.com/samltolb" -signatureAlg RSA-SHA256 -digestMethod SHA256 -samlBinding REDIRECT -groupNameField Groups
add authentication Policy AUTH_POL_SAMP_SP_VPN_TO_LB -rule TRUE -action AUTH_ACT_SAML_SP_VPN_TO_LB

# Create Authentication Policy and Action for SAML SP to ADFS
add authentication samlAction AUTH_ACT_SAML_SP_ADFS -samlIdPCertName CTXDEMOS_ADFS_TOKEN_SIGNING -samlSigningCertName CTXDEMOS_PUBLIC_CERT -samlRedirectUrl "https://sts.ctxdemos.com/adfs/ls/" -samlUserField "Name ID" -samlRejectUnsignedAssertion OFF -samlIssuerName "https://access.ctxdemos.com" -Attribute1 "E-Mail Address" -signatureAlg RSA-SHA256 -digestMethod SHA256 -logoutURL "https://sts.ctxdemos.com/adfs/ls/wa=wsignout1.0" -forceAuthn ON
add authentication Policy AUTH_POL_SAML_SP_ADFS -rule TRUE -action AUTH_ACT_SAML_SP_ADFS

# Create Authentication Policy Label for for SAML SP to ADFS
add authentication policylabel AUTH_POLLBL_ADFS_AZUREMFA -loginSchema LSCHEMA_INT
bind authentication policylabel AUTH_POLLBL_ADFS_AZUREMFA -policyName AUTH_POL_SAML_SP_ADFS -priority 100 -gotoPriorityExpression NEXT

# Create Authentication Policy and Action for Group Extraction
add authentication ldapAction AUTH_ACT_LDAP_GROUP_EXTRACTION_AZUREMFACA -serverIP 22.22.22.61 -serverPort 636 -ldapBase "DC=ctxdemos,DC=com" -ldapBindDn "CN=svc_ctxadc01,OU=Services,OU=Accounts,DC=ctxdemos,DC=com" -ldapBindDnPassword 0c4fe86d56a865ef514a15affd1429f3e079ce1089731d4a407772d21036f3c8 -encrypted -encryptmethod ENCMTHD_3 -ldapLoginName sAMAccountName -searchFilter "memberOf:1.2.840.113556.1.4.1941:=CN=AzureMFACAUsers,OU=Groups,OU=Authorizations,DC=ctxdemos,DC=com" -groupAttrName memberOf -subAttributeName cn -secType SSL -authentication DISABLED -nestedGroupExtraction ON -maxNestingLevel 5 -groupNameIdentifier sAMAccountName -groupSearchAttribute memberOf -groupSearchSubAttribute CN -Attribute1 mail -Attribute2 objectGUID
add authentication Policy AUTH_POL_LDAP_GROUP_EXTRACTION_AZURAMFACA -rule TRUE -action AUTH_ACT_LDAP_GROUP_EXTRACTION_AZUREMFACA

# Create Authentication Policy Label for Group Extraction
add authentication policylabel AUTH_POLLBL_LDAP_GROUP_EXTRACTION_AZURAMFACA -loginSchema LSCHEMA_INT
bind authentication policylabel AUTH_POLLBL_LDAP_GROUP_EXTRACTION_AZURAMFACA -policyName AUTH_POL_LDAP_GROUP_EXTRACTION_AZURAMFACA -priority 100 -gotoPriorityExpression NEXT -nextFactor AUTH_POLLBL_ADFS_AZUREMFA


# Create Login Schema Policy and Profile for First Citrix ADC AAA Authentication vServer
add authentication loginSchema LSCHEMA_PRF_NOSCHEMA -authenticationSchema noschema -SSOCredentials YES
add authentication loginSchemaPolicy LSCHEMA_POL_NOSCHEMA -rule TRUE -action LSCHEMA_PRF_NOSCHEMA

# Create First Citrix ADC AAA Authentication vServer
add authentication vserver AAAVS_CTXDEMOS_COM_FOR_VPN SSL 0.0.0.0
set ssl vserver AAAVS_CTXDEMOS_COM_FOR_VPN -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind ssl vserver AAAVS_CTXDEMOS_COM_FOR_VPN -certkeyName CTXDEMOS_PUBLIC_CERT
bind ssl vserver AAAVS_CTXDEMOS_COM_FOR_VPN -cipherName CTXDEMOS_FRONTEND_APLUS
bind authentication vserver AAAVS_CTXDEMOS_COM_FOR_VPN -policy LSCHEMA_POL_NOSCHEMA -priority 100 -gotoPriorityExpression END
bind authentication vserver AAAVS_CTXDEMOS_COM_FOR_VPN -policy AUTH_POL_SAMP_SP_VPN_TO_LB -priority 100 -nextFactor AUTH_POLLBL_LDAP_GROUP_EXTRACTION_AZURAMFACA -gotoPriorityExpression NEXT

# Create First Citrix ADC AAA Authentication Profile
add authentication authnProfile AAA_AUTH_PRF_VPN -authnVsName AAAVS_CTXDEMOS_COM_FOR_VPN -AuthenticationHost aaa.ctxdemos.com

# Set Authentication Profile on Gateway vServer
set vpn vserver UGVS_VPN_UGCTXDEMOS -authnProfile AAA_AUTH_PRF_VPN
<!--NeedCopy-->

配置第二个身份验证服务器

# Create Authentication Policy and Action for LDAP
add authentication ldapAction AUTH_ACT_LDAP -serverIP 22.22.22.61 -serverPort 636 -authTimeout 60 -ldapBase "DC=ctxdemos,DC=com" -ldapBindDn "CN=svc_ctxadc01,OU=Services,OU=Accounts,DC=ctxdemos,DC=com" -ldapBindDnPassword 273881819af883e70c33d83c0546eac84e81d6eeba904f2d65bbebf2819c025a -encrypted -encryptmethod ENCMTHD_3 -ldapLoginName sAMAccountName -groupAttrName memberOf -subAttributeName cn -secType SSL -passwdChange ENABLED -nestedGroupExtraction ON -maxNestingLevel 5 -groupNameIdentifier sAMAccountName -groupSearchAttribute memberOf -groupSearchSubAttribute CN -Attribute1 userprincipalname -Attribute2 mail -Attribute3 userParameters
add authentication Policy AUTH_POL_LDAP_USER_NAME_PASSWORD -rule TRUE -action AUTH_ACT_LDAP

# Create Login Schema Policy and Profile for Second Citrix ADC AAA Authentication vServer - Username (Pre-filled ) and Password
add authentication loginSchema LSCHEMA_USER_NAME_PASSWORD -authenticationSchema "/nsconfig/loginschema/CTXDEMOS_USER_NAME_PASS.xml" -SSOCredentials YES
add authentication loginSchemaPolicy LSCHEMA_POL_USER_NAME_PASSWORD -rule TRUE -action LSCHEMA_USER_NAME_PASSWORD

# Create Authentication Policy Label for LDAP Username and Password
add authentication policylabel AUTH_POLLBL_LDAP_USER_NAME_PASSWORD -loginSchema LSCHEMA_USER_NAME_PASSWORD
bind authentication policylabel AUTH_POLLBL_LDAP_USER_NAME_PASSWORD -policyName AUTH_POL_LDAP_USER_NAME_PASSWORD -priority 110 -gotoPriorityExpression NEXT

# Create Login Schema Policy and Profile for Second Citrix ADC AAA Authentication vServer - Username Only
add authentication loginSchema LSCHEMA_USER_NAME_ONLY -authenticationSchema "/nsconfig/loginschema/CTXDEMOS_USER_NAME_ONLY.xml"
add authentication loginSchemaPolicy LSCHEMA_POL_NOPASSWORD -rule TRUE -action LSCHEMA_USER_NAME_ONLY

# Create Citrix ADC AAA Session Policy and Profile
add tm sessionAction AAA_SESSION_PRF_CTXDEMOS -SSO ON -ssoDomain CTXDEMOS -persistentCookie ON -persistentCookieValidity 30
add tm sessionPolicy AAA_SESSION_POL_CTXDEMOS TRUE AAA_SESSION_PRF_CTXDEMOS

# Create Second Citrix ADC AAA Authentication vServer
add authentication vserver AAAVS_CTXDEMOS_COM SSL 22.22.44.51 443
set ssl vserver AAAVS_CTXDEMOS_COM -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind ssl vserver AAAVS_CTXDEMOS_COM -certkeyName CTXDEMOS_PUBLIC_CERT
bind ssl vserver AAAVS_CTXDEMOS_COM -cipherName CTXDEMOS_FRONTEND_APLUS
bind authentication vserver AAAVS_CTXDEMOS_COM -portaltheme CTXDEMOS_PORTAL
bind authentication vserver AAAVS_CTXDEMOS_COM -policy AAA_SESSION_POL_CTXDEMOS -priority 100 -gotoPriorityExpression NEXT
bind authentication vserver AAAVS_CTXDEMOS_COM -policy LSCHEMA_POL_NOPASSWORD -priority 110 -gotoPriorityExpression END
bind authentication vserver AAAVS_CTXDEMOS_COM -policy AUTH_POL_LDAP_GROUP_EXTRACTION_AZURAMFACA -priority 140 -nextFactor AUTH_POLLBL_LDAP_USER_NAME_PASSWORD -gotoPriorityExpression NEXT

# Create Second Citrix ADC AAA Authentication Profile
add authentication authnProfile AAA_AUTH_PRF -authnVsName AAAVS_CTXDEMOS_COM -AuthenticationHost aaa.ctxdemos.com
<!--NeedCopy-->

Configure Citrix ADC as AD FS WAP

在 思杰 ADC 命令行界面中运行以下命令,以将 思杰 ADC 配置为 AD FS Web 应用程序代理 (WAP):

# Pattern Set - ADFS Proxy Hostname
add policy patset PATSET_ADFS_HOSTNAME
bind policy patset PATSET_ADFS_HOSTNAME sts.ctxdemos.com -index 1 -charset ASCII
# Policy Expression - ADFS Proxy Hostname
add policy expression is_ADFS_HOSTNAME "HTTP.REQ.HEADER(\"Host\").TO_LOWER.CONTAINS_ANY(\"PATSET_ADFS_HOSTNAME\")"

# Pattern Set - ADFS Proxy Path for NoAuth
add policy patset PATSET_ADFS_PATH_NOAUTH
bind policy patset PATSET_ADFS_PATH_NOAUTH "/adfs/services/trust" -index 1 -charset ASCII
bind policy patset PATSET_ADFS_PATH_NOAUTH "/federationmetadata/2007-06/federationmetadata.xml" -index 2 -charset ASCII
bind policy patset PATSET_ADFS_PATH_NOAUTH "/adfs/fs/federationserverservice.asmx" -index 3 -charset ASCII
bind policy patset PATSET_ADFS_PATH_NOAUTH "/adfs/ls/FormsSignIn.aspx" -index 4 -charset ASCII
bind policy patset PATSET_ADFS_PATH_NOAUTH "/adfs/services/trust/2005/usernamemixed" -index 5 -charset ASCII
bind policy patset PATSET_ADFS_PATH_NOAUTH "/adfs/services/trust/mex" -index 6 -charset ASCII

# Policy Expression - ADFS Proxy Path for NoAuth
add policy expression is_ADFS_PROXY_NOAUTH "HTTP.REQ.URL.PATH.TO_LOWER.CONTAINS_ANY(\"PATSET_ADFS_PATH_NOAUTH\")"

# Pattern Set - ADFS Proxy Path for Passive Client
add policy patset PATSET_ADFS_PATH_ACTIVE_PASSIVE
bind policy patset PATSET_ADFS_PATH_ACTIVE_PASSIVE "/adfs" -index 1 -charset ASCII
bind policy patset PATSET_ADFS_PATH_ACTIVE_PASSIVE "/cgi/selfauth" -index 2 -charset ASCII

# Policy Expression - ADFS Proxy Path for Passive Client
add policy expression is_ADFS_PROXY_ACTIVE_PASSIVE "(HTTP.REQ.HEADER(\"Host\").TO_LOWER.CONTAINS_ANY(\"PATSET_ADFS_HOSTNAME\") && HTTP.REQ.URL.PATH.TO_LOWER.STARTSWITH_ANY(\"PATSET_ADFS_PATH_ACTIVE_PASSIVE\"))"

# Rewrite Policies for ADFS PIP
add rewrite action RWACT_X_MS_Proxy insert_http_header X-MS-Proxy "\"NETSCALER\""
add rewrite policy RWPOL_X_MS_Proxy true RWACT_X_MS_Proxy

add rewrite action RWACT_X_MS_Forwarded_Client_IP insert_http_header X-MS-Forwarded-Client-IP CLIENT.IP.SRC
add rewrite policy RWPOL_X_MS_Forwarded_Client_IP true RWACT_X_MS_Forwarded_Client_IP

add rewrite action RWACT_X_MS_Endpoint_Absolute_Path insert_http_header X-MS-Endpoint-Absolute-Path HTTP.REQ.URL
add rewrite policy RWPOL_X_MS_Endpoint_Absolute_Path true RWACT_X_MS_Endpoint_Absolute_Path

add rewrite action RWACT_X_MS_Target_Role insert_http_header X-MS-Target-Role "\"PrimaryComputer\""
add rewrite policy RWPOL_X_MS_Target_Role true RWACT_X_MS_Target_Role

add rewrite action RWACT_X_MS_ADFS_Proxy_Client_IP insert_http_header X-MS-ADFS-Proxy-Client-IP CLIENT.IP.SRC
add rewrite policy RWPOL_X_MS_ADFS_Proxy_Client_IP true RWACT_X_MS_ADFS_Proxy_Client_IP

add rewrite action RWACT_X_MS_Client_User_Agent insert_http_header X-MS-Client-User-Agent "HTTP.REQ.HEADER(\"User-Agent\")"
add rewrite policy RWPOL_X_MS_Client_User_Agent true RWACT_X_MS_Client_User_Agent

add rewrite action RWACT_ADFS_PROXYMEX replace HTTP.REQ.URL.PATH_AND_QUERY "\"/adfs/services/trust/proxymex\" + HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).PATH_AND_QUERY.STRIP_START_CHARS(\"/adfs/services/trust/mex\").HTTP_URL_SAFE"
add rewrite policy RWPOL_ADFS_PROXYMEX "is_ADFS_HOSTNAME && HTTP.REQ.URL.TO_LOWER.STARTSWITH(\"/adfs/services/trust/mex\")" RWACT_ADFS_PROXYMEX

add rewrite policy RWPOL_ADFS_PROXY_HEADERS-NOACT TRUE NOREWRITE

add rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS http_req
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_Proxy 100 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_Forwarded_Client_IP 110 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_Endpoint_Absolute_Path 120 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_Target_Role 130 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_ADFS_Proxy_Client_IP 140 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_X_MS_Client_User_Agent 150 NEXT
bind rewrite policylabel RWPOLLBL_ADFS_PROXY_HEADERS RWPOL_ADFS_PROXYMEX 160 NEXT

# Create ADFS Server and Service Group
add server LBSRV_ADFS wsadfs01.ctxdemos.com
add serviceGroup LBSVCGRP_ADFS_443 SSL -maxClient 0 -maxReq 0 -cip ENABLED X-MS-Forwarded-Client-IP -usip NO -useproxyport YES -sp ON -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP YES
bind ssl serviceGroup LBSVCGRP_ADFS_443 -cipherName CTXDEMO_BACKEND
set ssl serviceGroup LBSVCGRP_ADFS_443 -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED
bind serviceGroup LBSVCGRP_ADFS_443 LBSRV_ADFS 443

# Create ADFS Proxy NoAuth Load Balancing vServer
add lb vserver LBVS_ADFS_PROXY_NOAUTH SSL 0.0.0.0 0 -persistenceType NONE -cltTimeout 180
set ssl vserver LBVS_ADFS_PROXY_NOAUTH -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind ssl vserver LBVS_ADFS_PROXY_NOAUTH -certkeyName CTXDEMOS-PUBLIC
bind ssl vserver LBVS_ADFS_PROXY_NOAUTH -cipherName CTXDEMO_BACKEND
bind lb vserver LBVS_ADFS_PROXY_NOAUTH LBSVCGRP_ADFS_443
bind lb vserver LBVS_ADFS_PROXY_NOAUTH -policyName RWPOL_ADFS_PROXY_HEADERS-NOACT -priority 100 -gotoPriorityExpression NEXT -type REQUEST -invoke policylabel RWPOLLBL_ADFS_PROXY_HEADERS

# Create ADFS Proxy NoAuth Content Switching Policy and Action
add cs action CSACT_ADFS_PROXY_NOAUTH -targetLBVserver LBVS_ADFS_PROXY_NOAUTH
add cs policy CSPOL_ADFS_PROXY_NOAUTH -rule is_ADFS_PROXY_NOAUTH -action CSACT_ADFS_PROXY_NOAUTH

# Create ADFS Proxy Active-Passive Load Balancing vServer
add lb vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE SSL 0.0.0.0 0 -persistenceType NONE -cltTimeout 180 -Authentication ON -authnProfile AAA_AUTH_PRF
set ssl vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind lb vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE LBSVCGRP_ADFS_443
bind ssl vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -certkeyName CTXDEMOS-PUBLIC
bind ssl vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -cipherName CTXDEMO_FRONTEND_APLUS
bind lb vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -policyName RWPOL_ADFS_PROXY_HEADERS-NOACT -priority 100 -gotoPriorityExpression NEXT -type REQUEST -invoke policylabel RWPOLLBL_ADFS_PROXY_HEADERS

# Create ADFS Proxy Active-Passive Content Switching Policy and Action
add cs action CSACT_ADFS_PROXY_ACTIVE_PASSIVE -targetLBVserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE
add cs policy CSPOL_ADFS_PROXY_ACTIVE_PASSIVE -rule is_ADFS_PROXY_ACTIVE_PASSIVE -action CSACT_ADFS_PROXY_ACTIVE_PASSIVE

# Bind Content Switching Policies to Citrix Gateway Content Switching vServer
bind cs vserver CSVS_UGCTXDEMOS -policyName CSPOL_ADFS_PROXY_NOAUTH -priority 100
bind cs vserver CSVS_UGCTXDEMOS -policyName CSPOL_ADFS_PROXY_ACTIVE_PASSIVE -priority 300

# Create Citrix ADC AAA Traffic Policies and Bind them to ADFS Proxy Active-Passive Load Balancing vServer
add tm formSSOAction AAATM_SSOPRF_ADFS_LOGIN -actionURL "/adfs/ls" -userField UserName -passwdField Password -ssoSuccessRule true -nameValuePair AuthMethod=FormsAuthentication -responsesize 15000 -submitMethod POST
add tm trafficAction AAATM_PRF_ADFS_LOGIN -appTimeout 1 -SSO ON -formSSOAction AAATM_SSOPRF_ADFS_LOGIN -persistentCookie OFF -InitiateLogout OFF -kcdAccount NONE -userExpression "HTTP.REQ.USER.ATTRIBUTE(3)" -passwdExpression "HTTP.REQ.USER.ATTRIBUTE(2)"
add tm trafficPolicy AAATM_POL_ADFS_LOGIN "HTTP.REQ.URL.TO_LOWER.STARTSWITH(\"/adfs/ls\")" AAATM_PRF_ADFS_LOGIN
add tm trafficAction AAATM_PRF_ADFS_LOGOUT -appTimeout 1 -persistentCookie OFF -InitiateLogout ON -kcdAccount NONE
add tm trafficPolicy AAATM_POL_ADFS_LOGOUT "HTTP.REQ.URL.TO_LOWER.STARTSWITH(\"/adfs/ls\") && HTTP.REQ.URL.QUERY.VALUE(\"wa\").EQ(\"wsignout1.0\")" AAATM_PRF_ADFS_LOGOUT
bind lb vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -policyName AAATM_POL_ADFS_LOGIN -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver LBVS_ADFS_PROXY_ACTIVE_PASSIVE -policyName AAATM_POL_ADFS_LOGOUT -priority 110 -gotoPriorityExpression END -type REQUEST
<!--NeedCopy-->

配置一个初始的身份验证流程

# Pattern Set - Gateway and AAA Hostname
add policy patset PATSET_GATEWAY_HOSTHEADER
bind policy patset PATSET_GATEWAY_HOSTHEADER access.ctxdemos.com -index 1 -charset ASCII
bind policy patset PATSET_GATEWAY_HOSTHEADER aaa.ctxdemos.com -index 2 -charset ASCII
# Policy Expression - Gateway and AAA Hostname
add policy expression is_GATEWAY_HOSTNAME "HTTP.REQ.HEADER(\"Host\").TO_LOWER.CONTAINS_ANY(\"PATSET_GATEWAY_HOSTHEADER\")"

# Create Initialization Load Balancing vServer
add lb vserver LBVS_SAML_SP_INITIALIZATION SSL 0.0.0.0 0 -persistenceType NONE -cltTimeout 180 -Authentication ON -authnProfile AAA_AUTH_PRF
set ssl vserver LBVS_SAML_SP_INITIALIZATION -ssl3 DISABLED -tls1 DISABLED -tls11 DISABLED -tls13 ENABLED -ocspStapling ENABLED -HSTS ENABLED -maxage 157680000 -IncludeSubdomains YES
bind lb vserver LBVS_SAML_SP_INITIALIZATION LBSVC_ALWAYS_UP
bind ssl vserver LBVS_SAML_SP_INITIALIZATION -certkeyName CTXDEMOS_PUBLIC_CERT
bind ssl vserver LBVS_SAML_SP_INITIALIZATION -cipherName CTXDEMOS_FRONTEND_APLUS

# Create Initialization Content Switching Policy and Action
add cs action CSACT_SAML_SP_INITIALIZATION -targetLBVserver LBVS_SAML_SP_INITIALIZATION
add cs policy CSPOL_SAML_SP_INITIALIZATION -rule "is_GATEWAY_HOSTNAME && HTTP.REQ.URL.PATH.TO_LOWER.STARTSWITH(\"/samltolb\")" -action CSACT_SAML_SP_INITIALIZATION

# Bind Content Switching Policies to Citrix Gateway Content Switching vServer
bind cs vserver CSVS_UGCTXDEMOS -policyName CSPOL_SAML_SP_INITIALIZATION -priority 500

# Create Initialization Citrix ADC AAA Traffic Policy and Action and Bind it to Load Balancing vServer
add tm samlSSOProfile AAATM_SAMLSSOPRF_VPN_TO_LB -samlSigningCertName CTXDEMOS_PUBLIC_CERT -assertionConsumerServiceURL "https://access.ctxdemos.com/cgi/samlauth" -relaystateRule "HTTP.REQ.URL.QUERY.VALUE(\"RelayState\")" -signatureAlg RSA-SHA256 -digestMethod SHA256 -Attribute1 Password -Attribute1Expr AAA.USER.PASSWD -Attribute2 Groups -Attribute2Expr AAA.USER.GROUPS -encryptAssertion ON -samlSPCertName CTXDEMOS_PUBLIC_CERT
add tm trafficAction AAATM_PRF_VPN_TO_LB -SSO ON -persistentCookie OFF -InitiateLogout OFF -kcdAccount NONE -samlSSOProfile AAATM_SAMLSSOPRF_VPN_TO_LB
add tm trafficPolicy AAATM_POL_VPN_TO_LB "HTTP.REQ.URL.STARTSWITH(\"/samltolb\")" AAATM_PRF_VPN_TO_LB
bind lb vserver LBVS_SAML_SP_INITIALIZATION -policyName AAATM_POL_VPN_TO_LB -priority 100 -gotoPriorityExpression END -type REQUEST
<!--NeedCopy-->

密码套件组

# Create Cipher Group for Backend vServers
add ssl cipher CTXDEMOS_BACKEND
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.3-AES256-GCM-SHA384 -cipherPriority 1
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.3-CHACHA20-POLY1305-SHA256 -cipherPriority 2
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.3-AES128-GCM-SHA256 -cipherPriority 3
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384 -cipherPriority 4
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA256 -cipherPriority 5
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.2-ECDHE-ECDSA-AES256-GCM-SHA384 -cipherPriority 6
bind ssl cipher CTXDEMOS_BACKEND -cipherName TLS1.2-ECDHE-ECDSA-AES128-GCM-SHA256 -cipherPriority 7

# Create Cipher Group for Frondend vServers
add ssl cipher CTXDEMOS_FRONTEND
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.3-AES256-GCM-SHA384 -cipherPriority 1
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.3-CHACHA20-POLY1305-SHA256 -cipherPriority 2
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.3-AES128-GCM-SHA256 -cipherPriority 3
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-ECDSA-AES128-GCM-SHA256 -cipherPriority 4
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-ECDSA-AES256-GCM-SHA384 -cipherPriority 5
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-ECDSA-AES128-SHA256 -cipherPriority 6
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-ECDSA-AES256-SHA384 -cipherPriority 7
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-ECDHE-ECDSA-AES128-SHA -cipherPriority 8
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-ECDHE-ECDSA-AES256-SHA -cipherPriority 9
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA256 -cipherPriority 10
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384 -cipherPriority 11
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-RSA-AES-128-SHA256 -cipherPriority 12
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-ECDHE-RSA-AES-256-SHA384 -cipherPriority 13
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-ECDHE-RSA-AES128-SHA -cipherPriority 15
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-ECDHE-RSA-AES256-SHA -cipherPriority 16
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-DHE-RSA-AES128-GCM-SHA256 -cipherPriority 17
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1.2-DHE-RSA-AES256-GCM-SHA384 -cipherPriority 18
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-DHE-RSA-AES-128-CBC-SHA -cipherPriority 19
bind ssl cipher CTXDEMOS_FRONTEND -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA -cipherPriority 20

# Create Cipher Group for Frondend vServers - A+
add ssl cipher CTXDEMOS_FRONTEND_APLUS
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.3-AES256-GCM-SHA384 -cipherPriority 1
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.3-CHACHA20-POLY1305-SHA256 -cipherPriority 2
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.3-AES128-GCM-SHA256 -cipherPriority 3
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-ECDSA-AES256-GCM-SHA384 -cipherPriority 4
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-ECDSA-AES128-GCM-SHA256 -cipherPriority 5
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-ECDSA-CHACHA20-POLY1305 -cipherPriority 6
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-ECDSA-AES256-SHA384 -cipherPriority 7
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-ECDSA-AES128-SHA256 -cipherPriority 8
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384 -cipherPriority 9
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA256 -cipherPriority 13
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-RSA-CHACHA20-POLY1305 -cipherPriority 14
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-RSA-AES-256-SHA384 -cipherPriority 15
bind ssl cipher CTXDEMOS_FRONTEND_APLUS -cipherName TLS1.2-ECDHE-RSA-AES-128-SHA256 -cipherPriority 16
<!--NeedCopy-->

登录架构 XML 文件

CTXDEMOS_USER_NAME_PASS.XML

<?xml version="1.0" encoding="utf-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
    <Status>success</Status>
    <Result>more-info</Result>
    <StateContext/>
    <AuthenticationRequirements>
        <PostBack>/nf/auth/doAuthentication.do</PostBack>
        <CancelPostBack>/Citrix/Authentication/ExplicitForms/CancelAuthenticate</CancelPostBack>
        <CancelButtonText>Cancel</CancelButtonText>
        <Requirements>
            <Requirement>
                <Credential>
                    <ID>login</ID>
                    <SaveID>ExplicitForms-Username</SaveID>
                    <Type>username</Type>
                </Credential>
                <Label>
                    <Text>User name</Text>
                    <Type>plain</Type>
                </Label>
                <Input>
                    <AssistiveText>Please supply username</AssistiveText>
                    <Text>
                        <Secret>false</Secret>
                        <ReadOnly>false</ReadOnly>
                        <InitialValue>${AAA.USER.NAME}</InitialValue>
                        <Constraint>.+</Constraint>
                    </Text>
                </Input>
            </Requirement>
            <Requirement>
                <Credential>
                    <ID>passwd</ID>
                    <SaveID>ExplicitForms-Password</SaveID>
                    <Type>password</Type>
                </Credential>
                <Label>
                    <Text>Password:</Text>
                    <Type>plain</Type>
                </Label>
                <Input>
                    <Text>
                        <Secret>true</Secret>
                        <ReadOnly>false</ReadOnly>
                        <InitialValue/>
                        <Constraint>.+</Constraint>
                    </Text>
                </Input>
            </Requirement>
            <Requirement>
                <Credential>
                    <ID>saveCredentials</ID>
                    <Type>savecredentials</Type>
                </Credential>
                <Label>
                    <Text>Remember my password</Text>
                    <Type>plain</Type>
                </Label>
                <Input>
                    <CheckBox>
                        <InitialValue>false</InitialValue>
                    </CheckBox>
                </Input>
            </Requirement>
            <Requirement>
                <Credential>
                    <ID>loginBtn</ID>
                    <Type>none</Type>
                </Credential>
                <Label>
                    <Type>none</Type>
                </Label>
                <Input>
                    <Button>Log On</Button>
                </Input>
            </Requirement>
        </Requirements>
    </AuthenticationRequirements>
</AuthenticateResponse>
<!--NeedCopy-->

CTXDEMOS_USER_NAME_ONLY.XML

<?xml version="1.0" encoding="utf-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
    <Status>success</Status>
    <Result>more-info</Result>
    <StateContext/>
    <AuthenticationRequirements>
        <PostBack>/nf/auth/doAuthentication.do</PostBack>
        <CancelPostBack>/Citrix/Authentication/ExplicitForms/CancelAuthenticate</CancelPostBack>
        <CancelButtonText>Cancel</CancelButtonText>
        <Requirements>
            <Requirement>
                <Credential>
                    <ID>login</ID>
                    <SaveID>ExplicitForms-Username</SaveID>
                    <Type>username</Type>
                </Credential>
                <Label>
                    <Text>User name</Text>
                    <Type>plain</Type>
                </Label>
                <Input>
                    <AssistiveText>Please supply username</AssistiveText>
                    <Text>
                        <Secret>false</Secret>
                        <ReadOnly>false</ReadOnly>
                        <InitialValue/>
                        <Constraint>.+</Constraint>
                    </Text>
                </Input>
            </Requirement>
            <Requirement>
                <Credential>
                    <Type>none</Type>
                </Credential>
                <Label>
                    <Text> Please submit credentials to continue Login ...</Text>
                    <Type>confirmation</Type>
                </Label>
                <Input/>
            </Requirement>
            <Requirement>
                <Credential>
                    <ID>saveCredentials</ID>
                    <Type>savecredentials</Type>
                </Credential>
                <Label>
                    <Text>Remember my password</Text>
                    <Type>plain</Type>
                </Label>
                <Input>
                    <CheckBox>
                        <InitialValue>false</InitialValue>
                    </CheckBox>
                </Input>
            </Requirement>
            <Requirement>
                <Credential>
                    <ID>loginBtn</ID>
                    <Type>none</Type>
                </Credential>
                <Label>
                    <Type>none</Type>
                </Label>
                <Input>
                    <Button>Log On</Button>
                </Input>
            </Requirement>
        </Requirements>
    </AuthenticationRequirements>
</AuthenticateResponse>
<!--NeedCopy-->

参考资料

Authentication to NetScaler using AD FS 4.0 on Server 2016, Citrix FAS, and Azure MFA in Azure Cloud. (2018). Retrieved from https://www.jgspiers.com/authentication-to-netscaler-using-ad-fs-4-0-server-2016-citrix-fas-azure-mfa-azure-cloud/

将 Azure MFA 配置为 AD FS 的身份验证提供程序。(2019)。检索自 https://docs.microsoft.com/zh-cn/windows-server/identity/ad-fs/operations/configure-ad-fs-and-azure-mfa

部署联合服务器场。(2017)。检索自 https://docs.microsoft.com/zh-cn/windows-server/identity/ad-fs/deployment/deploying-a-federation-server-farm

联合身份验证服务 ADFS 部署。(2018)。检索自 https://docs.citrix.com/zh-cn/citrix-virtual-apps-desktops/secure/federated-authentication-service/fas-architectures/fas-adfs.html

将 NetScaler 部署为 Active Directory 联合身份验证服务代理的指南。(n.d.)。检索自 https://www.citrix.com/content/dam/citrix/en_us/documents/products-solutions/guide-to-deploying-netscaler-as-an-active-directory-federation-services-proxy.pdf

工作原理:Azure 多重身份验证。(2018)。检索自 https://docs.microsoft.com/zh-cn/azure/active-directory/authentication/concept-mfa-howitworks

规划基于云的 Azure 多重身份验证部署。(2019)。检索自 https://docs.microsoft.com/zh-cn/azure/active-directory/authentication/howto-mfa-getstarted

蒂尔·范登布鲁克。(2017 年 12 月 7 日)。Windows 服务器 2012 R2 上的 ADFS v3 与 NetScaler。检索自 https://www.citrix.com/blogs/2015/05/29/adfs-v3-on-windows-server-2012-r2-with-netscaler/

使用 Citrix Gateway 迁移到混合云和 SaaS。(日期不详)。检索自 https://www.citrix.com/products/citrix-gateway/resources/netscaler-unified-gateway.html

使用 Azure Active Directory 直通身份验证进行用户登录。(2018)。检索自 https://docs.microsoft.com/zh-cn/azure/active-directory/hybrid/how-to-connect-pta

作者:Saman Salehian,首席网络销售工程师。

思杰网关 和 微软 Azure 多重身份验证