Citrix FAS – SID Lookup Mismatch with Citrix DaaS

Reading Time: 6 minutes

Issue

Recently I tried to setup a Citrix DaaS environment with OnPrem VDA’s and FAS for a working Azure AD B2B scenario. Every B2B customer’s UPN suffix is created OnPrem with the matching Shadow Account.

Update – August 23, 2023

It is now possible to use cip_sid (SID) OR cip_upn (UPN) Attribute when using SAML 2.0 as the Identity Provider for DaaS – so the following mentioned post for the usage of a NetScaler isn’t a requirement, anymore.

Use upn OR sid attribute, at least one is required

You are able to delete cip_sid which will enter it in cursive:

cip_sid is able to delete

Start using the Citrix Cloud SAML SSO Azure AD Gallery Enterprise Application and modify the Attributes & Claims, delete the cip_sid Claim:

Delete cip_sid Claim when using the Citrix Cloud SAML SSO Gallery App

That’s it, now I am able to login to DaaS via SAML 2.0 to Azure AD with my employee tenant and the mapping to my OnPrem LAB Shadow Account AD User is working fine – no error because of no SID-Check:

FAS certificate for the matching OnPrem Shadow Account without a SID-Error

Begin of the older Post – Background Information

When starting a HDX Session via a B2B Azure AD User with a matching Shadow Account, SSO to the VDA never works. On FAS, you’re getting the following Eventlog issue with Event ID 103:

[S103] Server [CC:XXXXXXXX] requested UPN [julian.jakob@lab.ch] SID S-1-5-21-984895203-1488828186-1863578951-5285, but lookup returned SID S-1-5-21-977221278-2530229883-4204116001-9174. [correlation: cc#967472c8-4342-489b-9589-044a24ca57d1]

Citrix FAS is checking the SID of my Azure AD User and comparing that to my OnPrem Shadow Account AD User. Logically, the SID’s in this B2B situation never match. There is no difference when using the DaaS Azure Active Directory Connector (which is using OAuth and OpenID Connect) or SAML 2.0.

When doing a typical sync from OnPrem AD to Azure AD with AD-Connect or Cloud Sync to only one tenant, everything will work fine as the synced SID’s are matching.

Looks like the issue is present since years (Eg Citrix Discussions) but never found any listed solution for this.

But why is it working fine with OnPrem CVAD + NetScaler with SAML to AAD + FAS and some B2B customers? The difference is the authentication-process!

When using OnPrem NetScaler as the frontend, NetScaler inspects the UPN and finds the corresponding shadow account, the shadow account’s SID is used and the session launches fine on the VDA with SSO.

When using Workspace Service / DaaS as the frontend, the session is created for the principal account, not the shadow one, and as FAS will lookup the user account by UPN and get the SID of the shadow account, this will NOT match the SID of the Workspace Service session. As a security precaution, FAS will not perform SSO to the VDA and the above mentioned eventlog S103 will take place.

The goal would be to disable the SID-Check, as this breaks the architecture of how shadow accounts work. When doing SAML 2.0 / Azure Active Directory (OAuth & OpenID Connect) / Citrix Gateway or Adaptive Authentication mechanisms with your DaaS Tenant, you can see the mandatory for SID.

SAML 2.0:

SAML 2.0 required SID Attribute

OAuth:

I’ve already written about Citrix Gateway as an IdP for Citrix DaaS and the needed requirements – SID included!

Finding the Way

To push the missing Shadow Account SID to Citrix DaaS, it was clear to use OnPrem NetScaler / Adaptive Authentication / NetScaler on Azure / NetScaler “on whatever” connected as the “Citrix Gateway” Authentication Method in DaaS Identity and Access Management and also enabled in Workspace Configuration.

I’ve setup the OAuth IdP Policy and Profile, bound to an AAA vServer and bound also a SAML Azure AD Auth-Policy, which is configured as an Enterprise Application in Azure AD.

The way it should work for the authentication to take place than looks like customer.cloud.com -> NetScaler OAuth Policy -> Azure AD SAML Policy -> NetScaler OAuth Policy -> customer.cloud.com but I got authentication errors from Citrix Workspace Service.

Checking my ns.log brought me to the following important notes:

"OAUTHIDP: CC IDTOKEN: user: <julian.jakob@lab.ch>'s claims are: sub:\, name:, upn:, email:, ctx_auth_alias:, cip_domain:, cip_forest: sid:, oid:, amr:["external"], nonce:6380854677429951, familyname:, givename:, domain: , groups len 0" 
"OAUTHIDP: CC IDTOKEN: user: <julian.jakob@lab.ch>'s claims are insufficient to perform federation with Citrix Cloud, domain len 0, displayname_len 0 cip_domain_len 0, cip_forest_len 0, sid_len 0, oid_len 0, upn_len 0, email_len 0 " 

The claims like name, upn, email and also SID are empty. As we’re doing OAuth followed by SAML, no authentication takes place on the NetScaler(OnPremAD)-side, how should the required attributes ever reach Citrix Cloud?

Solution

One Solution is to deploy two extended Attributes to your Azure Active Directory, containing guestShadowUPN and guestUserOnPremSID. It’s described in detail in this Article, but as you have to do the mapping to every user from every B2B customer, that’s no option and to much manual work to do for any enterprise organizations.

My preferred way in this situation is the following:

You have to insert a OnlyUsername.xml No-Auth LDAPS LoginSchema in between the flow, so it looks like customer.cloud.com -> NetScaler OAuth Policy -> NetScaler OnlyUsername LoginSchema -> Azure AD SAML Policy -> NetScaler OAuth Policy -> customer.cloud.com

AAA bound Advanced Authentication Policy

The user needs to enter their sAMAccountName or UserPrincipalName for extracting all required OnPrem-AD attributes, also containing the SID of the matching OnPrem Shadow Account, which is than send (after the successful login to Azure AD) to Citrix Cloud via the OAuth IDTOKEN, SSO to your VDA is working fine and Error S103 on FAS Servers is gone!

User Experience

Here’s a successful test with my Option Consulting AAD User logging in to my HDXLAB AAD Tenant and this is how the user experience looks like. NetScaler sends the required SID of my HDXLAB OnPrem Shadow Account to Workspace Service.

User Experience Logon-Flow

Now this is how the ns.log looks like:

"SAMLIDP: LOGIN SUCCESS; Core <0>, adding SAML/OAUTH entry with action <oAuthProf_DaaS> in session for user <julian.jakob@lab.ch>"  
"OAUTHIDP: CC IDTOKEN: user: <julian.jakob@lab.ch>'s claims are: sub:HDXLAB\julian.jakob, name:Julian Jakob, upn:julian.jakob@lab.ch, email:julian.jakob@lab.ch, ctx_auth_alias:Julian Jakob, cip_domain:hdxlab.ch, cip_forest:hdxlab.ch sid:S-1-5-21-9772812045-2530229883-4204116001-9255, oid:b33376b0-3aed-4e1f-ejj2-eed0d4520a86, amr:["password","external"], nonce:638085492672781615, familyname:Jakob, givename:Julian, domain: HDXLAB, groups len 1"

Commands

Here are the CLI commands containing this setup.

#Adding OAuth Profile
add authentication OAuthIDPProfile oAuthProf_DaaS -clientID 12345 -clientSecret 12345 -redirectURL "https://accounts.cloud.com/core/login-cip" -issuer "https://aaa.customer.com" -audience (clientid) -skewTime 10 -encryptToken ON -sendPassword ON
add authentication OAuthIdPPolicy OAuthPol_DaaS -rule true -action oAuthProf_DaaS

#Adding Azure AD SAML Profile and PolicyLabel
add authentication samlAction META_saml_server_OPTION -metadataUrl "https://login.microsoftonline.com/b6bc373-b78cfcacd6/federationmetadata/2007-06/federationmetadata.xml?appid=e36ca49e-e8-e7665cb4a5" -samlSigningCertName wildcard.customer.com -samlIssuerName "https://aaa.customer.com" -enforceUserName OFF -logoutURL "https://login.microsoftonline.com/b67373-b82-4b0-b235-70dcccd6/saml2" -logoutBinding REDIRECT -metadataRefreshInterval 3600
add authentication Policy META_Saml_Server_Azure_OPTION -rule true -action META_saml_server_OPTION
add authentication policylabel AuthPol_SAML_AAD_Option -loginSchema LSCHEMA_INT
bind authentication policylabel AuthPol_SAML_AAD_Option -policyName META_Saml_Server_Azure_OPTION -priority 100 -gotoPriorityExpression NEXT

#Adding LDAPS NoAuth Group Extraction Action and Policy
add authentication ldapAction srv_ldaps_lb_GroupExtractionNoAuth -serverIP 10.10.10.10 -serverPort 636 -ldapBase "DC=contoso,DC=local" -ldapBindDn serviceuser@contoso.com -ldapLoginName UserPrincipalName -groupAttrName memberOf -subAttributeName CN -secType SSL -authentication DISABLED -passwdChange DISABLED -nestedGroupExtraction ON -groupNameIdentifier sAMAccountName -groupSearchAttribute memberOf -groupSearchSubAttribute CN
add authentication Policy AuthPol_LDAPS_NoAuth -rule true -action srv_ldaps_lb_GroupExtractionNoAuth

#Creating OnlyUsername Loginschema
add authentication loginSchema LoginSchema_OnlyUsername -authenticationSchema "/nsconfig/loginschema/LoginSchema/OnlyUsername.xml"
add authentication loginSchemaPolicy lschema_OnlyUsername -rule true -action LoginSchema_OnlyUsername

#Creating AAA vServer and binding Policies
add authentication vserver AAA_vServer_DaaS SSL 0.0.0.0
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_SAML_AAD_Option -gotoPriorityExpression NEXT
bind authentication vserver AAA_vServer_DaaS -policy oAuthPol_DaaS -priority 90 -gotoPriorityExpression NEXT

#Binding your cert to vpnglobal is a requirement
bind vpn global -certkeyName wildcard.customer.com

Summary

I hope this Post will save you some time troubleshooting FAS SSO issues with B2B / Shadow Accounts when using Azure AD or any IdP where Citrix DaaS checks the SID as a requirement.

Hopefully there will be an option to disable SID-Check in DaaS, soon – as mostly the Unique User Identifier (Name ID) in the world of IdP’s primary focusses on UserPrincipalName.

By the way, you can also use OAuth to Azure AD instead of a SAML Policy, if you want to stay permanent on OAuth 🙂

Thanks to Nathanael Davison for the open minded discussion about this issue.

6 comments

  1. Hey Julian. Thanks for this updated article. Im into this issue myself. I have a citrix cloud tenant with two domains. Workspace is using AzureAD as idP. My goal was to publish a vdi to a user in both domains. For the second domain the users upn is the same as the first domain. Have cloud connectors and fas servers in two resource groups. So I would love to be able to disable this SID check. Do you if this is possible if we create a support case?

    Regards
    Geir Ove Bjørseth

    1. Hello Geir,
      thanks for your comment! You can try to raise a support case / feature request, I know that there are changes coming for this scenario, but there is no ETA yet.

    2. Hi Geir

      If you raise a support case and ask them to escalate it to engineering using a CCPHELP ticket I can assist you. We will need a full discription of the context of your case and I may request a call with you to view your SAML and AD config for real time debugging.

      ‘Workspace is using AzureAD as idP.’

      If you mean that Workspace is using AAD OIDC you will need to switch to SAML to use the “Simplified SAML” feature and remove the SID. This avoids the “SID mismatch” issue in DaaS this article is intended to solve. There is no AAD OIDC equivalent of “Simplified SAML” so workspace would need to be updated to use SAML as the logon method.

      Happy to discuss more on a call if u need assistance.

      Regards Mark Dear
      (Customer Quality Engineer, Citrix Engineering)

  2. Useful AD PowerShell to add a large number of Alt UPN Suffixes to the AD forest/domain

    # Load the Active Directory Module
    if (-not (Get-Module ActiveDirectory))
    {
    Import-Module ActiveDirectory
    }
    # Get existing list of Alt UPN Suffixes
    (Get-ADForest).UPNSuffixes
    # Use “add” OR “remove”
    $Action = “add”
    $AltUPNSuffixes = @(“test1.com”,”test2.com”)
    foreach($AltUPNSuffix in $AltUPNSuffixes)
    {
    Get-ADForest | Set-ADForest -UPNSuffixes @{$Action=$AltUPNSuffix}
    }
    # Get existing list of Alt UPN Suffixes
    (Get-ADForest).UPNSuffixes

Leave a Reply

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