I was
recently working on a project with a customer to extend their ADFS server farm
to Azure for a passive backup in the event of DR.
When I run
the command Add-AdfsFarmNode command ADFS returned an almost programmatic
error. The error was “ADMIN0011: InvalidRequestFault”
which was not very helpful.
The Event
Log’s on the server I was trying to join to the ADFS server farm was logging
Event 344 “There was an error doing
synchronization. Synchronization of data from the primary federation server to
a secondary server did not occur”.
The
installation with the Add-AdfsFarmNode
fails at 80% at the stage “synchronizing local database”.
The first
step was to check the health of the ADFS server farm and to check all the
relevant configurations such as SPN’s, DNS etc were configured correctly for an
ADFS farm join. The following PowerShell command is handy for checking all
these at once;
Test-AdfsFarmJoin
|
For some
reason the command does not run correctly unless you store the ADFS service
account in a variable and then call it from the variable, so to run the command
you must enter it like this;
$ADFScred
= Get-Credentials
Test-AdfsFarmJoin
–ServiceAccountCredential $ADFScred –PrimaryComputerName SERVER
|
As you can
see everything test successfully, one thing that is worth noting here as there
is some conflicting information around, the ADFS service account SPN should be
set to host/ not http/. The ADFS
wizard should automatically sets the SPN for you.
The next stage in my
troubleshooting was to enable ADFS logging, by default Verbose logging is not
enabled for ADFS as every transaction such as a new claim being issued would be
logged. Although this article relates to ADFS 2.0 it is relevant for 3.0 as well.
This particular ADFS
infrastructure had a number of custom Relaying Party Trusts configured for
home-grown applications. At this stage I had to open a support case with
Microsoft.
Although I thought I knew ADFS
fairly well, I did learn something new about Relaying Party Trusts. A Relaying
Party Trust can only have one policy of each type.
PolicyUsage = 0
"Issuance Transform Rules"
PolicyUsage = 1
"IssuanceAuthorizationRule"
PolicyUsage = 2
"Delegation Authorization Rule"
PolicyUsage = 3
"ImpersonationAuthorizationRules"
PolicyUsage = 4
"StrongAuthenticationPolicy"
By querying the ADFS (WID)
database directly Microsoft was able to identify that there was one of the
custom Relying Party Trust had stored two entries for IssuanceAuthorizationRule and Delegation
Authorization Rule.
To do this run the following PS command;
$stsWMIObject =
(Get-WmiObject -Namespace root\ADFS -Class SecurityTokenService)
$connection = new-object system.data.SqlClient.SqlConnection($stsWMIObject.ConfigurationDatabaseConnectionString); $connection.Open() $connection.Database $query = @“ SELECT [ScopeId], [AdfsConfiguration].[IdentityServerPolicy].[Policies].[PolicyUsage], [AdfsConfiguration].[IdentityServerPolicy].[ScopePolicies].[PolicyId] FROM [AdfsConfiguration].[IdentityServerPolicy].[ScopePolicies] INNER JOIN [AdfsConfiguration].[IdentityServerPolicy].[Policies] ON [AdfsConfiguration].[IdentityServerPolicy].[Policies].[PolicyID] = [AdfsConfiguration].[IdentityServerPolicy].[ScopePolicies].[PolicyID] ORDER BY [ScopeId],[AdfsConfiguration].[IdentityServerPolicy].[Policies].[PolicyUsage] ”@ $command = $connection.CreateCommand(); $command.CommandText = $query; $result = $command.ExecuteReader(); $table = new-object “System.Data.DataTable” $table.Load($result) $table |
Identify the duplicate
entries;
Scope ID
Policy Usage
Policy ID
7ae60ee4-d27b-e511-80c7-00505689310d
0 cd983eb1-d47b-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
1 3a317185-d47b-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
1 63dc770a-fc91-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
2 64dc770a-fc91-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
2 3b317185-d47b-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
3 7ee60ee4-d27b-e511-80c7-00505689310d
7ae60ee4-d27b-e511-80c7-00505689310d
4 7ce60ee4-d27b-e511-80c7-00505689310d
Match a Scope ID to a
Relaying Party Trust to identify which one is giving you problems;
$stsWMIObject = (Get-WmiObject -Namespace root\ADFS -Class
SecurityTokenService)
$connection = new-object
system.data.SqlClient.SqlConnection($stsWMIObject.ConfigurationDatabase
ConnectionString);
$connection.Open()
$connection.Database
AdfsConfiguration
$query = "SELECT * FROM
IdentityServerPolicy.ScopeIdentities";
$command = $connection.CreateCommand();
$command.CommandText = $query;
$result = $command.ExecuteReader();
$table = new-object "System.Data.DataTable"
$table.Load($result)
$table
|
The Scope ID translates to your
Relaying Party Trust. Interestingly enough if you opened the Relaying Party
Trust from the ADFS GUI the secondary Policy Usage entry was not visible.
Luckily in this case the problematic Relaying Trust Trust was only for testing
and it could be removed without much of a drama.
Although if you are experiencing
this issue with a trust you do require, the following steps can be taken to
resolve the problem
1.
Stop the ADFS service
2.
Export the Relying Party Configuration with " Get-AdfsRelyingPartyTrust
-Identifier <url identifier> "
(The <url
identifier> can be any of the identifiers associated with the "Relying
Party Trust" in the "[ScopeIdentities] " table)
Disabling the Relaying Party Trust does not work.
3.
From the Primary Server, remove the Relying Party causing the
conflict.
4.
Start the ADFS service and attempt an ADFS farm join.
5.
Sync should work now.
Surprising there is no metadata clean up etc.
required for ADFS, once you remove (or remove and then re-add) the trust and
the duplicate Policy Usage statements are gone everything should sync properly.