Posted in : ADFS, NetScaler By Simon Gottschlag

2 years ago

How do you configure Citrix NetScaler SAML Service Provider with Microsoft ADFS as SAML Identity Provider? I’ve tried making it easy to understand and how you do it using CLI (NetScaler CLI and powershell).
Before we begin, let us look at what we need to establish the federation:

  • NetScaler (with at least Enterprise license)
  • Active Directory domain and ADFS (read this post if you want to load balance and use NetScaler as ADFS Proxy)
  • Website (lb vserver) we want to protect with AAA (will be referred to as the service provider)
  • AAA vserver to bind SAML Service Provider policy

In my case, the following FQDNs are used:

  • LB vserver: webapp-test.domain.com / LB-WEBAPP-TEST
  • AAA vserver: sp.domain.com / AAA-SP-DOMAIN.COM (note: it will actually not be access by the web browser)
  • ADFS: adfs.domain.com

When installing ADFS two self signed certificates are issued for Token-signing and Token-decryption. When it comes to the NetScaler, we could always use whatever certificate for the signing and decryption – but I recommend using a certificate that isn’t used for web site communication. That’s why I create a self signed certificate that I use: (note: I do this on my computer, modify the variables to match your environment – and even though this certificate and key is self signed – keep them secure)

$SITE="netscaler-saml-sp-signing"
$PATH="C:\Xenit"
$CERTPATH="${PATH}\${SITE}"
$OPENSSLPATH="C:\Program Files (x86)\OpenSSL-Win32\bin"
$OPENSSL="${OPENSSLPATH}\openssl.exe"
$ReqO  = "NetScaler SAML SP Signing"
$ReqOU = "IT"
$ReqC  = "SE"
$ReqL  = "Goteborg"
$ReqST = "Vastra Gotaland"
# Generate key
New-Item -path ${CERTPATH} -type directory
& ${OPENSSL} genrsa -out "${CERTPATH}\${SITE}.key" 2048
# Generate csr
$OpenSSLConfig = "[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = ${ReqC}
ST = ${ReqST}
L = ${ReqL}
O = ${ReqO}
OU = ${ReqOU}
CN = ${ReqCN}
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${ReqC}"
$OpenSSLConfig | Out-File "${CERTPATH}\${SITE}.cnf" -Encoding ASCII
& ${OPENSSL} req -new -sha256 -subj "/CN=${SITE}/O=${ReqO}/OU=${ReqOU}/C=${ReqC}/L=${ReqL}/ST=${ReqST}/" -key "${CERTPATH}\${SITE}.key" -out "${CERTPATH}\${SITE}.csr" -config "${CERTPATH}\${SITE}.cnf"
& ${OPENSSL} x509 -req -days 3650 -in "${CERTPATH}\${SITE}.csr" -signkey "${CERTPATH}\${SITE}.key" -out "${CERTPATH}\${SITE}.crt"

The certificate (not the key) needs to be copied to the ADFS server for when we create the Relying Party Trust, and we also need to copy the ADFS Token-signing certificate to the NetScaler (below called adfs.domain.com-signing).
Copy the newly created certificate and key to the NetScaler, as well as the ADFS Token-signing certificate:

add ssl certKey adfs.domain.com-signing -cert adfs.domain.com-signing.crt
add ssl certKey netscaler-saml-sp-signing -cert netscaler-saml-sp-signing.crt -key netscaler-saml-sp-signing.key

Now we need to create the SAML Service Provider action and profile, as well as bind it to the AAA vserver:

add authentication samlAction SAML-SP-WEBAPP-TEST.DOMAIN.COM -samlIdPCertName adfs.domain.com-signing -samlSigningCertName netscaler-saml-sp-signing -samlRedirectUrl "https://adfs.domain.com/adfs/ls" -samlUserField "Name ID" -samlIssuerName "https://webapp-test.domain.com" -Attribute1 "Name ID" -signatureAlg RSA-SHA256 -digestMethod SHA256
add authentication Policy SAML-SP-POL-WEBAPP-TEST.DOMAIN.COM -rule "HTTP.REQ.HOSTNAME.EQ(\"webapp-test.domain.com\")" -action SAML-SP-WEBAPP-TEST.DOMAIN.COM
bind authentication vserver AAA-SP-DOMAIN.COM -policy SAML-SP-POL-WEBAPP-TEST.DOMAIN.COM -priority 100 -gotoPriorityExpression NEXT

(Note: As I stated before, this policy is bound to the AAA vserver but the expression is matching the hostname of the LB vserver – since the web browser actually never is redirected to the AAA vserver in this scenario)
As a last step, create (if it isn’t already) an authentication profile and bind it to the LB vserver:

add authentication authnProfile authprofile-sp.domain.com -authnVsName AAA-SP-DOMAIN.COM -AuthenticationHost sp.domain.com
add lb vserver LB-WEBAPP-TEST HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 180 -Authentication ON -authnProfile authprofile-sp.domain.com

Now configure ADFS (modify the variables to match your need):

$RPName = "Webapp-test"
$RPIdentifier = "https://webapp-test.domain.com"
$RPEndpointURL = "https://webapp-test.domain.com/cgi/samlauth"
$RPEndpoint = New-ADFSSamlEndpoint -Binding "POST" -Protocol "SAMLAssertionConsumer" -Uri $RPEndpointURL
$RPCertPath = "C:\temp\netscaler-saml-sp-signing.crt"
$RPCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$RPCert.Import($RPCertPath)
$RPSignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
$RPTransforms = '@RuleTemplate = "LdapClaims"
@RuleName = "AD Claims"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"), query = ";userPrincipalName;{0}", param = c.Value);
@RuleTemplate = "MapClaims"
@RuleName = "Transform UPN to Name ID"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
 => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "http://schemas.xmlsoap.org/claims/UPN");'
Add-AdfsRelyingPartyTrust -Name $RPName -Identifier $RPIdentifier -EncryptClaims $true -EncryptionCertificate $RPCert -SignedSamlRequestsRequired $true -RequestSigningCertificate $RPCert -SignatureAlgorithm $RPSignatureAlgorithm -SamlEndpoint $RPEndpoint -IssuanceTransformRules $RPTransforms -AccessControlPolicyName "Permit everyone"

 

Tags : AAA, ADFS, IDP, NetScaler, SAML, SP

Add comment

Your comment will be revised by the site if needed.