Citrix ADC

nFactor 可扩展性

nFactor 身份验证框架提供了添加自定义项的灵活性,使登录界面更加直观,以获得丰富的用户体验。您可以添加自定义登录标签、自定义登录凭据、自定义 UI 显示等。

使用 nFactor,每个因素都可以有自己的登录屏幕。在每个登录屏幕中,您可以显示来自以前任何因素的任何信息或在其他因素中不可见的更多信息。例如,您的最后一个因素可以是用户阅读说明并单击继续的信息页面。

在 nFactor 之前,自定义登录页面受到限制,需要自定义和支持。可以替换 tmindex.html 或应用重写规则来改变其一些行为。但是,不可能实现基本功能。

本主题将详细捕获以下 nFactor 相关的自定义项。

  • 自定义登录标签
  • 自定义 UI 以显示图像
  • 自定义 Citrix ADC nFactor 登录表单

假设

您熟悉 nFactor、Shell 命令、XML 和文本编辑器。

必备条件

  • 只有在 Citrix ADC 上配置 RFWeb UI 主题(或基于主题的)时,才可以进行本主题中描述的自定义。
  • 身份验证策略必须绑定到身份验证、授权和审核虚拟服务器,否则流无法按预期工作。有关详细信息,请参阅 CTX224241。
  • 您有以下与 nFactor 相关的项目
    • XML 模式
    • JavaScript
    • 身份验证操作
    • 身份验证虚拟服务器
    • Citrix ADC 11.1 及更高版本

自定义登录标签

要自定义登录标签,您需要以下内容:

  • 描述登录页面外观的 XML 架构。
  • 包含用于更改渲染过程的 JavaScript 的脚本 .js 文件。

工作原理

JavaScript 解析 XML 文件,渲染 <Requirements> 标签内的每个项目。每个元素对应于 HTML 表单中的一行。例如,登录字段是一行,密码字段是另一行,登录按钮也是如此。要引入新行,您必须使用 StoreFront SDK 在 XML 架构文件中指定这些行。StoreFront SDK 允许具有 XML 架构的登录页面使用 <Requirement> 标签并在其上定义元素。这些元素允许使用 JavaScript 在该空间中引入任何需要的 HTML 元素。在这种情况下,将以 HTML 形式创建一行。

可以使用的 XML 如下所示:

<Requirement>
<Credential>
<Type>nsg-custom-cred</Type>
<ID>passwd</ID>
</Credential>
<Label>
<Type>nsg-custom-label</Type>
</Label>
</Requirement>

<Requirement>:登录页中提供的空间。凭据填充空间,其他部分将引擎路由到正确的信息中。在这种情况下,键入 nsg-自定义化。这被定义为纯文本,标签是为其正文定义的。 要求 XML 与 JavaScript 代码配对以获得所需的结果。

// Custom Label Handler for Self Service Links
CTXS.ExtensionAPI.addCustomAuthLabelHandler({
getLabelTypeName: function () { return "nsg-custom-label"; },
getLabelTypeMarkup: function (requirements) {
return $("< Your HTML Code Here>");
},
// Instruction to parse the label as if it was a standard type
parseAsType: function () {
return "plain";
}
});
//Custom Credential Handler for Self Service Links
CTXS.ExtensionAPI.addCustomCredentialHandler({
getCredentialTypeName: function () { return "nsg-custom-cred"; },
getCredentialTypeMarkup: function (requirements) {
return $("<div/>");
},
});

XML 部分指示登录页面要显示的内容,JavaScript 代码提供实际文本。凭据处理程序会打开空间,标签会填充空间。因为现在对于重写和响应程序来说,所有身份验证流量都是不可见的,所以您可以更改页面的外观和感觉。 自定义登录标签的配置

  1. 创建和绑定基于 RFWeb 的主题。

    add vpn portaltheme RfWebUI_MOD -basetheme RfWebUI
    
    bind vpn vserver TESTAAA –portaltheme RfWebUI_MOD
    

    基于主题的文件路径在目录中可用; /var/netscaler/logon/themes/RfWebUI_MOD

  2. 将以下代码段添加到 script.js 文件的末尾:

    注意:如果没有在正确的文件中包含前面的行,或者缺少包含任何 JavaScript 函数,则无法加载 XML。该错误只能在浏览器的开发人员控制台中看到,其中包含以下文本:“未定义类型 nsg-custom-cred”。

    // Custom Label Handler for Self Service Links
    CTXS.ExtensionAPI.addCustomAuthLabelHandler({
    getLabelTypeName: function () { return "nsg-custom-label"; },
    getLabelTypeMarkup: function (requirements) {
    return $("<a href="https://identity.test.com/identity/faces/register" style="font-size: 16px;" style="text-align: center;">Self Registration</a><br><a href="https://identity.test.com/identity/faces/forgotpassword" style="font-size: 16px;" style="text-align: center;">Forgot Password</a><br><a href="https://identity.test.com/identity/faces/forgotuserlogin" style="font-size: 16px;" style="text-align: center;">Forgot User Login</a>");
    },
    // Instruction to parse the label as if it was a standard type
    parseAsType: function () {
    return "plain";
    }
    });
    //Custom Credential Handler for Self Service Links
    CTXS.ExtensionAPI.addCustomCredentialHandler({
    getCredentialTypeName: function () { return "nsg-custom-cred"; },
    getCredentialTypeMarkup: function (requirements) {
    return $("<div/>");
    },
    });
    

此示例中使用的登录模式

<?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>Username</SaveID>
<Type>username</Type>
</Credential>
<Label>
<Text>User name</Text>
<Type>plain</Type>
</Label>
<Input>
<AssistiveText>Please supply either domain\username or user@fully.qualified.domain</AssistiveText>
<Text>
<Secret>false</Secret>
<ReadOnly>false</ReadOnly>
<InitialValue></InitialValue>
<Constraint>.+</Constraint>
</Text>
</Input>
</Requirement>
<Requirement>
<Credential>
<ID>passwd</ID>
<SaveID>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>
<Type>nsg-custom-cred</Type>
<ID>passwd</ID>
</Credential>
<Label>
<Type>nsg-custom-label</Type>
</Label>
</Requirement>
<Requirement>
<Credential>
<ID>loginBtn</ID>
<Type>none</Type>
</Credential>
<Label>
<Type>none</Type>
</Label>
<Input>
<Button>Please Log On</Button>
</Input>
</Requirement>
</Requirements>
</AuthenticationRequirements>
</AuthenticateResponse>

执行以下命令以加载自定义模式到配置。

add authentication loginSchema custom -authenticationSchema custom.xml

add authentication loginSchemaPolicy custom -rule true -action custom

bind authentication vserver AAATEST -policy custom -priority 100 -gotoPriorityExpression END

下图显示了使用此配置呈现的登录页面。

本地化后的图片

自定义 UI 以显示图像

nFactor 允许使用登录架构文件进行自定义显示。除了内置 loginschema 文件提供的自定义外,可能还需要进一步的自定义。例如,在 UI 中显示超链接或编写自定义逻辑。这些可以使用由登录模式扩展和相应的 javascript 文件组成的“自定义凭据”来实现。

对于用户界面自定义来显示图像,使用“Citrix ADC 旋转”集成中的部署流程作为示例。

这种流程中有两个因素。

  • 第一个因素:检查用户的 AD 凭据。
  • 第二个因素:基于组成员身份提示用户登录。

本地化后的图片

在这个流程中,所有用户都经历第一个因素。在第二个因素之前,有一个伪因素来检查是否可以从“旋转”因素中省略某些用户。如果用户需要“旋转”系数,则会显示图像和文本框以输入代码。

解决方案

自定义 UI 以显示图像的解决方案包含两部分;

  • 登录架构扩展。
  • 用于处理登录架构扩展的自定义脚本。

登录模式扩展

为了控制表单呈现,将自定义 ‘id’/’凭据’ 注入到登录架构中。这可以通过重用现有模式并根据要求进行修改来完成。

在该示例中,考虑只有一个文本字段(如 /nsconfig/loginschema/LoginSchema/OnlyPassword.xml)的登录架构。 以下代码段被添加到登录架构中。

<Requirement><Credential><ID>swivel_cred</ID><Type>swivel_cred</Type><Input><Text><Hidden>true</Hidden><InitialValue>${http.req.user.name}</InitialValue></Text></Input></Credential></Requirement>

在代码段中,“swivel_cred”被指定为凭据的“类型”。由于这不被识别为内置的“凭据”,UI 会为此类型查找处理程序,并在存在时调用它。 将为此凭据发送初始值,该凭据是 Citrix ADC 动态填充的表达式。在示例中,它是用于通知旋转服务器用户名的用户名。它可能不是所有的时间都需要,或者它可以用其他一些数据来增强。必须根据需要添加这些详细信息。

处理自定义凭据的 Javascript

当 UI 找到自定义凭据时,它会查找处理程序。所有自定义处理程序都是用 /var/netscaler/logon/LogonPoint/custom/script.js 编写的默认门户主题。 对于自定义门户主题,可以在 /var/netscaler/logon/themes/<custom_theme>/ 目录中找到 script.js。

添加了以下脚本来呈现自定义凭据的标记。

CTXS.ExtensionAPI.addCustomCredentialHandler({
    // The name of the credential, must match the type returned by the server
    getCredentialTypeName: function () { return "swivel_cred"; },
    // Generate HTML for the custom credential
    getCredentialTypeMarkup: function (requirements) {
        var div = $("<div></div>");
        var image = $("<img/>");
        var username = requirements.input.text.initialValue; //Get the secret from the response
        image.attr({
            "style" : "width:200px;height:200px;",
            "id" : "qrcodeimg",
            "src" : "https://myswivelserver.citrix.com:8443/pinsafe/SCImage?username=" + username
        });
        div.append(image);
        return div;
    }
});

这个代码片段用于处理 ‘swivel_cred’ 的标记。突出显示的凭据名称必须与前面在 loginschema 扩展中指定的 ‘type’ 匹配。 要生成标记,需要添加源指向旋转服务器的图像。完成此操作后,UI 将从指定位置加载图像。由于此登录架构也有一个文本框,UI 会呈现该文本框。

注意: 管理员可以修改图像元素的“样式”来调整图像大小。目前它配置为 200x200 像素。

自定义 UI 以显示图像的配置

nFactor 配置自下而上构造得更好,这是最后一个因素,因为当您尝试为之前的因素指定“nextFactor”时,需要后续因素的名称。

旋转系数配置:

add loginschema swivel_image –authenticationSchema /nsconfig/loginschema/SwivelImage.xml

add authentication policylabel SwivelFactor –loginSchema swivel_image

bind authentication policylabel SwivelFactor –policy <policy-to-check-swivel-image> -priority 10

注意:从示例中使用的登录架构下载 SwivelImage.xml。

组检查配置的伪因素:

add authentication policylabel GroupCheckFactor

add authentication policy contractors_auth_policy –rule ‘http.req.user.is_member_of(“contractors”)’ –action NO_AUTHN

add authentication policy not_contractors _auth_policy–rule true –action NO_AUTHN

bind authentication policylabel GroupCheckFactor –policy contractors_auth_policy –pri 10 –nextFactor SwivelFactor

bind authentication policylabel GroupCheckFactor –policy not_contractors_auth_policy –pri 20

Active Directory 登录的第一个因素:

add ldapAction <>

add authentication policy user_login_auth_policy –rule true –action <>

bind authentication vserver <> -policy user_login_auth_policy –pri 10 –nextFactor GroupCheckFactor

在配置中,指定了三个因素,其中一个是隐式/伪。

此示例中使用的登录模式

下面是带旋转凭据和文本框的示例架构。

注意:为 Web 浏览器复制数据时,引号的显示可能不同。在将数据保存到文件之前,将数据复制到编辑器中,如记事本。

<?xml version="1.0" encoding="UTF-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
<Status>success</Status>
<Result>more-info</Result>
<StateContext></StateContext>
<AuthenticationRequirements>
<PostBack>/nf/auth/doAuthentication.do</PostBack>
<CancelPostBack>/nf/auth/doLogoff.do</CancelPostBack>
<CancelButtonText>Cancel</CancelButtonText>
<Requirements>
<Requirement><Credential><ID>swivel_cred</ID><Type>swivel_cred</Type><Input><Text><Hidden>true</Hidden><InitialValue>${http.req.user.name}</InitialValue></Text></Input></Credential></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></InitialValue><Constraint>.+</Constraint></Text></Input></Requirement>
<Requirement><Credential><Type>none</Type></Credential><Label><Text>Hello ${http.req.user.name}, Please enter passcode from above image.</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>

输出

执行配置后,将显示以下图像。

本地化后的图片

注意: 图像的高度和位置可以在 JavaScript 中更改。

自定义 Citrix ADC nFactor 登录表单以显示或隐藏字段

Citrix Gateway 的 RFWeb UI 允许各种自定义。此功能与 nFactor 身份验证框架结合使用后,可让客户配置复杂的流程,而不会影响现有工作流。

在此示例中,两个身份验证选项(OAuth 和 LDAP)可从“登录类型”列表中获得。首次加载表单时,将显示用户名和密码字段(首先显示 LDAP)。如果选择了 OAuth,则所有字段都将被隐藏,因为 OAuth 意味着将身份验证卸载到第三方服务器。通过这种方式,管理员可以根据用户的方便配置直观的工作流程。

注意:

  • 通过对脚本文件进行简单修改,可以修改“登录类型”列表中的值。
  • 本节仅介绍流的 UI 部分。身份验证的运行时处理超出了本文的范围。建议用户参考 nFactor 文档进行身份验证配置。

如何自定义 nFactor 登录表单

自定义 nFactor 登录表单可分为两部分

  • 将正确的登录模式发送到 UI
  • 编写一个处理程序来解释登录架构和用户选择

将正确的登录模式发送到 UI

在此示例中,在登录架构中发送一个简单的声明/要求。

为此,修改单个授权 .xml 文件。SingleAuth.xml 随 Citrix ADC 固件一起发送,并且可以在 /nsconfig/loginschema/LoginSchema 目录中找到。

发送登录架构的步骤:

  1. 通过 SSH 登录并放到 shell(键入“shell”)。

  2. 将单个 Auth.xml 复制到其他文件以进行修改。

    注意:目标文件夹不同于默认的 Citrix ADC 登录模式文件夹。

    cp /nsconfig/loginschema/LoginSchema/SingleAuth.xml /nsconfig/loginschema/SingleAuthDynamic.xml

  3. 将以下声明添加到单个授权动态 .xml 中。

    <Requirement><Credential><ID>nsg_dropdown</ID><Type>nsg_dropdown</Type></Credential><Label><Text>Logon Type:</Text><Type>plain</Type></Label></Requirement>
    
  4. 将 Citrix ADC 配置为发送此登录架构以加载第一个窗体。

    add loginschema single_auth_dynamic –authenticationSchema SingleAuthDynamic.xml
    
    add loginschemaPolicy single_auth_dynamic –rule true –action single_auth_dynamic
    
    bind authentication vserver aaa_nfactor –policy single_auth_dynamic –pri 10
    

脚本更改以加载表单和处理用户事件

您可以修改使管理员能够自定义显示登录表单的 JavaScript。在此示例中,如果选择了 LDAP,则会显示用户名和密码字段,如果选择了 OAuth,则会隐藏该字段。管理员也可以只隐藏密码。 管理员必须将以下代码段附加到 /var/netscaler/logon/LogonPoint/custom 目录中的 script.js。

注意:由于此目录是一个全局目录,因此创建一个门户主题并在该文件夹中编辑“script.js”文件,位于"/var/netscaler/logon/themes/<THEME_NAME>"

CTXS.ExtensionAPI.addCustomCredentialHandler({
    // The name of the credential, must match the type returned by the server
    getCredentialTypeName: function () { return "nsg_dropdown"; },
    // Generate HTML for the custom credential
    getCredentialTypeMarkup: function (requirements) {
        var div = $("<div></div>");
        var select = $("<select name='nsg_dropdown'></select>").attr("id", "nsg_dropdown");

        var rsa = $("<option></option>").attr("selected", "selected").text("LDAP").val("LDAP");
        var OAuthID = $("<option></option>").text("OAuth").val("OAuth");
        select.append(rsa, OAuthID);

        select.change(function(e) {
            var value = $(this).val();
            var ldapPwd = $($(".credentialform").find(".CredentialTypepassword")[0]);
            var ldapUname = $($(".credentialform").find(".CredentialTypeusername"));
            if(value == "OAuth") {
                if (ldapPwd.length)
                        ldapPwd.hide();
                if (ldapUname.length)
                        ldapUname.hide();
            } else if(value == "LDAP") {
                if (ldapPwd.length)
                        ldapPwd.show();
                if (ldapUname.length)
                        ldapUname.show();
            }
        });
       div.append(select);
        return div;
    }
});

最终用户体验

当最终用户首次加载登录页时,将显示以下屏幕。

本地化后的图片

如果在登录类型中选择 OAuth,则隐藏用户名和密码字段。

本地化后的图片

如果选择了 LDAP,则会显示用户名和密码。这样,可以根据用户选择动态加载登录页面。

此示例中使用的登录模式

<?xml version="1.0" encoding="UTF-8"?>
<AuthenticateResponse xmlns="http://citrix.com/authentication/response/1">
<Status>success</Status>
<Result>more-info</Result>
<StateContext></StateContext>
<AuthenticationRequirements>
<PostBack>/nf/auth/doAuthentication.do</PostBack>
<CancelPostBack>/nf/auth/doLogoff.do</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 either domain\username or user@fully.qualified.domain</AssistiveText><Text><Secret>false</Secret><ReadOnly>false</ReadOnly><InitialValue></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></InitialValue><Constraint>.+</Constraint></Text></Input></Requirement>
<Requirement><Credential><ID>nsg_dropdown</ID><Type>nsg_dropdown</Type></Credential><Label><Text>Logon Type:</Text><Type>plain</Type></Label></Requirement>
<Requirement><Credential><Type>none</Type></Credential><Label><Text>First factor</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>

重要: 有关各种 nFactor 相关主题的更多详细信息,请参阅 nFactor

nFactor 可扩展性