I recently had to assist designing a portal solution. The customer had an existing solution based on Microsoft ADFS to log on users to ShareFile, Office 365, SAP and similar applications. In addition they used Citrix Gateway (NetScaler Gateway) to publish applications XenApp applications and VDI (XenDesktop) to users. We had to unify the user experience and bring both solutions into a single portal.
Not the solution
In a first step, the customer created bookmarks in Citrix Gateway’s portal. This made all SAS applications available from Gateway. Unfortunately users first had to log on to Gateway to be able to click the applications. After clicking the application they had to logon through ADFS to actually launch the application. So users had to logon twice.
Things would have been easy without ADFS. We could have created gateway server in Citrix ADC (NetScaler Gateway) and use it as a SAML IDP for SAS applications. But this was not an option, as the customer wanted to keep his existing ADFS solution.
A problem using Citrix ADC as a SAML IDP?
As mentioned above, this was not an option. The customer wanted to use ADFS, so we had to go with ADFS. But what if the customer would have agreed? There is a problem using a Citrix ADFS (NetScaler) as a SAML IDP: It seems to be impossible to authenticate more than a single resource, as it will allow to authenticate just to the first IDP definition bound to a AAA server. Wtf?
After thinking about the problem, I thought, it would be either a problem of binding or a problem of filtering the IDP policies. Some tries: There is no chance using filters.
So what about bindings? SAML IDP definitions contain a Service Provider ID. This Service Provider ID has to match the ID the service provider sends. A request will never get processed if this ID does not match, therefore it should fall down to the next one, if the policy was bound using a NEXT statement. But there is no GOTO statement during binding-procedure. Looking from command line I saw: all policies got bound using a GOTO END.
I investigated this issue and found CTX230267. This problem is an old one, but it still exists: It’s not possible to bind IDP policies with a GOTO NEXT. At least not from GUI, but it’s there from command line only!
bind authentication vserver Saml-IDP-AAA-server -policy auth_pol_SAML -priority 90 -gotoPriorityExpression NEXT
Quite simple. You just have to know about.
SAML authentication in a nutshell
In SAML you have 2 components: The Identity provider (usually called IDP) and the service provider (referred as SP)
Usuelly the user connects to the SP. The SP will redirect the user to the IDP. At the same time it give a message (called assertion) to the user, addressed to the IDP. The IDP will authenticate the user, handle an assertion to the user, the user will then connect to the SP again, deliver the assertion to the SP, to prove he was logged on successfully.
SAML uses certificates to make sure there is no fake.
- So the IDP has a certificate, to sign it’s assertions (including the private key), called IDP certificate (also IDP signing certificate). The SP needs to have the same certificate (but without private key) called IDP certificate. It is used to verify the IDP’s assertions.
- Vice versa the SP also got a signing certificate (including the private key) to sign it’s assertions, called Signing Certificate. The IDP needs to have the same certificate (but without private key) called SP Certificate, so it may verify and trust SP’s assertions.
Both of these certificate are of type server certificates (MS-CA: Web Server Certificate) and don’t need to be trusted. Hostnames are of no importance. They usually get created using a private CA. Microsoft ADFS uses a self-signed certificate created during installation (like many Microsoft ideas this is not a good idea, I will go into this later).
The SP needs to know IDP’s authentication URL (Redirect URL). A Citrix ADC (NetScaler) based IDP will use https://<IDP-host-FQDN>/saml/login. And the IDP needs to know SP’s authentication URL (Assertion Consumer Service URL), a Citrix ADC (NetScaler) based SP will use https://<SP-Host-FQDN>/cgi/samlauth. These URLs don’t follow a RFC, instead they are vendor specific.
There are two methods of authentication:
- SP initiated authentication (the usual way), the user connects to the SP and gets directed to the IDP, authenticates and gets redirected to the SP and consumes the ressource
- IDP initiated authentication, the user connects to the IDP, authenticates and gets directed to the SP. This is not usual as users don’t want to authenticate, but to consume resources.
The IDP will never expose the password to the SP, so the SP will not know about it.
As IDP does not expose the password to the SP, Citrix Gateway (NetScaler Gateway) is not a good SAML SP: Gateway logon via ADFS would result in not knowing user’s password and therefore not being able to log on to StoreFront. Succeding, the user would also not be able to log on to published applications and desktop seemlesly. We could overcome this issue by using Federated Authentication Service (FAS), but this is a complex solution. I don’t like complex solutions. Best solution would be: Use Citrix gateway as a SAML IDP! but like mentioned above: It was not an option as the customer wanted to keep his Microsoft ADFS.
If you look at bookmarks in Citrix Gateway you’ll see the Application Type.
Now we may select a SSO type. This should, of course, be SAML. We want to use our well known ADFS (?) for authentication, but at the same time do single sign on (SSO) to SAS applications. It will prompt for a SAML SSO Profile.
Taking a closer look at this profile, you’ll see: It’s a SAML-IDP profile! How can we use 2 IDPs to authenticate to a single SP? It does not seem to be possible.
How can a SP recognize a IDP? Just by verifying the assertion! How is an assertion verified? By using the certificate provided by the admin. The solution would be: Fake ADFS by using the same certificate as ADFS does. So we will use an IDP initiated authentication and at the same time fake the IDP.
We just face one problem: We need to get the IDP certificate out of Microsoft ADFS. And that’s not possible, as it’s impossible to export the private key. So we need to create a certificate for ADFS (type: “webserver”, hostname does not matter, validity should not be < 2 years for security reasons, but as long as any possible for convenience). For all the rest of this policy: Follow my guide about SAML IDPs.
I hope you liked my blog. I’d be happy to get a short message, if my blog was of any help to you. Tell me which information is missing and point out mistakes I did. You are allowed to link to my page. Thank you