Skip to content

Commit 98bc609

Browse files
authored
Merge pull request #8520 from Deland-Han/ci3907
AB#3907 [Child of 3895][Azure AD PowerShell references]: ADFS SSO troubleshooting - Windows Server
2 parents 5258a8d + b72893a commit 98bc609

1 file changed

Lines changed: 40 additions & 178 deletions

File tree

support/windows-server/active-directory/troubleshoot-ad-fs-sso-issue.md

Lines changed: 40 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ADFS SSO troubleshooting
33
description: Introduce how to troubleshoot ADFS SSO issues.
4-
ms.date: 01/15/2025
4+
ms.date: 04/01/2025
55
manager: dcscontentpm
66
audience: itpro
77
ms.topic: troubleshooting
@@ -82,7 +82,8 @@ Verify if the user agent string of your browser is in the list. If not, add the
8282
Example:
8383

8484
```powershell
85-
$wiaStrings = $wiaStrings+" =~Windows\s*NT.*Edge"+"Mozilla/5.0"
85+
#Add Edge and Chrome on Windows to the string
86+
$wiaStrings = $wiaStrings+"=~Windows\s*NT.*Edg.*"+ "=~Windows\s*NT.*Chrome"
8687
```
8788

8889
4. Update the WIASupportedUserAgents setting by running the following command:
@@ -104,42 +105,26 @@ For more information, see [Overview of authentication handlers of AD FS sign-in
104105

105106
If the application that you want to access is not Microsoft Online Services, what you experience is expected and controlled by the incoming authentication request. Work with the application owner to change the behavior.
106107

107-
[!INCLUDE [Azure AD PowerShell deprecation note](~/../support/reusable-content/msgraph-powershell/includes/aad-powershell-deprecation-note.md)]
108-
109108
If the application is Microsoft Online Services, what you experience may be controlled by the **PromptLoginBehavior** setting from the trusted realm object. This setting controls whether Microsoft Entra tenants send prompt=login to AD FS. To set the **PromptLoginBehavior** setting, follow these steps:
110109

111110
1. Open Windows PowerShell with the "Run as administrator" option.
112-
2. Get the existing domain federation setting by running the following command:
111+
2. Set the PromptLoginBehavior setting by running the following commands:
113112

114113
```powershell
115-
Get-MSOLDomainFederationSettings -DomainName DomainName | FL *
114+
Connect-MgGraph -scopes Domain.ReadWrite.All, Directory.ReadWrite.All
115+
$tdo= Get-MgDomainFederationConfiguration -DomainID <domain_id>
116+
Update-MgDomainFederationConfiguration -DomainId <domain_id> -InternalDomainFederationId $tdo.Id -PromptLoginBehavior <translateToFreshPasswordAuthentication|nativeSupport|disabled>
117+
Disconnect-MgGraph
116118
```
117119

118-
3. Set the PromptLoginBehavior setting by running the following command:
119-
120-
```powershell
121-
Set-MSOLDomainFederationSettings -DomainName DomainName -PromptLoginBehavior <TranslateToFreshPasswordAuth|NativeSupport|Disabled> -SupportsMFA <$TRUE|$FALSE> -PreferredAuthenticationProtocol <WsFed|SAMLP>
122-
```
120+
> [!NOTE]
121+
> \<domain_id> is a placeholder for your domain's name. For example, contoso.com.
123122
124123
The values for the PromptLoginBehavior parameter are:
125124

126-
1. **TranslateToFreshPasswordAuth**: Microsoft Entra ID sends wauth and wfresh to AD FS instead of prompt=login. This leads to an authentication request to use forms-based authentication.
127-
2. **NativeSupport**: The prompt=login parameter is sent as is to AD FS.
128-
3. **Disabled**: Nothing is sent to AD FS.
129-
130-
To learn more about the Set-MSOLDomainFederationSettings command, see [Active Directory Federation Services prompt=login parameter support](/windows-server/identity/ad-fs/operations/ad-fs-prompt-login).
131-
132-
<a name='azure-active-directory-azure-ad-scenario'></a>
133-
134-
### Microsoft Entra scenario
135-
136-
If the authentication request sent to Microsoft Entra ID include [the prompt=login parameter](/windows-server/identity/ad-fs/operations/ad-fs-prompt-login), disable the prompt=login capability by running the following command:
137-
138-
```powershell
139-
Set-MsolDomainFederationSettings –DomainName DomainName -PromptLoginBehavior Disabled
140-
```
141-
142-
After you run this command, Office 365 applications won't include the prompt=login parameter in each authentication request.
125+
1. **translateToFreshPasswordAuth**: Microsoft Entra ID sends wauth and wfresh to AD FS instead of prompt=login. This leads to an authentication request to use forms-based authentication.
126+
2. **nativeSupport**: The prompt=login parameter is sent as is to AD FS.
127+
3. **disabled**: Nothing is sent to AD FS.
143128

144129
<a name='non-azure-ad-scenario'></a>
145130

@@ -229,13 +214,23 @@ If the application that you want to access is Microsoft Online Services for Offi
229214
1. Get the current SupportsMFA domain federation setting by running the following command:
230215

231216
```powershell
232-
Get-MSOLDomainFederationSettings -DomainName DomainName | FL *
217+
Connect-MgGraph -scopes Domain.ReadWrite.All, Directory.ReadWrite.All
218+
Get-MgDomainFederationConfiguration -DomainId <domain_id> | FL *
233219
```
234220

221+
> [!NOTE]
222+
> \<domain_id> is a placeholder for your domain's name. For example, contoso.com.
223+
235224
2. If the SupportsMFA setting is FALSE, set it to TRUE by running the following command:
236225

237226
```powershell
238-
Set-MSOLDomainFederationSettings -DomainName DomainName -SupportsMFA $TRUE
227+
Update-MgDomainFederationConfiguration -DomainId <DomainName> -FederatedIdpMfaBehavior "acceptIfMfaDoneByFederatedIdp"
228+
```
229+
230+
3. Then, run the following command to sign out:
231+
232+
```powershell
233+
Disconnect-MgGraph
239234
```
240235

241236
### Check if SSO is disabled
@@ -267,7 +262,7 @@ Let's check the internal sign-in functionality using IdpInitiatedSignOn. To do t
267262
```
268263

269264
2. From a computer that is inside your network, visit the following page:
270-
`https://<FederationInstance>/adfs/ls/idpinitiatedsignon.aspx`
265+
`https://<FederationInstance>/adfs/ls/idpinitiatedsignon`
271266

272267
3. Enter the correct credentials of a valid user on the sign-in page.
273268

@@ -288,7 +283,7 @@ Then, check the external sign-in functionality using IdpInitiatedSignOn. Use the
288283
```
289284

290285
2. From a computer that is outside of your network, visit the following page:
291-
`https://<FederationInstance>/adfs/ls/idpinitiatedsignon.aspx`
286+
`https://<FederationInstance>/adfs/ls/idpinitiatedsignon`
292287

293288
3. Enter the correct credentials of a valid user on the sign-in page.
294289

@@ -626,11 +621,10 @@ If a user is trying to log in to Microsoft Entra ID, they will be redirected to
626621

627622
1. [Download](https://connect.microsoft.com/site1164/Downloads/DownloadDetails.aspx?DownloadID=59185) and install the Azure AD PowerShell module for Windows PowerShell.
628623
1. Open Windows PowerShell with the "Run as administrator" option.
629-
1. Initiate a connection to Microsoft Entra ID by running the following command:
630-
`Connect-MsolService`
624+
1. Initiate a connection to Microsoft Entra ID by running `Connect-MgGraph` with proper permission.
631625
1. Provide the global administrator credential for the connection.
632626
1. Get the list of users in the Microsoft Entra ID by running the following command:
633-
`Get-MsolUser`
627+
`Get-MgUser`
634628
1. Verify if the user is in the list.
635629

636630
If the user is not in the list, sync the user to Microsoft Entra ID.
@@ -906,132 +900,6 @@ DS Mapper Usage : Disabled
906900
Negotiate Client Certificate : Disabled
907901
```
908902

909-
### Run script to automatically detect problems
910-
911-
To automatically detect problems with the proxy trust relationship, run the following script. Based on the problem detected, take the action accordingly.
912-
913-
```powershell
914-
param
915-
(
916-
[switch]$syncproxytrustcerts
917-
)
918-
function checkhttpsyscertbindings()
919-
{
920-
Write-Host; Write-Host("1 – Checking http.sys certificate bindings for potential issues")
921-
$httpsslcertoutput = netsh http show sslcert
922-
$adfsservicefqdn = (Get-AdfsProperties).HostName
923-
$i = 1
924-
$certbindingissuedetected = $false
925-
While($i -lt $httpsslcertoutput.count)
926-
{
927-
$ipport = $false
928-
$hostnameport = $false
929-
if ( ( $httpsslcertoutput[$i] -match "IP:port" ) ) { $ipport = $true }
930-
elseif ( ( $httpsslcertoutput[$i] -match "Hostname:port" ) ) { $hostnameport = $true }
931-
## Check for IP specific certificate bindings
932-
if ( ( $ipport -eq $true ) )
933-
{
934-
$httpsslcertoutput[$i]
935-
$ipbindingparsed = $httpsslcertoutput[$i].split(":")
936-
if ( ( $ipbindingparsed[2].trim() -ne "0.0.0.0" ) -and ( $ipbindingparsed[3].trim() -eq "443") )
937-
{
938-
$warning = "There is an IP specific binding on IP " + $ipbindingparsed[2].trim() + " which may conflict with the AD FS port 443 cert binding." | Write-Warning
939-
$certbindingissuedetected = $true
940-
}
941-
$i = $i + 14
942-
continue
943-
}
944-
## check that CTL Store is set for ADFS service binding
945-
elseif ( $hostnameport -eq $true )
946-
{
947-
$httpsslcertoutput[$i]
948-
$ipbindingparsed = $httpsslcertoutput[$i].split(":")
949-
If ( ( $ipbindingparsed[2].trim() -eq $adfsservicefqdn ) -and ( $ipbindingparsed[3].trim() -eq "443") -and ( $httpsslcertoutput[$i+10].split(":")[1].trim() -ne "AdfsTrustedDevices" ) )
950-
{
951-
Write-Warning "ADFS Service binding does not have CTL Store Name set to AdfsTrustedDevices"
952-
$certbindingissuedetected = $true
953-
}
954-
$i = $i + 14
955-
continue
956-
}
957-
$i++
958-
}
959-
If ( $certbindingissuedetected -eq $false ) { Write-Host "Check Passed: No certificate binding issues detected" }
960-
}
961-
function checkadfstrusteddevicesstore()
962-
{
963-
## check for CA issued (non-self signed) certs in the AdfsTrustedDevices cert store
964-
Write-Host; Write-Host "2 – Checking AdfsTrustedDevices cert store for non-self signed certificates"
965-
$certlist = Get-Childitem cert:\LocalMachine\AdfsTrustedDevices -recurse | Where-Object {$_.Issuer -ne $_.Subject}
966-
If ( $certlist.count -gt 0 )
967-
{
968-
Write-Warning "The following non-self signed certificates are present in the AdfsTrustedDevices store and should be removed"
969-
$certlist | Format-List Subject
970-
}
971-
Else { Write-Host "Check Passed: No non-self signed certs present in AdfsTrustedDevices cert store" }
972-
}
973-
function checkproxytrustcerts
974-
{
975-
Param ([bool]$repair=$false)
976-
Write-Host; Write-Host("3 – Checking AdfsTrustedDevices cert store is in sync with ADFS Proxy Trust config")
977-
$doc = new-object Xml
978-
$doc.Load("$env:windir\ADFS\Microsoft.IdentityServer.Servicehost.exe.config")
979-
$connString = $doc.configuration.'microsoft.identityServer.service'.policystore.connectionString
980-
$command = "Select ServiceSettingsData from [IdentityServerPolicy].[ServiceSettings]"
981-
$cli = new-object System.Data.SqlClient.SqlConnection
982-
$cli.ConnectionString = $connString
983-
$cmd = new-object System.Data.SqlClient.SqlCommand
984-
$cmd.CommandText = $command
985-
$cmd.Connection = $cli
986-
$cli.Open()
987-
$configString = $cmd.ExecuteScalar()
988-
$configXml = new-object XML
989-
$configXml.LoadXml($configString)
990-
$rawCerts = $configXml.ServiceSettingsData.SecurityTokenService.ProxyTrustConfiguration._subjectNameIndex.KeyValueOfstringArrayOfX509Certificate29zVOn6VQ.Value.X509Certificate2
991-
#$ctl = dir cert:\LocalMachine\ADFSTrustedDevices
992-
$store = new-object System.Security.Cryptography.X509Certificates.X509Store("ADFSTrustedDevices","LocalMachine")
993-
$store.open("MaxAllowed")
994-
$atLeastOneMismatch = $false
995-
$badCerts = @()
996-
foreach($rawCert in $rawCerts)
997-
{
998-
$rawCertBytes = [System.Convert]::FromBase64String($rawCert.RawData.'#text')
999-
$cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(,$rawCertBytes)
1000-
$now = Get-Date
1001-
if ( ($cert.NotBefore -lt $now) -and ($cert.NotAfter -gt $now))
1002-
{
1003-
$certThumbprint = $cert.Thumbprint
1004-
$certSubject = $cert.Subject
1005-
$ctlMatch = dir cert:\localmachine\ADFSTrustedDevices\$certThumbprint -ErrorAction SilentlyContinue
1006-
if ($ctlMatch -eq $null)
1007-
{
1008-
$atLeastOneMismatch = $true
1009-
Write-Warning "This cert is NOT in the CTL: $certThumbprint – $certSubject"
1010-
if ($repair -eq $true)
1011-
{
1012-
write-Warning "Attempting to repair"
1013-
$store.Add($cert)
1014-
Write-Warning "Repair successful"
1015-
}
1016-
else
1017-
{
1018-
Write-Warning ("Please install KB.2964735 or re-run script with -syncproxytrustcerts switch to add missing Proxy Trust certs to AdfsTrustedDevices cert store")
1019-
}
1020-
}
1021-
}
1022-
}
1023-
$store.Close()
1024-
if ($atLeastOneMismatch -eq $false)
1025-
{
1026-
Write-Host("Check Passed: No mismatched certs found. CTL is in sync with DB content")
1027-
}
1028-
}
1029-
checkhttpsyscertbindings
1030-
checkadfstrusteddevicesstore
1031-
checkproxytrustcerts($syncproxytrustcerts)
1032-
Write-Host; Write-Host("All checks completed.")
1033-
```
1034-
1035903
### Problem 1: There is an IP specific binding
1036904

1037905
The binding may conflict with the AD FS certificate binding on port 443.
@@ -1072,23 +940,6 @@ If a CA issued certificate is in a certificate store where only self-signed cert
1072940

1073941
Therefore, delete any CA issued certificate from the AdfsTrustedDevices certificate store.
1074942

1075-
### Problem 4: Install KB2964735 or re-run the script with -syncproxytrustcerts
1076-
1077-
When a proxy trust relationship is established with an AD FS server, the client certificate is written to the AD FS configuration database and added to the AdfsTrustedDevices certificate store on the AD FS server. For an AD FS farm deployment, the client certificate is expected to be synced to the other AD FS servers. If the sync doesn't happen for some reason, a proxy trust relationship will only work against the AD FS server the trust was established with, but not against the other AD FS servers.
1078-
1079-
To solve this problem, use one of the following methods.
1080-
1081-
#### Method 1
1082-
1083-
Install the update documented in [KB 2964735](https://support.microsoft.com/topic/700e0502-c19a-54e4-9c5f-65c2844d9a9f) on all AD FS servers. After the update is installed, a sync of the client certificate is expected to happen automatically.
1084-
1085-
#### Method 2
1086-
1087-
Run the script with the – syncproxytrustcerts switch to manually sync the client certificates from the AD FS configuration database to the AdfsTrustedDevices certificate store. The script should be run on all the AD FS servers in the farm.
1088-
1089-
> [!NOTE]
1090-
> This is not a permanent solution because the client certificates will be renewed on a regular basis.
1091-
1092943
### Problem 5: All checks are passed. But the problem persists
1093944

1094945
Check if there is a time or time zone mismatch. If time matches but the time zone doesn't, proxy trust relationship will also fail to be established.
@@ -1238,3 +1089,14 @@ The following are the device claims. The authorization rules may use some of the
12381089
If there is a missing claim, follow the steps in [Configure On-Premises Conditional Access using registered devices](/windows-server/identity/ad-fs/operations/configure-device-based-conditional-access-on-premises) to make sure the environment is setup for device authentication.
12391090

12401091
If all the claims are present, see if the values of the claims from the Dump Token app match the values required in the authorization policy.
1092+
1093+
## Reference
1094+
1095+
For more informaiton, see the following articles:
1096+
1097+
- [Get-MgDomainFederationConfiguration](/powershell/module/microsoft.graph.identity.directorymanagement/get-mgdomainfederationconfiguration)
1098+
- [Update-MgDomainFederationConfiguration](/powershell/module/microsoft.graph.identity.directorymanagement/update-mgdomainfederationconfiguration)
1099+
- [Connect-MgGraph](/powershell/microsoftgraph/authentication-commands#use-connect-mggraph)
1100+
- [Disconnect-MgGraph](/powershell/module/microsoft.graph.authentication/disconnect-mggraph)
1101+
- [Get-MgUser](/powershell/module/microsoft.graph.users/get-mguser)
1102+
- [internalDomainFederation resource type](/graph/api/resources/internaldomainfederation)

0 commit comments

Comments
 (0)