Citrix DaaS – Prevent Session takeover when using NetScaler as IdP followed by SAML

Reading Time: 4 minutes


A customer of mine recently came across a way to sign in to Cloud Workspace with any other user, provided you sign up before with some valid credentials – for example your own.

The following constellation is affected by default:

  • Using Citrix Gateway as IdP for Cloud Workspace (OAuth), where Citrix Gateway doing first a group extraction (NoAuth) followed by redirecting the Auth-Flow to another IdP (SAML, tested with Azure AD)
  • Using Adaptive Authentication as IdP for Cloud Workspace (OAuth), where Adaptive Auth doing first a group extraction (NoAuth) followed by redirecting the Auth-Flow to another IdP (SAML, tested with Azure AD)

Here’s a simple demonstration video. First I’m logging in with my (Julian) credentials. After sign-out on Cloud Workspace, I am able to logon with any other (Ben’s) user, without prompting any passwords or MFA. It’s working fine until deleting cookies (Closing browser)

This post contains a simple user-verification on the NetScaler side to prevent the issue.


What is causing the issue? Signing out on Cloud Workspace is not killing the active session between SAML SP (NetScaler) and SAML IdP (Azure AD) so if any other user is asking NetScaler again, there’s a passthrough to Azure AD.

The following simple checkmark can solve the security issue, but is negatively impacting the User Experience of your corporate devices, because a synced browser also has to sign in with UPN instead of doing SSO.

Force Authentication will force the IdP (Azure AD) to re-authenticate when a request comes from the SP (NetScaler):

SAML Server Force Authentication setting

Instead of using the Force Authentication setting, let’s check the AAA.USER.ATTRIBUTE (Entered Username / UPN on the OnlyUsername NetScaler Logonpage) is matching the AAA.USER.NAME for the SAML-flow.

Script if you’re preferring the CLI.

GUI Configuration

For the used OnlyUsername bound loginschema, I’m using Attribute 15 to get the User Credentials put into:

LoginSchema User Credential Attribute 15

Create another Login Schema – noschema with enabled SSO:

Passthrough noschema with SSO

Create a NO_AUTHN auth-policy containing the AAA.USER.ATTRIBUTE(15).EQ(AAA.USER.NAME) Expression:

No-Auth User-Validation Policy

Create a LSCHEMA_INT PolicyLabel and bind your previously created User-Validation Auth-Policy:

User-Validation PolicyLabel

Create a PolicyLabel bound to the Passthrough Login Schema. Bind your AAD SAML Policy, followed by the previously created User-Validation Policy:

Passthrough PolicyLabel

Putting it all together – bind the LDAPS GroupExtraction followed by Passthrough Authentication Policy to your AAA vServer, where the DaaS OAuth IdP Policy is also bound to:

Bound Auth Policy to AAA vServer

Also bind the OnlyUsername loginschema Policy:

Bound loginschema Policy to AAA vServer

Script Configuration

#Securing the SAML Flow when NetScaler (Adaptive Auth or Citrix Gateway) is used as first IdP for Citrix DaaS, followed by another SAML IdP (Tested with Azure AD)
#Doing a Username-Validation so it's not possible to sign on in the Name of anothers User

add authentication loginSchema LoginSchema_OnlyUsername -authenticationSchema "/nsconfig/loginschema/LoginSchema/OnlyUsername.xml" -userCredentialIndex 15
add authentication loginSchemaPolicy lschema_OnlyUsername -rule true -action LoginSchema_OnlyUsername

add authentication Policy AuthPol_NoAuth_ValidateUser -rule "AAA.USER.ATTRIBUTE(15).EQ(AAA.USER.NAME)" -action NO_AUTHN

add authentication policylabel AuthPol_NoAuth_ValidateUser -loginSchema LSCHEMA_INT
bind authentication policylabel AuthPol_NoAuth_ValidateUser -policyName AuthPol_NoAuth_ValidateUser -priority 100 -gotoPriorityExpression NEXT

add authentication loginSchema Passthrough -authenticationSchema noschema -SSOCredentials YES
add authentication policylabel AuthPol_Passthrough -loginSchema Passthrough
bind authentication policylabel AuthPol_Passthrough -policyName AuthPol_SAML_HdxlabAAD -priority 100 -gotoPriorityExpression NEXT -nextFactor AuthPol_NoAuth_ValidateUser

bind authentication vserver AAA_vServer_DaaS -policy lschema_OnlyUsername -priority 100 -gotoPriorityExpression END
bind authentication vserver AAA_vServer_DaaS -policy AuthPol_LDAPS_NoAuth -priority 70 -nextFactor AuthPol_Passthrough -gotoPriorityExpression NEXT
bind authentication vserver AAA_vServer_DaaS -policy oAuthPol_DaaSCTPDemoTenant -priority 100 -gotoPriorityExpression NEXT


Here’s the demonstration video containing the above user-verification configuration. Before redirecting to SAML IdP (Azure AD) NetScaler is blocking the Auth-Flow, because the UPN is not matching:

I hope this Post is making a few NetScaler configurations a bit more secure.


  1. This article is essentially a guide on how to correct faulty configuration. If someone has executed such a configuration, it means they lack expertise in the subject matter. Moreover, after implementation, the solution should undergo an audit to identify configuration errors that impact security.

Leave a Reply

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