Sunday, October 19, 2014

How to build ADFS (SAML 2.0) to KCD "proxy" using Citrix NetScaler - Part 2

This is second part of my 'How to build ADFS (SAML 2.0) to KCD "proxy" using Citrix NetScaler' guide.
You can find first of guide from: How to build ADFS (SAML 2.0) to KCD "proxy" using Citrix NetScaler - Part 1

On first part of this guide I said that we will join Netscaler to domain. Well I noticed later that is not needed on this configuration because any client doesn't connect to Netscaler using Kerberos authentication.

Anyway here is rest of needed configurations to get this working.

Enable Kerberos authentication to IIS page


I don't want copy whole that checklist here but shortly you need:
  • Disable "Anonymous Authentication"
  • Enable "Windows Authentication" to IIS web site.
  • Disable kernel mode authentication.
  • Add "Negotiate:Kerberos" authentication provider and remove all others.
My IIS settings looks like this.

Test that kerberos authentication works

On that point it is good idea test that you really can connect to application and authentication to it works from some machine which is on same domain with backend server.


Because we are using kerberos authentication you will notice that you must connect to application using name which have registered SPN (Service Principal Names) on Active Directory.

That means that on default settings these urls works:
  • http://iis.contoso.local
  • http://iis

And these ones are not working:
  • http://192.168.100.21
  • http://iis.contoso.com

I used ASP code like this on IIS to show me that which account was actually authenticated to it (IIS ASP feature is needed):
<asp:LoginName id="LoginName1" runat="server" FormatString ="Welcome, {0}" />

Important note here is that when you connect to this page through Netscaler, it will always use server's FQDN name to connect it. That means that even public url on this example is iis.contoso.com, you don't need register SPN for it.

Custom monitor

After you are forced IIS to use Kerberos authentication you will notice that service on Netscaler will go down (at least if you are used HTTP monitor).

Reason for this is that Netscaler can't any more get right response from IIS server.
To solve this issue I created "HealthCheck" folder to IIS side and enabled anonymous authentication to it.

Then I created custom monitor like and linked it to IIS service.
add lb monitor http_HealthCheck HTTP -respCode 200 -httpRequest "HEAD /HealthCheck/" -LRTM DISABLED
unbind service svc_IIS -monitorName http
bind service svc_IIS -monitorName http_HealthCheck


Allow Kerberos delegations from AD

  • Created domain account svc_ns_kcd
  • Created new SPN for that account using following command:
  • setspn -S host/nsidp.contoso.com svc_ns_kcd
    • This is only needed for enabling "Delegation" tab to that service account but of course it need to unique on domain. I used nsidp.contoso.com name which was used SAML provider.
  • Added following delegation:


Traffic policy

When we have everything else on place we just need create KCD account to Netscaler and assign it to service using traffic policy.
add aaa kcdAccount svc_ns_kcd -realmStr CONTOSO.LOCAL -delegatedUser svc_ns_kcd -kcdPassword Qwerty7

add tm trafficAction trafficKCDSSO -SSO ON -kcdAccount svc_ns_kcd
add tm trafficPolicy trafficKCDSSO TRUE trafficKCDSSO
bind lb vserver vsrv_IIS -policy trafficKCDSSO -priority 100

After you add that configuration you should be able to connect to https://iis.contoso.com using SAML federation and you should be authenticated to application using kerberos.

Session handling trick

After some testing I noticed that Netscaler got kerberos ticket only for first user and after that it authenticated second user to application using first user's credentials. Because I didn't found solution to that problem my self I created support request to Citrix. They found from log files that problem on this configuration is that Netscaler always connects to backend application using same source port, that why IIS didn't requested user authentication (using 401 error) and second user was delegated to application using first users session.

Solution to this problem is set maxClient = 1 setting to service. With that configuration Netscaler always uses different source port when it connects to application. Then IIS always responses 401 to first request and Netscaler will get kerberos ticket for user.
We can enable this setting following commands:
rm service svc_IIS

add service svc_IIS IIS HTTP 80 -maxClient 1

bind lb vserver vsrv_IIS svc_IIS
bind service svc_IIS -monitorName http_HealthCheck

Add another page behind this proxy

After you are used lot of time to get this working, relevant question is that "What is needed to add another vserver behind this system?"
First you need have:
  • AssertionConsumerService value specified on SAML metadata.
    • On example on first part of this guide I already included iis2.contoso.com to there.
  • You need add kerberos delegations to new IIS server for svc_ns_kcd account.
Then you just create new vserver with needed configurations like this:
add server DC 192.168.110.11
add service svc_DC DC HTTP 80 -maxClient 1
add lb vserver vsrv_DC SSL 192.168.110.22 443 -persistenceType NONE
bind lb vserver vsrv_DC svc_DC
bind ssl vserver vsrv_DC -certkeyName wildcard
set ssl vserver vsrv_DC -tls11 DISABLED -tls12 DISABLED
bind service svc_DC -monitorName http_HealthCheck

set lb vserver vsrv_DC -AuthenticationHost iis2.contoso.com -Authentication ON -authnVsName auth_vsrv
bind lb vserver vsrv_DC -policy trafficKCDSSO -priority 100

NOTE! On this configuration both of these web pages (iis.contoso.com and iis2.contoso.com) are authenticated using auth.contoso.com authentication vserver and them are using same relaying party rule on ADFS side. If you are service provider which wants publish different web pages to different customers then you need have one authentication vserver per customer that configuration allows to use different relaying parties for different web servers.

The final words

It have been very nice experience to leaning how kerberos authentication and SAML federations works on deep level and I really like that Netscaler allows us to do this. I hope that this will be useful guide for people who are looking for same kind solution. My trip here is now over and it is time to move on to next technologies.