Home > Identity Management > Modifying the AD FS 2.0 Passive Federation Endpoint

Modifying the AD FS 2.0 Passive Federation Endpoint

December 30th, 2009 Leave a comment Go to comments

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.

AD FS 2.0 Endpoints

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.

Windows Internal Database Connection

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:

  1. 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.
  2. Set the @EndPointAddress variable to the desired address of your STS login page.
  3. 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)[1] 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

  1. 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.
  2. 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.

Wrapping Up

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!

Categories: Identity Management
  1. December 30th, 2009 at 15:31 | #1

    Good post, Garrett. I have a couple questions though:

    * Why not simply change /adfs/ls in IIS to point to your custom login app and change it back as needed? That sounds just as easy (if not easier) than running the SQL script against WID. Is it because of audience restrictions and other policy that ADFS will apply to incoming RSTs?

    * Was there anything in the PowerShell API that would have allowed you to change this endpoint? A cursory look seems like no.

    * The RPs are configured to point to an issuer w/ an arbitrary URI — anything not necessarily …/adfs/ls. So, whatever Web app that refers to is the passive STS that that RP will redirect subjects to. Why not use the API exposed by Microsoft.IdentityServer and the login app shipped w/ ADFS as a starting point/reference to build what you need? (This is what I’ve done.)

  2. Garrett
    December 30th, 2009 at 16:04 | #2

    @Travis Spencer
    Thanks for the feedback, Travis. All good thoughts.

    1. We had originally done just as you said — pointed the IIS virtual directory to the custom application. This was with Beta 2 when the site was found under /FederationPassive. With the RC and the new /adfs/ls folder structure, it seemed a little messier to change a sub-folder so that’s when I started looking for a way to change the AD FS configuration. In the end, it may be a little more work, but it seems cleaner to me.

    2. I hadn’t looked to see if there were any PowerShell methods, but if somebody finds one, that would be excellent.

    3. If I’m following you correctly, I understand that the STS URI is fairly arbitrary from the RP standpoint. However, the Metadata “endpoint” in AD FS points the RP to /adfs/ls. Therefore, if you use FedUtil to setup the trust between your RP and AD FS, you will get the /adfs/ls address. This can be changed in the web.config manually, but that’s just another step for every RP app.

    As far as using the out of the box login app as a starting point, that’s exactly what we did. I certainly like what Microsoft’s done with the Microsoft.IdentityServer library in the RC. It does make it fairly simple to roll your own AD FS sign-on pages. We’ve even gone as far as supporting OpenID and Facebook Connect in the login process.

  3. December 31st, 2009 at 08:21 | #3

    Ah yes, the metadata. Now, I see the problem and why this sort of thing is necessary. I’ve been configuring all my RPs by hand, so I didn’t think of that.

  4. Garrett
    January 12th, 2010 at 07:50 | #4

    Well, I stand corrected. Travis, you were correct that there are PowerShell Cmdlets to perform AD FS 2.0 administration:

    http://technet.microsoft.com/en-us/library/ee126138(WS.10).aspx

    But it doesn’t look like you can do the same endpoint configuration using PowerShell.

  5. Arjan
    August 16th, 2013 at 05:51 | #5

    You can also set this property with the following command (using ADFS 2.0):

    Set-ADFSProperties -FederationPassiveAddress “/adfs/ls”

    Thanks for the informative post though, helped me in better understanding how ADFS works.

  1. June 23rd, 2011 at 13:22 | #1