Kategoriarkiv: StoreFront

Citrix Workspace App and SAML/FAS

User experience

For the first setup of the workspace app, there will be a popup, where you can enter information about the environment you will connect to. Once you enter the URL/Email, it will contact the Citrix ADC if you’re from the outside, and hopefully the StoreFront directly, if you’re on the inside. But since I want to show the SAML at once, this will be a setup from external.

I’m using OKTA as my SAML provider, therefore am i redirected to Okta login

After i sign in, i will get access to my apps

I can launch my desktop

And on my FAS server I can see my certificate is created

Citrix ADC

Now to the fun part, how do we make it work.

I will mainly focus on the Citrix ADC part, as there are other great guides out there for the Citrix FAS, like the one Carl Stalhood made, which can be found here: https://www.carlstalhood.com/citrix-federated-authentication-service-saml

The Citrix ADC needs to be upgraded to firmware, It’s suppose to work in .49 also, but there is a kernel error which will make your Citrix ADC reboot, from what I’ve been told, by some fellow PTEC guys.

I’ve tested it both with a normal Citrix Gateway and Unified Gateway. To make it work it will require that you have an Advanced License (The old Enterprise), because we need to make use of nFactor.

On the Citrix Gateway we will have to configure an authentication Profile, so we can point our authentication traffic to an AAA server, to trigger the nFactor.

You can create the Authentication under Security – AAA Application Traffic – Autentication Profile – Add, now an authentication profile is just a pointer to the AAA server

This is how we move the authentication traffic from the Unified Gateway to AAA, where we want to do the SAML authentication.

I’ve created a SAML server for my Okta account. Like I wrote in the earlier blog post, there are some requirements for setting up SAML. We need the Redirection URL (Where will users do the authentication), the iDP signing certificate, the User Field (What will we receiver from the iDP), to sign our request from the service provider and finally the issuer name, which is the name the Citrix ADC sends to the iDP to uniquely identify the ADC.

My SAML server looks like this

Next we need a policy to call our server (remember that a policy is how we call a server/action). I’m using an Advanced Policy, which can be created under Policies – Authentication – Advanced Policies – Policy – Add

Since I want SAML to be used for everyone and everything, I will just use the policy expression true and point the action to my SAML server created earlier

Now it’s time to bind it to my AAA server, I will bind it under Advanced Authentication policies

That is basicly all you need to change, if you used a SAML policy directly on the Citrix Gateway before, which will work with browsers. But the workspace app needs nFactor to kick in.

The CLI can be found here


add authentication samlAction auth_okta_saml -samlIdPCertName Okta -samlSigningCertName wildcard_netscaler_dk -samlRedirectUrl “https://netscaler.okta.com/app/citrixnetscalergateway_saml/secretsauce/sso/saml” -samlUserField “Name ID” -samlIssuerName “http://www.okta.com/secretsauce” -signatureAlg RSA-SHA256 -digestMethod SHA256 -logoutURL “https://netscaler.okta.com”

add authentication Policy authadv_pol_okta -rule true -action auth_okta_saml


add authentication authnProfile AAA-AUPL-SERVER -authnVsName AAA-SERVER -AuthenticationHost aaa.netscaler.dk -AuthenticationDomain netscaler.dk -AuthenticationLevel 3

add authentication Policy authadv_pol_okta -rule true -action auth_okta_saml

bind authentication vserver AAA-SERVER -policy authadv_pol_okta -priority 100 -gotoPriorityExpression END

Unified Gateway:

set vpn vserver UG_VPN_gw.netscaler.dk -authnProfile AAA-AUPL-SERVER


If you have issues with authentication, we can head over to the good old aaa.debug in /tmp folder, remember this file is a pipe, so we’re looking into it as traffic is coming through.

A sample SAML authentication will a little like this:

Sun Feb 3 13:34:11 2019

/home/build/rs_121_50_16_RTM/usr.src/netscaler/aaad/naaad.c[900]: process_kernel_socket 0-64: partition id is 0

Sun Feb 3 13:34:11 2019

/home/build/rs_121_50_16_RTM/usr.src/netscaler/aaad/naaad.c[2221]: process_kernel_socket 0-64: saml_canon: preamble size is 10782

Sun Feb 3 13:34:11 2019

/home/build/rs_121_50_16_RTM/usr.src/netscaler/aaad/naaad.c[2223]: process_kernel_socket 0-64: saml_canon: read 10758 bytes from socket

Sun Feb 3 13:34:11 2019

/home/build/rs_121_50_16_RTM/usr.src/netscaler/aaad/naaad.c[2232]: process_kernel_socket 0-64: saml_canon: canon_req size is 10722

Sun Feb 3 13:34:11 2019

/home/build/rs_121_50_16_RTM/usr.src/netscaler/aaad/naaad.c[2233]: process_kernel_socket 0-64: saml_canon: input string is <saml2:Assertion xmlns:saml2=”urn:oasis:names:tc:SAML:2.0:assertion” ID=”id243710244642880201145219498″ IssueInstant=”2019-02-03T12:34:10.919Z” Version=”2.0″><saml2:Issuer Format=”urn:oasis:names:tc:SAML:2.0:nameid-format:entity” xmlns:saml2=”urn:oasis:names:tc:SAML:2.0:assertion”>http://www.okta.com/SecretSauce</saml2:Issuer><ds:Signature xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”/><ds:SignatureMethod Algorithm=”http://www.w3.org/2001/04/xmldsig-more#rsa-sha256″/><ds:Reference URI=”#id243710244642880201145219498″><ds:Transforms><ds:Transform Algorithm=”http://www.w3.org/2000/09/xmldsig#enveloped-signature”/><ds:Transform Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”/></ds:Transforms><ds:DigestMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#sha256″/><ds:DigestValue>6pq1us+JQQXPIWJ8R/p+ZH7Vb1DYUNyUCZvhg4WaFoY=</ds:DigestValue></ds:Reference>

You can also use a SAML tool in the browser to decode. I like SAML Message Decoder for Chrome myself and the Developer tools in the browsers are also useful.

The flow is as following

  1. Client: GET / HTTP/1.1
  2. ADC: HTTP/1.1 302 Object Moved Location: /vpn/index.html
  3. Client: GET /vpn/index.html HTTP/1.1
  4. ADC: HTTP/1.1 302 Object Moved Location: /logon/LogonPoint/tmindex.html
  5. Client: GET /logon/LogonPoint/tmindex.html HTTP/1.1
  6. ADC: HTTP/1.1 200 OK
    1. Now the Client and ADC will talk until the Client Ask for Authentication and ADC will respond with SAML
  7. ADC: GET /nf/auth/doSaml?act=auth_okta_saml;nf=;wv=0 HTTP/1.1

Now the Client will talk with the SAML iDP and here it will do a SAMLRequest, which is a base64 encoded message (Look for a POST against the iDP which contains the SAMLRequest) as seen here:

Now this big block of data, is something you can decode online. I like https://www.samltool.com/decode.php, where you can paste the whole SAMLRequest, and it will return something like this

So there is a lot of information to troubleshoot SAML on the Netscaler and in the browser