Explore Yubico

Making use of Azure B2B in a Citrix deployment – OnPrem

Why do you want this?

In this post I will walk your throug leveraging Entra ID and the b2b feature within, together with your Citrix deployment.

This gives you the possibility to give external users access via their own credentials.

It also opens up the usage of all of Entra ID´s authenication methods for your users, passwordless, FIDO etc.

Using Entra ID where you can, is a great and powerful way to help you leverage some of the best security mechanisms to protect your users identity, and access to your data, so why would you not leverage it where you can?

The setup below is something I have had running for a number of years and has proven to be very useful and comfortable to use.

The plan was to post this long ago, but that did not happen, but now I finally got around to it, and as a bonus I will post a seperate post this week that covers the same setup, but with Citrix Cloud (DaaS) instead of the traditional Citrix On-Prem infrastructure, good stuff 🙂

So let´s get started.

Prerequisites and Components.:

  • Microsoft Entra ID (Azure AD) – with P1 level.
  • Azure Subscription
  • On-Prem AD with Shadow accounts
  • Citrix NetScaler (ADC)
  • Citrix Federated Authentication Service (FAS)
  • Server with Enterprise CA role
  • Citrix Virtual Apps and Desktops (CVAD)

Component.: Microsoft Entra ID

Think of Entra ID as your user catalog, controlling and securing access to the service your are providing to the users accessing it. We are trusting Entra ID to do the user verification for us, to be our source of truth.

Our goal here is to provide users access to a Citrix CVAD environment, that you manage and control. Since we are controlling the Entra ID that handles the authentication, this means we can control, via our Conditional Access rules, the requirements for MFA etc to reach our resources, regardless of what they have configured on their own end. 

We also want the users to be able access the environment with their own existing credentials. To make this possible, we will make use of  the b2b feature within Entra ID. This means you do not need to handle the credentials used by the users to access the service, and focus only on the parts that your are responsible for.

This means we will use Microsoft Entra ID as the IdP (Identity provider) for the Citrix Environment, create an SAML based “Enterprise Application” in Microsoft Entra ID, add the external users as guests in Entra ID, and give users access via this Enterprise application we will create.

Preferably you will create a group (dynamic or static) in Entra ID, to add to the Enterprise application, making the admin overhead simpler. *

Depending on the scale or context of the deployment, you can opt to create a seperate Entra ID for this “service” or use your existing Entra ID.
In this case I am setting this up to deliver a service to people outside of the organization, and prefer to not get alot of external /guest users in “My // Internal Organizations” Entra ID. This keeps this environment isolated and managed as its own “service”, and limits clutter. **

*To be able to assign groups to the enterprise application you need P1 License level on Entra ID. This is also a requirement to add a “non-gallery” enterprise application.

** You choose what  fits your intended setup

Component.: Azure Subscription – To use against Microsoft Entra External ID.

A while back Microsoft changed the licensing model for external collaboration with Entra ID (Azure AD). Previously you had to license the environment with 1 P1 license pr 5 guest accounts//b2b user.
This is now changed to a MAU model (Monthly Active Users), you can read more about that in Microsoft learn site here.

This means you have to add a Azure subscription to the Entra ID environment, to handle the billing for the MAU users, should your MAU count exeed the included free usage. *

*The first 50 000 MAUs per month are free for both Premium P1 and Premium P2 features.

More details on pricing here.

Component.: On-Prem AD with Shadow accounts

In this post, we are basing this on a Classic Citrix environment (On-Prem CVAD).
This means we have a Active Directory Domain Services involved (ADDS).

This AD is will contain your users/groups/computers as normal.
To provide access to our external (b2b) users, we will leverage shadow accounts.
These are normal AD user objects in your ADDS. These users will have their UPN and E-Mail attribute set to the same as the external users actual information. So if your external user has E-Mail address of user@somedomain.com, you will add somedomain.com as a upn suffix in the ADDS environment and set the users E-mail and UPN to match this on the shadow account.

For password you can set something random and secure, as the user does not need this password on their end to access the environment – the authenticate with their own existing credentials that you do not manage. *

*Exception here is if the user needs access to applications when inside the environment that does not use integrated authentication – meaning they will need the acutal AD user password to access the app after loging in to the Citrix environment.

Component.: Citrix Federated Authentication Service (FAS)

We want the users to get access with proper SSO from when they enter the service.
Because we are using Entra ID as IdP, SAML authentication, and shadow accounts on the inside, we need to implement Citrix FAS to handle the SSO into the session host.

Citrix FAS issues a virtual smart card for the users shadow account, that smartcard is used to logon to the session host.

Component.: Citrix NetScaler (ADC)

The NetScaler will act as our frontend to integrate between our IdP (Entra ID) and our ADDS.
The NetScaler will be configured on our Enterprise App in Entra ID. When the user accesses the NetScaler gateway URL, the user will be redirected to Entra ID for user verification (Your managed Entra ID tenant), MFA is enforced, etc – after Entra ID verifies the user, the user gets sent to the gateway and gets a list of their available resources to start.

Starting the application/desktop should be seamless as FAS handles the SSO part for the backend shadow account belonging to the user.

Setting it up

Setup Entra ID for Citrix on-prem

In the Entra ID you choose to use for the setup we need to configure an Enterprise Application to use for SSO via SAML against the NetScaler Gateway.

When you create the app and configure the SSO settings, remember to take a note of the Entity ID and urls provided in the app.
Also download the Base64 certificate – you will need this when you configure the NetScaler.

Enable MAU billing model for guest accounts

First, to enable the MAU model, you need to make a quick change in your Entra ID, and link external identities to an Azure Subscription. This is to handle billing for authentications above the already included 50.000 pr month.

To do this, go to the external identities section in Entra ID – Entra ID>External identities>Linked Subscriptions.

1: Select Linked Subscriptions in the left navigation panel
2: Check the tenant you want to link
3: Click Link subscription
4: Select the subscription to use
5: Select the Resource group to use
6: Click Apply

Setup the Enterprise app

In the Entra ID you choose to use for the setup we need to configure an Enterprise Application to use for SSO via SAML against our NetScaler. We will use a custom/ non-gallery app for this – this requires your Entra ID to be at P1 level minimum.

When you create the app and configure the SSO settings, remember to take a note of the Entity ID and urls provided in the app.
Also download the Base64 certificate – you will need this when you configure NetScaler.

Create the Enterprise App

1: Go to the enteprise applications blade in your azure portal
2: Click add to create a new application
3: Chose Enterprise application in the dropdown menu

1: On the browse Microsoft Entra Gallery page, click Create your own application
2: Input a name for your enterprise application
3: Select the option for Non-Gallery application
4: Click create to create the initial application

Configure SSO settings

1: Once the application is created, click the Single Sign-on selection in the left bar and select SAML

Basic SAML Configuration

1: After selecting SAML, still on the SSO settings, input the details for your NetScaler Gateway in the Basic SAML Configuration settings.
(Entity ID here will be used later on the NetScaler SAML profile and must match on both ends, you could use the url for your gateway virtual server)
Reply URL is your gateways url with the appended with the “/cgi/samlauth” on the end.

2: Take a note of the App Federation Metadata URL, and download the Base64 certificate for the NetScaler configuration later.
3: Take a note of the provided URLS and Identifier for NetScaler configuration later.

User assignment for Enterprise app

Next is to configure your Entra ID users/groups access to the Enterprise application.

Limit app to a subset of users/groups

If you want  to limit the SSO app to a specific set of users or groups:
(I would reccomend using a group – i.e a dynamic group targeting guest user objects)

1: Click the “Users and Groups” option in the left bar
2: Click “Add user/group”
3: Click Users in the Add Assignments page
4: Select your users or groups to give access to the SSO app
5: Click select, and then the Assign button to complete assignment.

Do not require assignment

1: Click on the Properties option in the left navigation bar on the Enterprise Application
2: Set Assignment required to No
3: Click Save

Setup NetScaler

Next we will setup the NetScaler side to connect the two parts together for authentication.

On the NetScaler side we need to configure:

  • NetScaler virtual gateway or gatweway + AAA virtual server*
  • SAML policy
  • Bind certificate globally
  • Modify NetScaler config file to exclude the subject field in the saml token**
  • Enforce authentication from the IdP***
  • Make config change so the file is persisted after reboots of the NetScaler

The SAML policy is where we will put in the details we get from Entra ID when we create the Enterprise App. (Entity ID, Login/our url certificate etc)

I will not put the full guide on seting the NetScaler parts up here, as others already have detailed steps published already. So you can look at the step by step instructions from Carl Stalhood here.
I will include the setup to get it up an running without the AAA setup and based on user access via web browser.

Personally I believe that nothing else should be needed these days, remembering a simple webpage is simple for users, and also gives you some room to work should you need to change portals etc in the future etc, a web browser is mostly what you need to access services used day to day in real life these days. In most cases adding the account to a native app etc is just more administrative overhead. There are of course deviations on this, but that can be handled case by case.

Step-by step

I assume that you already have a NetScaler gateway available and configured with an IP, Certificate and a public dns record pointing to it from the web and will not include those parts of the gateway setup.

Create SAML Server

1: Login to your NetScaler, and head over to “Citrix Gateway>Policies>SAML>Servers”
2: Click Add to create a new SAML profile

1: Input a name for your SAML profile
2: In the SAML IDP Metadata URL field you input the Federation URL noted down from Entra ID previously.
3: For User Field – enter the name of the SAML Claim from the IdP that contains the value that matches the userPrincipalName of your On-Prem ADDS shadow accounts. This defaults to the NameID field, but you might have to use a different claim, like emailaddress. (when using b2b accounts in Entra ID, the UPN in your Entra ID will include #EXT etc in the name, this will obviously not work. If you set this to mail, it will use the actual e-mail address on the b2b account)
4: For signing Certificate  – select the certificate used on your NetScaler gateway
5: For Issuer Name –  you input the name you set for Entity ID in the Enterprise App in Entra ID – they must match.

If you unselect the Import Metadata option, you may find the following fields already populated – you may need to save the profile and go back to it.
In these fields Redirect and logout url are the URLs you noted down from the Enterprise App in Entra ID.

For SAML Binding, set POST.
For Logout set, Redirect.

Scroll abit down, and you can a similar relay state rule for your profile.
This is to protect you from session hijacking in accordance to Citrix docs

Scroll down an click more and configure the following

Ensure Signature and Digest settings are set tup SHA256 if not already.

To prevent issues with multiple tokens in the browser session you can select to enable the Force authentication flag. ***
Scroll down and click the OK button to save the profile.

Create SAML Policy

Next we create the SAML policy.

1: Click over on the Policies tab

2: Click Add  to add a new policy.

1: Give your policy a name
2: In the Server dropdown, select the SAML profile you created
3: in expression set “ns_true”

Bind SAML Policy to Gateway

Last step is to bind the SAML policy to you NetScaler for authentication

Head over to Citrix Gateway>Virtual Servers, and click on your NetScaler Gateway.

Scroll down to the Basic Authenticatin field, and click the “+” option to bind a policy.

In the Choose Type option, select SAM for policy, and Primary for type, and click Continue.

Next click in the Select Policy option that comes up to get to the page where you select your policy

Select your SAML policy in the list, and click the Select button, then clikc Bind, and you are back to your NetScaler Gateway. Scroll down and click Done.

That is it for basic NetScaler config to get access via Entra ID and B2B.

The next you will need to do is have FAS up and running.


*If you only configure a SAML policy and bind it directly to the gatweway, you will not be able to use the functionality to add an account to the local workspace app client on the endpoints, only via web browser as the “portal” to start applications.

If you need your users to be able to add their account in the full Workspace App client you will also need to configure a AAA virtual server with needed components for use together with the NetScaler Gateway.
(Authenitcation profile, policy labels etc)

** Entra ID does not support the Subject field in authentication requests, as refrenced here

If you do not exclude the subject field from the authentication request coming from the NetScaler > Entra ID, you will get an error like this.:

Configuration change to exclude subject on the NetScaler

SSH into your NetScaler and run the following commands to make the needed changes, and make it is persist over reboots.

#Binding your cert to vpnglobal is a requirement
bind vpn global -certkeyName wild-iteam
#Exclude subject
nsapimgr_wr.sh -ys call=ns_saml_dont_send_subject
#persist  config over reboot
touch /nsconfig/rc.netscaler
chmod 644 /nsconfig/rc.netscaler
echo "nsapimgr_wr.sh -ys call=ns_saml_dont_send_subject" >> /nsconfig/rc.netscaler
#save config
Save nsconfig

***If you/your users have multiple Microsoft credentials in the browser session when accessing the NetScaler URL – if they get the prompt to select account to use as shown in the image below – you may experience that you get an error at logon reffering to “AADSTS90015: Requested query string is too long.”

This comes from the token that exists in the browser session is not accepted. To work around this, enable the Force authentication flag on the NetScaler SAML profile. This will remove the account selection window, and force the user to input their e-mail address to logon. Ensuring you get a fresh and valid authentication token.

Setup FAS

For FAS you configure this like normal, and set it up with rules to fit your requirement in terms of limiting user groups / VDA server / Storefront and FAS servers if you do not want to use the default “everything” configuration.

I will not put the full guide on seting the FAS parts up here, as others already have detailed steps published already. So you can look at the step by step instructions from Carl Stalhood here, and official Citrix documentation can be found here

You are now ready to test logging on with a user via your Entra ID and b2b user objects.
To do this you will need to create shadow accounts in your ADDS and create the b2b objects in your Entra ID. How you choose to create the users on-prem and in Entra ID is up to you, but I will include an example here on how this could be done.

Provisioning/managing users/tenants

When it comes to creating the users you want to give access there are multiple ways of doing this.

You could create the users first in Entra ID, and then sync the b2b users down to your on-prem AADS.

One way of doing that is with the “B2B to AD” sync script located here.
The script can run as a task on intervals to get new users etc.

However this will sync all users to one OU in AADS by default, so you will need to customize that should you want to seperate different users to different OU’s. If you have alot of different “tenants” this may not be ideal.

The other way is to do it in the opposite direction, meaning we create the shadow accounts in AADS first, and use the shadow accounts to provision the b2b accounts in Entra ID.
This is my preferred way, as it means I can create my structure in AADS, and provision the users to Entra ID after it is setup. Since you are giving access to the service you manage, you probably have full insight into who is going to be given access as well.

My way of doing this, is to create a collection of “onboarding” scripts, and put a GUI on top of that.
This way I have a simple “application” that helpdesk etc can use to do what is required to create a new “tenant” add/delete a user, create unique service users provision the b2b users, and also to create documentation on what is onboarded.  Since the process of onboarding is scripted, this means I can define my OU structure, groups pr tenant etc as a part of the onboarding process, meaning all users get created the same way, minimizing human errors. (if something is configured wrong, you have the same thing wrong across the board).

How does this look on my end?

In my environment I created a collection of scripts for each of the functions I want to be able to do in a simplified way, or i.e  orthers can do it without needing to know all the gritty details.

The script collection is put together and baked into a simple GUI based “app”. This way the scary powershell code and terminal window do not need to scara away others from using the functionality.

To create a simple GUI for a s script you can cut down the effort by leveraging stuff like poshgui, to create the code for the gui for you based on your  layout.

Poshgui gives you a quick way to create the layout in a simple  WYSIWYG  editor, and serves you back the code for the GUI (Winframe).

You then put your code together to make it usable.

For the one I made, i wanted the following functionality in the GUI.:

  • Enter info for a new “tenant”
  • Import the users for the new tenant
    • Script handles OU creation, GPO links, passwords, service accounts, security groups and members, as well as nesting against central groups used to publish resources on the Citrix side. This way all “tenants” get set up their own way, with their own prefixed groups in accordance to naming conventions etc. And I can publish the citrix apps against a central group for all “tenants” using the same app/resource. This means I can control everything based on the groups and rrarely need to go into Citrix WEM, Studio etc to manage user access.
  • Add new user(s) to exisiting tenant
  • Delete user(s) for exisiting tenant
  • Create dedicated SQL instansce for a tenant
  • Provisiong the tenants shadow users to Entra ID b2b
  • Create initial documentation at point of onboarding

This ended up looking like this with options for the functions to initiate.

To provision the Entra ID b2b users I use the option for provisioning in the gui, and the terminal window gives me the option to choose what tenant to provision users for.

After selecting the tenant nr and hitting enter.

The script takes the info of the shadow accounts, connects to Entra ID using service principal/Certificate, and does the b2b invitation. You can in that process set the b2b creation to send a invite message on email to the users once they are provisioned . I opt to not do this,

The scripts shows in the terminal status for b2b generation as it moves throught the tenant.

Once it is finished, the menu is active again and I proceed with next action or exit if that was all i needed to do.

At this point the users can access the environment with their own credentials.

Connect to Entra ID via certificate auth and script

To make the process of provisioning users via script you can set up authentication to your Entra ID via Certificate. This way you can connect via  a service principal and certificate on your “management workstation” unattended – meaning the usage of a b2b provisioning script via self-made GUI or automated scheduled task can be achieved for less hassle in user management.


To connect with certificate you create a app registration in Entra ID

Give your app registration a name and create the registration

Go to the Overview page of the registration and take a note of:

Application (client) ID

Directory (tenant) ID

Object ID

Head down to API permissionsand give the registration the needed permission to add b2b users and add them to a group. Also grant admin consent for the registration

Create a certificate on the endpoint where you are going to connect from

Install-Module Microsoft.Graph -Scope AllUsers
$Cert = New-SelfSignedCertificate -DnsName youraad.onmicrosoft.com -CertStoreLocation "Cert:\LocalMachine\My" -FriendlyName "b2bscriptMicrosoftGraphSDK" -Subject "Azure b2b onboarding - Cert for Microsoft Graph SDK"
Get-ChildItem "Cert:\CurrentUser\My\$($Cert.thumbprint)"

Note down the Thumbprint

Import the certifcate for use on the app registration

From the device you created the certificate on, export the certificate

Import the certificate on the App registration in Entra ID

You should then be able to conncet to Entra ID via powershell with the following command


The result of this setup for your users is a seamless logon experience to access the apps/desktop you provide. Since we are leveraging Entra ID, B2B and SAML to access the solution, your users will get a real SSO experience to access their apps, all with their own already exisiting credentials, that they manage on their own.

Since we are using b2b functionality to provide access, it doesn’t really matter where the external users have their identity. If they already are a M365 user, they will be able to use that identity, same for google and other providers.

Since we are enforcing conditional access rules on our end, we have the control to require MFA regardless what the users have on their end.

During the first logon the users will be prompted to setup MFA on their account as normal.

Should you want to give users access via features like cross-tenant sync, you could do that also, but keep in mind that you will need to make steps to ensure that  the users synced into your b2b tenant are created on the on-prem side, in your ADDS.

The next post will show you how you can achieve the same setup as this post, but instead of using the traditional on-prem Citrix products, we will do it using Citrix Cloud and the DaaS service – meaning less server and maintenance overhead on your end. I aim to post this tomorrow or friday, as I am currently out on a cruise together with the good people of Citrix User Group Norway and internet is somewhat limited 🙂

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Dybbugt.no

Subscribe now to keep reading and get access to the full archive.

Continue reading

Explore Yubico