NetScaler – How to get rid of SSO / missing PRT Issues using Entra ID Phone Sign-in

Reading Time: 5 minutes

Overview

You’re using Microsoft Entra ID (SAML or OAuth) as IdP for your OnPrem CVAD or DaaS Environment. Your default is to use Citrix FAS so the User-Logon to the VDA happens with a virtual Smartcard (Certificate). When there is no Microsoft ADFS in place, your session doesn’t get a Primary Refresh Token (PRT) and this will result in SSO Issues regarding all kind of M365 Apps inside your HDX Session.

This Post will cover the configuration Details of “Method 4 – Citrix NetScaler with nFactor Authentication” from Julian’s Post about all insights of FAS and PRT Issues.

Citrix is working hard on that process, to eliminate FAS and use native Microsoft SSO “Technology” to provide SSO to the VDA with a PRT. At the moment, there is a private Tech Preview for Entra ID SSO, working only with Citrix DaaS as Control Plane and the VDA has to be Entra joined, too. (hybrid joined not supported yet) – so big things to come, soon.

As long as Entra ID SSO will not be GA (and working with hybrid joined machines, too) Consultants like me have to provide some Workarounds, like the following solution.

User Experience

Here’s a quick demonstration of how the Logonflow looks like for the Enduser.

Browsing to the NetScaler Portal, first step is to enter the UPN and go on:

Redirect to Entra ID is happening, as we are using OAuth, the UPN get’s pushed to Entra ID, there is no need to enter the UPN again. Now there’s the Push for Phone Sign-in:

Phone Sign-in on the Smartphone is always combined with Number matching:

After the successful Phone Sign-in, the redirect back to our NetScaler takes place. UPN is filled from the first “UPN-Only” Logonschema and read-only, so there’s no way to modify.

Now entering the Active Directory password finishes the Logonflow and the password is used for SSO to StoreFront / NetScaler Portal without FAS.

Also, the password is used for SSO to the VDA, which means we are getting a PRT and having no Issues regarding SSO with M365 Apps inside our HDX Session.

Configuration

Entra ID

First we have to create an Authentication strengths Policy to force Phone Sign-in so our User don’t have to enter their Password on the Part of the Entra-ID Logon – which would result in two times Password (Entra ID and NetScaler):

Choose only Microsoft Authenticator (Phone Sign-in):

An Authentication strengths Policy can only be bound to a Conditional Access Policy, so make sure to create a separate CA-Policy which hits only your NetScaler Enterprise Application in Entra ID.

In the Access controls section of the CA-Policy, you can bind your previously created Authentication strengths Policy:

Smartphone Configuration

Configuring Phone Sign-in is done inside the Microsoft Authenticator App. Select your Entra ID Account with registered MFA-Token:

A Passcode / Touch ID / Face ID for your Device is required and there is also the hint for the Device Registration (Entra registered), Sign On with your Entra ID Account and the registration Process is finished:

As soon as your phone is ready for Phone Sign-in, the Phone gets MS Entra registered:

Regarding GDPR, there is no personal data shown, expect the UPN, OS and the OS-Build.

NetScaler

Configure NetScaler via OAuth to Entra ID, details here.

Get the complete nFactor configuration from the CLI-Script below. One little note to add here, in my Script I am using an Active Directory Group-Filter for the example-group “ACL-NetScaler-NoMFA” to bypass MFA, so there is no redirect to Entra ID and the Logon is working with UPN + Password only for temporary Emergency NoMFA Logonmethods.

You can download my used OnlyUsername and OnlyPassword Loginschema XML’s here:

CLI Commands

################### NetScaler AAD NoFAS nFactor Config with UPN Only + LDAPS as last Flow
################### Recommended to use Authentication Strenghts Policy for the NetScaler AAD-Enterprise App with Phone Sign-In forced / configured
#replace customer with your customer name
#replace 172.16.10.14 with your LDAPS LB IP
#replace contoso.local with your FQDN
#replace ACL-NetScaler-NoMFA with your NoMFA-Emergency Active Directory Group


add authentication vserver AAA_vServer_nFactor_NA SSL 0.0.0.0 -maxLoginAttempts 3 -failedLoginTimeout 15
add authentication authnProfile AuthProf_AAA_nFactor -authnVsName AAA_vServer_nFactor_NA



add authentication ldapAction Auth_LDAPS_NoAuth_contoso.local -serverIP 172.16.10.14 -serverPort 636 -ldapBase "dc=contoso,dc=local" -ldapBindDn svc_ns@contoso.local -ldapBindDnPassword Start#123 -ldapLoginName UserPrincipalName -groupAttrName memberOf -subAttributeName cn -secType SSL -authentication DISABLED -passwdChange ENABLED -nestedGroupExtraction ON -maxNestingLevel 5 -groupNameIdentifier cn -groupSearchAttribute memberOf -groupSearchSubAttribute cn
add authentication ldapAction Auth_LDAPS_UPN_contoso.local -serverIP 172.16.10.14 -serverPort 636 -ldapBase "dc=contoso,dc=local" -ldapBindDn svc_ns@contoso.local -ldapBindDnPassword Start#123 -ldapLoginName UserPrincipalName -groupAttrName memberOf -subAttributeName cn -secType SSL -ssoNameAttribute sAMAccountName -passwdChange ENABLED -nestedGroupExtraction ON -maxNestingLevel 5 -groupNameIdentifier cn -groupSearchAttribute memberOf -groupSearchSubAttribute cn

add authentication OAuthAction OAuth_AAD_Customer -authorizationEndpoint "https://login.microsoftonline.com/c80325-f665-45a-950-f9d1b1b/oauth2/v2.0/authorize" -tokenEndpoint "https://login.microsoftonline.com/c8a025-f65-4b5a-90-f9d10a1b/oauth2/v2.0/token" -clientID 4174635b-75bc-44d5-b0e7-274dhd63gc2 -clientSecret XXX -CertEndpoint "https://login.microsoftonline.com/c8395-f65-4b5a-900-f91be1b/discovery/v2.0/keys" -userNameField preferred_username


add authentication loginSchema Schema_OnlyUsername -authenticationSchema "/nsconfig/loginschema/customer/OnlyUsername.xml"
add authentication loginSchema Schema_OnlyPassword -authenticationSchema "/nsconfig/loginschema/customer/OnlyPassword.xml" -userCredentialIndex 1 -passwordCredentialIndex 2 -SSOCredentials YES
add authentication loginSchema Schema_NoLoginSchema -authenticationSchema noschema


add authentication loginSchemaPolicy Schema_OnlyPassword -rule true -action Schema_OnlyPassword
add authentication loginSchemaPolicy Schema_EnterUPN -rule true -action Schema_OnlyUsername
add authentication loginSchemaPolicy Schema_NoLoginSchema -rule true -action Schema_NoLoginSchema


add authentication Policy Adv_Pol_LDAPS_UPN_contoso.local -rule true -action Auth_LDAPS_UPN_contoso.local
add authentication Policy Adv_Pol_LDAPS_GroupExtr_contoso.local -rule true -action Auth_LDAPS_NoAuth_contoso.local
add authentication Policy Adv_Pol_LDAPS_Emergency_contoso.local -rule "AAA.USER.IS_MEMBER_OF(\"ACL-NetScaler-NoMFA\")" -action NO_AUTHN
add authentication Policy Adv_Pol_LDAPS_AAD_contoso.local -rule true -action NO_AUTHN
add authentication Policy Adv_Pol_OAuth_AAD_Customer -rule true -action OAuth_AAD_Customer


add authentication policylabel GroupExtraction_contoso.local -loginSchema LSCHEMA_INT
add authentication policylabel LDAPS_Emergency_contoso.local -loginSchema Schema_OnlyPassword
add authentication policylabel OAuth_AAD_Customer -loginSchema LSCHEMA_INT
add authentication policylabel LDAPS_OnlyPassword_contoso.local -loginSchema Schema_OnlyPassword


bind authentication policylabel GroupExtraction_contoso.local -policyName Adv_Pol_LDAPS_Emergency_contoso.local -priority 100 -gotoPriorityExpression NEXT -nextFactor LDAPS_Emergency_contoso.local
bind authentication policylabel GroupExtraction_contoso.local -policyName Adv_Pol_LDAPS_AAD_contoso.local -priority 110 -gotoPriorityExpression NEXT -nextFactor OAuth_AAD_Customer


bind authentication policylabel LDAPS_Emergency_contoso.local -policyName Adv_Pol_LDAPS_UPN_contoso.local -priority 100 -gotoPriorityExpression END
bind authentication policylabel OAuth_AAD_Customer -policyName Adv_Pol_OAuth_AAD_Customer -priority 100 -gotoPriorityExpression NEXT -nextFactor LDAPS_OnlyPassword_contoso.local
bind authentication policylabel LDAPS_OnlyPassword_contoso.local -policyName Adv_Pol_LDAPS_UPN_contoso.local -priority 100 -gotoPriorityExpression END


bind authentication vserver AAA_vServer_nFactor_NA -policy Schema_EnterUPN -priority 100 -gotoPriorityExpression END
bind authentication vserver AAA_vServer_nFactor_NA -policy Adv_Pol_LDAPS_GroupExtr_contoso.local -priority 10 -nextFactor GroupExtraction_contoso.local -gotoPriorityExpression NEXT

DaaS

The mentioned Configuration is also usable for Citrix DaaS Cloud-Workspace deployments. Use the NetScaler’s configuration for an OnPrem NetScaler / Hosted Cloud NetScaler (Workspace Authentication set to Citrix Gateway) or Adaptive Authentication (managed NetScaler on Azure)

Just one important note here for DaaS – you have to use SAML instead of OAuth to Entra ID – because “OAuth (DaaS) to OAuth (Entra ID)” is currently not working – I hope I can post an update, soon. Details and why see here.

Summary

Another technical solution to avoid missing PRT’s, within some Pro’s and Con’s – as always.

3 comments

  1. Great article Julian. Two questions:

    1. Since it is the LDAP auth aka second factor where (the later, please see below) PRT is obtained, the first factor might as well be e.g. SAML, correct? As long as we have the UPN handy and ready for the 2nd factor..

    2. Kinda hard to imagine where the PRT is really coming from. So we are getting a KRB ticket from 2nd factor and passing- that -through (through SF all the way to VDA).
    Is it at the point of VDA logon where the PRT is obtained? Is that based on the fact that such a VDA is (must be) hybrid (EntraID) joined?

    Love your work and articles.
    Peace out.

Leave a Reply

Your email address will not be published. Required fields are marked *