What Is Active Directory Federation Services

Active Directory Federation Services (AD FS) is a Windows Server role that provides federated identity and single sign-on (SSO) capabilities. It enables users to authenticate once against their organization’s Active Directory and then access applications and services in other organizations or cloud platforms without re-entering credentials. AD FS implements the WS-Federation, WS-Trust, SAML 2.0, and OAuth 2.0/OpenID Connect protocols, making it compatible with a wide range of enterprise applications including Microsoft 365, Salesforce, and custom SAML-aware web applications.

In an AD FS deployment, the organization hosting the identity store (Active Directory) operates as the Claims Provider, and the organization hosting the application is the Relying Party. The AD FS server issues security tokens containing claims — assertions about the authenticated user such as their name, email address, group memberships, or department. The relying party application consumes these claims to authorize access without ever directly querying Active Directory.

AD FS Prerequisites

Before installing AD FS on Windows Server 2022, ensure the following prerequisites are in place. The AD FS server must be a domain member. You need a service account — either a traditional domain user account or a Group Managed Service Account (gMSA), with gMSA strongly preferred for production use. A valid SSL certificate is required for the AD FS service, with a subject name matching the federation service name (e.g., adfs.corp.local) and Subject Alternative Names as needed. This certificate must be trusted by all client browsers and devices that will access the federation service, which typically means using an internal CA-issued certificate published via AD CS autoenrollment or an externally trusted certificate.

Create the gMSA for AD FS before installation:

# Create a Key Distribution Services root key if not already present
Add-KdsRootKey -EffectiveTime (Get-Date).AddHours(-10)

# Create the gMSA for AD FS
New-ADServiceAccount `
    -Name "svc-adfs" `
    -DNSHostName "adfs.corp.local" `
    -PrincipalsAllowedToRetrieveManagedPassword "ADFS-Servers$"   # AD group containing AD FS servers

# Install the gMSA on the AD FS server
Install-ADServiceAccount -Identity "svc-adfs"
Test-ADServiceAccount -Identity "svc-adfs"

Install the AD FS Windows feature:

Install-WindowsFeature -Name ADFS-Federation -IncludeManagementTools

Creating the AD FS Farm with Install-AdfsFarm

After the feature is installed, configure the first AD FS server (the primary federation server) using Install-AdfsFarm. Retrieve the SSL certificate thumbprint first:

# Find the SSL certificate thumbprint
Get-ChildItem Cert:LocalMachineMy | 
    Where-Object { $_.Subject -like "*adfs.corp.local*" } | 
    Select-Object Subject, Thumbprint, NotAfter
# Install the first AD FS farm node
$thumbprint = "AABBCCDDEEFF00112233445566778899AABBCCDD"  # Replace with actual thumbprint

Install-AdfsFarm `
    -CertificateThumbprint $thumbprint `
    -FederationServiceName "adfs.corp.local" `
    -FederationServiceDisplayName "Corp Federation Service" `
    -GroupServiceAccountIdentifier "corpsvc-adfs$" `
    -Credential (Get-Credential)

The -GroupServiceAccountIdentifier parameter accepts the gMSA in the format DOMAINaccountname$. After the command completes, verify the AD FS service is running:

Get-Service adfssrv
Get-AdfsFarmInformation

To add additional AD FS servers to the farm for high availability:

Add-AdfsFarmNode `
    -CertificateThumbprint $thumbprint `
    -GroupServiceAccountIdentifier "corpsvc-adfs$" `
    -PrimaryComputerName "ADFS01.corp.local" `
    -Credential (Get-Credential)

Configuring Relying Party Trusts

A Relying Party Trust (RPT) defines the relationship between the AD FS server and an application that accepts tokens. Most modern applications provide federation metadata URLs that allow AD FS to automatically import the required configuration. To add a relying party trust from a metadata URL:

Add-AdfsRelyingPartyTrust `
    -Name "CorpExpenseApp" `
    -MetadataURL "https://expenseapp.corp.local/federationmetadata/2007-06/federationmetadata.xml" `
    -AutoUpdateEnabled $true `
    -MonitoringEnabled $true `
    -Enabled $true

For applications that do not provide a metadata URL, manually specify the SAML endpoints and certificate:

Add-AdfsRelyingPartyTrust `
    -Name "LegacySamlApp" `
    -Identifier "https://legacyapp.corp.local" `
    -SamlEndpoint (New-AdfsSamlEndpoint `
        -Binding POST `
        -Protocol SAMLAssertionConsumer `
        -Uri "https://legacyapp.corp.local/saml/acs") `
    -RequestSigningCertificate (Get-PfxCertificate "C:certslegacyapp.cer") `
    -Enabled $true

To view all configured relying party trusts:

Get-AdfsRelyingPartyTrust | Select-Object Name, Identifier, Enabled | Format-Table -AutoSize

Configuring Claim Rules

Claim rules define what information AD FS extracts from Active Directory and includes in the security token sent to the relying party. There are three main rule types: issuance transform rules (transform or pass-through claims), issuance authorization rules (control who can access the relying party), and delegation authorization rules.

To add claim rules to a relying party trust using PowerShell, define the rules in ADFS claim rule language:

# Define claim rules as a string
$claimRules = @"
@RuleTemplate = "LdapClaims"
@RuleName = "Send LDAP Attributes"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", 
   Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", 
    types = (
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
        "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups"
    ), 
    query = ";mail,givenName,sn,tokenGroups;{0}", 
    param = c.Value);
"@

# Apply the rules to a relying party trust
Set-AdfsRelyingPartyTrust `
    -TargetName "CorpExpenseApp" `
    -IssuanceTransformRulesFile $claimRules

To add an issuance authorization rule that restricts access to members of a specific AD group:

$authRule = @"
@RuleTemplate = "Authorization"
@RuleName = "Allow Expense App Users Group"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", 
   Value == "S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-1234"]
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "PermitUsersWithClaim");
"@

Set-AdfsRelyingPartyTrust `
    -TargetName "CorpExpenseApp" `
    -IssuanceAuthorizationRulesFile $authRule

Deploying the Web Application Proxy

The Web Application Proxy (WAP) is an AD FS proxy role deployed in the DMZ that allows external users to access AD FS-protected applications without VPN. WAP forwards authentication requests to the internal AD FS farm and pre-authenticates users before publishing applications. Install WAP on a non-domain-joined server in the DMZ (or a domain-joined server with network access to the AD FS farm):

Install-WindowsFeature -Name Web-Application-Proxy -IncludeManagementTools

Configure the WAP to connect to the AD FS farm using the federation service name and the AD FS trust certificate:

$adfsCredential = Get-Credential  # Domain admin credentials

Install-WebApplicationProxy `
    -FederationServiceName "adfs.corp.local" `
    -FederationServiceTrustCredential $adfsCredential `
    -CertificateThumbprint "AABBCCDDEEFF00112233445566778899AABBCCDD"

After WAP is joined to the AD FS farm, publish an application through the proxy:

Add-WebApplicationProxyApplication `
    -BackendServerURL "https://expenseapp.corp.local" `
    -ExternalURL "https://expenseapp.contoso.com" `
    -Name "Corp Expense Application" `
    -ExternalPreAuthentication ADFS `
    -ADFSRelyingPartyName "CorpExpenseApp" `
    -ExternalCertificateThumbprint "EXTERNALCERTTHUMBPRINT"

Configuring Multi-Factor Authentication

AD FS on Windows Server 2022 supports additional authentication methods beyond username and password through its multi-factor authentication (MFA) framework. Windows Hello for Business, certificate-based authentication, and third-party MFA providers (Microsoft Entra MFA, Duo, RSA) can be integrated as additional authentication methods.

To configure a per-relying-party MFA policy requiring a second factor for all users:

# View available additional authentication providers
Get-AdfsAuthenticationProvider | Select-Object Name, IsEnabled

# Configure global MFA policy to require additional auth for extranet users
Set-AdfsAdditionalAuthenticationRule -AdditionalAuthenticationRules `
    'c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"] 
    => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", 
             Value = "http://schemas.microsoft.com/claims/multipleauthn");'

# Set per-relying-party additional auth requirement
Set-AdfsRelyingPartyTrust `
    -TargetName "CorpExpenseApp" `
    -AdditionalAuthenticationRules `
    'c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork"] 
    => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", 
             Value = "http://schemas.microsoft.com/claims/multipleauthn");'

AD FS Endpoints and Configuration

AD FS exposes multiple endpoints for different protocol operations. Use Get-AdfsEndpoint to see all configured endpoints and their status:

Get-AdfsEndpoint | Where-Object { $_.Enabled -eq $true } | 
    Select-Object FullUrl, Protocol, Proxy, AddressPath | 
    Format-Table -AutoSize

Important endpoints include: /adfs/ls (passive sign-in for browser-based clients), /adfs/services/trust/13/windowstransport (WS-Trust for Windows Integrated Auth), /adfs/oauth2/authorize and /adfs/oauth2/token (OAuth 2.0), and /adfs/federationmetadata/2007-06/federationmetadata.xml (metadata endpoint used by relying parties for automatic configuration).

To enable the IdP-Initiated Sign-On page for testing (disabled by default in Windows Server 2022 for security):

Set-AdfsProperties -EnableIdPInitiatedSignonPage $true

Then navigate to https://adfs.corp.local/adfs/ls/idpinitiatedsignon.aspx to test authentication manually. Disable this page after testing:

Set-AdfsProperties -EnableIdPInitiatedSignonPage $false

Troubleshooting AD FS

AD FS writes diagnostic events to the Application and Services Logs under AD FS > Admin and AD FS Tracing in Event Viewer. Enable verbose tracing for detailed diagnostics:

# Enable AD FS debug/tracing event log
wevtutil sl "AD FS Tracing/Debug" /e:true /l:5

# View recent AD FS admin events
Get-WinEvent -LogName "AD FS/Admin" -MaxEvents 50 | 
    Select-Object TimeCreated, Id, LevelDisplayName, Message |
    Format-Table -AutoSize -Wrap

Common AD FS issues and their diagnostics:

Token signing certificate mismatch: The relying party has an outdated copy of the AD FS token signing certificate. Run Update-AdfsRelyingPartyTrust -TargetName "AppName" to refresh the metadata, or manually update the certificate fingerprint in the application.

Service account password expiry: If using a traditional service account, the AD FS service will fail to start when the password expires. Migrate to a gMSA to eliminate this issue.

Clock skew: SAML assertions have a validity window and will be rejected if the server clocks are out of sync. Ensure all AD FS, WAP, and relying party servers are synchronizing time from a reliable NTP source.

# Check AD FS service health and configuration
Get-AdfsProperties | Select-Object HostName, HttpsPort, HttpPort, IdTokenIssuer
Test-AdfsFarmInstallation

# Check token signing and encryption certificates
Get-AdfsCertificate | Select-Object CertificateType, Thumbprint, IsPrimary, Certificate