Modifying the AD FS 2.0 Passive Federation Endpoint
Out of the box, Active Directory Federation Services (AD FS) 2.0 comes bundled with several endpoints to support different protocols (WS-Trust, WS-Federation, etc.), credential types, and security modes. These endpoints are used for communication to the STS so if you have an application that needs to receive tokens via WCF, you can connect to one of the provided endpoints depending on your security and transport requirements.
Customizing the Passive Federation Site
The endpoint that many developers will encounter the most is the Passive Federation endpoint. This is the URI that a user will be redirected to when trying to authenticate with a Windows Identity Foundation (WIF)-enabled site. In other words, this is the AD FS login page.
So what happens if you want to customize this site? Well, the official documentation describes how you can easily configure three things in the sign-on pages: the accepted authentication types, the theme (CSS) of the site including the logo, and finally the “behavior and layout” of the sign-on pages. There are extension points for creating your own pages as well as modifying the existing ones.
In this posting, I won’t go into the details of the library used to make these customizations (Microsoft.IdentityServer) but needless to say, you have the ability to control many aspects of the AD FS login process.
Changing the Passive Federation Endpoint URL
Once you’ve decided to customize the login site, it would also be nice to change the location of the site so you’re not stuck with the hard-wired URI (/adfs/ls). In my case, I wanted to simply keep the existing site in place (for backup and testing purposes) while putting in a newly customized STS login site.
Since there’s no way to change the endpoint URI within the management console, you need to update the AD FS configuration, which is conveniently stored in a database column as a single XML file in Windows Internal Database (WID)! Have no fear. I’ve written a SQL script (see below) to make this update process much simpler.
Connecting to Windows Internal Database (WID)
The first thing you’ll need to do is to connect to the Windows Internal Database (WID) instance on your machine. As of the RC of AD FS, the settings are no longer stored in an external SQL Server or SQL Server Express database. Instead, AD FS utilizes WID, which is simply SQL Server running with limited rights and visibility within Windows Server.
To connect, open SQL Server Management Studio (if you’re running this in Windows 2008, be sure to run it as an Administrator) and enter \\.\pipe\mssql$microsoft##ssee\sql\query as the server name. Yes, that’s the connection string. It seems like a bit of a hack getting into it, but this is well documented (it’s even on Wikipedia!) so don’t be afraid.
Updating the Endpoint
Once you’ve connected, you can execute the script below to change the address of the Passive Federation endpoint. A couple of notes first:
- Standard disclaimer: This is a database update script so be sure that you’ve either backed up the database or made a copy of the settings so that you can roll back if necessary.
- Set the @EndPointAddress variable to the desired address of your STS login page.
- If you want to just see the configuration results before committing the changes, set the @Debug variable to 1 (true).
USE AdfsConfiguration GO -- -- Variables -- DECLARE @Settings XML DECLARE @EndPointAddress VARCHAR(255) DECLARE @Debug BIT -- Set the new Passive Federation location here(original='/adfs/ls') SET @EndPointAddress = '/PassiveFederationSite' -- Set this to true(1) if you only want to see the changes and not apply them SET @Debug = 0 -- -- Convert the settings to XML data type -- so we can more easily work with it. -- SET @Settings = ( SELECT CAST( REPLACE(ServiceSettingsData, 'encoding="utf-8"', '') AS XML) AS x FROM IdentityServerPolicy.ServiceSettings ) -- Update settings in XML SET @Settings.modify('replace value of (/ServiceSettingsData/SecurityTokenService/PassiveEndpoint/@Address) with sql:variable("@EndpointAddress")') -- Convert new settings back to NVARCHAR DECLARE @NewSettings NVARCHAR(MAX) SET @NewSettings = '' + CAST(@Settings AS NVARCHAR(MAX)) IF @Debug = 1 BEGIN SELECT @NewSettings SELECT @Settings.query ('/ServiceSettingsData/SecurityTokenService/PassiveEndpoint') END ELSE BEGIN DECLARE @ObjectId UNIQUEIDENTIFIER DECLARE @ServiceSettingsVersion BIGINT -- Get the latest settings data SELECT TOP 1 @ObjectId = ServiceSettingId, @ServiceSettingsVersion = ServiceSettingsVersion FROM IdentityServerPolicy.ServiceSettings ORDER BY LastUpdateTime DESC -- -- Execute stored procedure to update settings -- EXEC IdentityServerPolicy.UpdateServiceSettings @ObjectId, @NewSettings, @ServiceSettingsVersion END
Some Notes on the Script
- The removal of the “utf-8″ encoding string is necessary for the configuration to be properly converted into the SQL Server XML type. Without using the XML data type, this script would have been a lot more complex.
- In addition to updating the configuration settings, the UpdateServiceSettings stored procedure increments the version column and updates the LastUpdatedTime column. The version column (as far as I can tell) is only used for handling update conflicts.
Once the script has been run, the changes will be instantaneous in AD FS. There’s no need to restart the service. To roll back to the original URI, just set @EndpointAddress to “/adfs/ls” and rerun the script!