Integrate Captive Portal with ADFS using SAML Authentication

Showing results for 
Search instead for 
Did you mean: 
We are conducting regularly scheduled maintenance over the weekend, which could cause some downtime on LIVEcommunity. We apologize for any inconvenience.

Integrate Captive Portal with ADFS using SAML Authentication

L1 Bithead

Another post regarding an additional method for gaining userID info for non-domain joined assets.   There are lots of examples of using other idPs, but not much I could find regarding ADFS, so hope this is helpful for others looking for a similar option.



To begin, create an Auth policy and list the matching criteria.  In my config, I used,

- src zone “Inside”

- dst zone “Outside”

- any src/dst IP

- unknown users

- service-http and https (TCP - 80, 8080, 443)

- URL Cateogory “slack” containing “” and “*”

- Authentication Enforcement to “default-web-form”

- Timeout (min) to “1” since the captive portal settings override this setting anyway


So, in short, my policy only gets triggered when connections without userID attempt to connect to “” or “*”








Next, you need to download the metadata file from ADFS…https://#SERVER-FQDN#/federationmetadata/2007-06/federationmetadata.xml.  You can find this link listed in ADFS Management under “Endpoints / Metadata”.








On the Palo, click “SAML Identity Provider under “Devices” and give the server profile a name, then Browse to and select the ADFS metadata file you downloaded.


NOTE: I renamed my file from “federationmetadata (1).xml” to “newFederationMetadata.xml” so the Palo would take it: doesn't like "()" in the name.


Select checkbox to validate the idP certificate, and set the clock skew if needed…my systems are off, so I selected the max to be safe (max: 900s, default: 60s), then click “OK”.






Open up the newly created server profile and update the http binding from “Redirect” to “Post”, then click “OK”.  In my case, I did not choose to sign SAML requests from the Palo, so I unchecked “Sign SAML Message to IDP”.


NOTE: If you use a self-signed cert from AFDS, you cannot perform the trust verification (Validate Identity Provider Certificate) using a certificate profile.






Generate a certificate profile to verify the idP cert against a trusted root cert.  Choose any other options if you wish to provide further verification.






Create an Authentication Profile, type “SAML”, select the idP (SAML) server profile you created previously, choose a certificate that the Palo can use to sign requests (in this case, I’m not using a cert to sign requests to the idP, but it must be provided), select the cert profile to verify the idP cert trust, and leave the “Username Attribute” set to the default value “username” (it will not be used).






Select the “Advanced” tab and update the allow list.  Once finished, click “OK”.






Configure the captive portal to use the new Authentication Profile and make sure an SSL/TLS Service Profile is configured with a valid web cert for the redirect (in this case  I set the “Idle Timer” to 5 mins and the “Timer” value to 480 (8 hours), but you can decide which timer values work for your situation.  Make sure redirect is being used, and uncheck the session cookie “Enable” and “Roaming” (in testing, this absolutely did allow a computer to roam (change IPs and still get through), however, userID did not log for the new IP, so that is something to consider).  Lastly, set the redirect host FQDN pointing the configured firewall interface to handle the SAML auth traffic (please see my post on Kerberos SSO: you can use the interface configuration and DNS section from that post to see how to configure a firewall interface for captive portal redirection).


NOTE:  In testing, having the idle timer set to 300s is plenty enough to ensure the user mapping/authentication persists during general device usage.  Any traffic that passes through the firewall matching the same source/destination zones and sourced from an IP with an established user/authentication cache will reset the idle timer (does not not have to match the Authentication Policy criteria).  So, in environments where there is a quick release/assignment IP allocation method, such as VPNs with local IP pools, you can end up with users being pre-authenticated and logged as a different user (prior true user).  To circumvent this, most VPN local pool assignments have a method for delaying reissue of an IP that has been released.  In my case, if I delay reassignment for beyond 5 mins, the user and policy cache will timeout before any other users grab that IP.  For the general enterprise using DHCP, this is not an issue (extended period leases).  If a device moves from wired to wireless, w/in 5 mins, the policy and user cache will timeout.






Next, select the “Metadata” link (see below at top of example: blue hyperlinked "Metadata" under "SAML") on the Authentication Profile in the authentication profile window, then select “Service: captive-portal” for the top dropdown box.  The “Authentication Profile” field will be prepopulated.  Next, click the dropdown for “IP or Hostname”, which should have an available value based on the captive portal settings (in my case, "").  Click “OK” to download the .xml file.  Transfer this file to the ADFS server to create the relying party trust.






In ADFS Management, select “Relying Party Trusts” and select “Add Relying Party Trust” to begin configuring.  On the welcome page, select “Claims Aware”, and then click “Start”.






Select “Import data about the relying party from a file” and browse to/select the metadata file from the Palo, then click “Next”.






Enter a “Display name” and click “Next”.






Choose an access control policy and click “Next”.






Click “Next” again, then check the box for “Configure claims issuance policy for this application" and click “Close”.






At this point, the claims issuance policy dialog box will open.  Click “Add Rule”, then select “Send LDAP Attributes as Claims” and click “Next”.






Give the rule a name, select “SAM-Account-Name” under “LDAP Attribute…” and select “Name” for the outgoing claim type, then click “Finish”.


NOTE: SAM-Account-Name contains multiple values (#USERNAME#, and #DOMAIN#\#USERNAME#).  Claim type “Name” stores both values so you can use a transform rule to grab the #DOMAIN#\#USERNAME# format to send as an attribute to the Palo for proper user group mapping.






Click “Add Rule” again, then select “Send Claims Using a Custom Rule” and click “Next”.






Give the rule a name and enter the rule data.  In short, this rule takes the “Name” claim values acquired from the SAM-Account-Name, performs a regex operation (Value=~) to match on the attribute value beginning with (^) “PRAKTIKL” (the domain), and assigns this value to attribute “NameID”, which is automatically picked up by the Palo as it is contained within the <Subject> field in the SAML response.  Click “OK”, then click “Apply” and “OK” again.






Next, ADFS is set to encrypt claims for relying parties by default.  This must be disabled.  Open PS (run as admin) and type in the following command to disable claim encryption for the relying party trust (-Targetname is the same as the “Display name” value used when configuring the relying party: in my case, “PALO”).

"Set-AdfsRelyingPartyTrust -Targetname "PALO" -EncryptClaims $false"





Also, make sure that “keep me signed in” “KmsiEnabled” is set to True.  This will allow users to authenticate with ADFS for a predetermined period without having to enter credentials again by using SSO cookies.  The default lifetime is 1440 mins, but it can be scaled back or extended if desired.





At this point, you should be able to perform a test.  Since I’m using Slack as the URL matching criteria for my authentication policy, I browse to  In the screenshot below, you can see my ADFS splash page and that I’m selecting a certificate for authentication.


NOTE: I’m using the SAML Devtools Extension for Chrome.  This is extremely helpful in verifying the attributes sent.






I connect successfully.  In the SAML data, you can see attribute name “NameID” is set to “PRAKTIKL\user2”.




Checking the Authentication logs in the Palo, you see that the Palo received the SAML assertion, that it verified the idP cert from ADFS, and that the authentication was successful and userID “praktikl\user2” was acquired.






Via the CLI, you can see the IP-user-mapping from “SSO”.





Tested using a mobile device with a user certificate loaded (Android).







With KmsiEnabled set to True, other connections matching the authentication policy, where the policy and user cache are gone in the Palo, causes the same redirection to ADFS, and because the client has a valid SSO cookie, it uses it to authenticate with ADFS and trigger the SAML response back to the Palo (SP) without user interaction (below, the ADFS redirect happens fast, but you can see the captive portal "User Authenticated" acknowledgement page showing that this device has reauthenticated with the captive portal).






The end.



Community Team Member

Hi @jbworley ,


This is great stuff ! Thanks for the detailed information and explanation !




LIVEcommunity team member, CISSP
Don't forget to hit that Like button if a post is helpful to you!
Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the LIVEcommunity as a whole!

The LIVEcommunity thanks you for your participation!