Not every organization wants to move from ADFS to Microsoft Entra ID. Some want to stay vendor-neutral, keep identity infrastructure on-premises, or simply avoid per-user licensing costs. Keycloak fills that gap — it handles SAML 2.0, OIDC, and integrates directly with Active Directory via LDAP federation.

The migration isn’t trivial, though. ADFS and Keycloak have different architectural models, and some ADFS features don’t have direct Keycloak equivalents. This guide covers the practical steps, common blockers, and configuration patterns you’ll need.

Architecture Differences

Before diving into migration steps, understand what changes:

AspectADFSKeycloak
Identity SourceBuilt into AD trustLDAP Federation (connects to AD)
SAML SupportNativeNative
WS-FederationNativeCommunity extension only
OIDC/OAuthAdded in ADFS 2016+Native, first-class
MFAExternal adapter or Azure MFABuilt-in OTP, WebAuthn, conditional
Session ManagementPer-application tokensCentralized SSO sessions
DeploymentWindows Server roleDocker/Kubernetes/bare metal (Java)

The fundamental shift: ADFS relies on the Windows domain trust model and is tightly coupled to Active Directory. Keycloak is a standalone identity broker that connects to AD as an external user store.

Step 1: Set Up Keycloak with AD Integration

Deploy Keycloak

For production, run Keycloak 26.x on a supported database (PostgreSQL recommended):

# Docker Compose for initial setup
docker run -d --name keycloak \
  -p 8443:8443 \
  -e KC_DB=postgres \
  -e KC_DB_URL=jdbc:postgresql://db:5432/keycloak \
  -e KC_DB_USERNAME=keycloak \
  -e KC_DB_PASSWORD=changeme \
  -e KC_HOSTNAME=idp.yourdomain.com \
  -e KC_HTTPS_CERTIFICATE_FILE=/opt/keycloak/conf/server.crt \
  -e KC_HTTPS_CERTIFICATE_KEY_FILE=/opt/keycloak/conf/server.key \
  quay.io/keycloak/keycloak:26.5.2 start

Configure LDAP User Federation

In the Keycloak admin console, navigate to your realm → User Federation → Add LDAP provider:

SettingValue
VendorActive Directory
Connection URLldaps://dc01.corp.local:636
Bind DNCN=svc-keycloak,OU=Service Accounts,DC=corp,DC=local
Bind Credential(service account password)
Users DNOU=Users,DC=corp,DC=local
Username LDAP attributesAMAccountName
UUID LDAP attributeobjectGUID
User Object Classesperson, organizationalPerson, user
Search ScopeSubtree

Key settings that catch people off guard:

  • Import Users: Set to ON for the migration period so Keycloak caches user data. You can switch to NO_IMPORT later if you want pure pass-through.
  • Sync Registrations: OFF unless you want Keycloak to write back to AD.
  • Periodic Full Sync: Enable with a 1-hour period during migration to keep users current.

Map AD Groups

Add a Group LDAP mapper to import AD security groups:

  • LDAP Groups DN: OU=Groups,DC=corp,DC=local
  • Group Name LDAP Attribute: cn
  • Membership LDAP Attribute: member
  • Mode: READ_ONLY

This gives you AD group membership in Keycloak, which you’ll use for SAML role claims.

Step 2: Migrate SAML Applications

Export ADFS Relying Party Configuration

For each SAML relying party in ADFS, grab the essential settings:

Get-AdfsRelyingPartyTrust -Name "My App" | Select-Object `
    Identifier, SamlEndpoint, IssuanceTransformRules, `
    EncryptClaims, SignedSamlRequestsRequired, TokenLifetime

Create Keycloak SAML Client

In Keycloak admin console → Clients → Create client:

  1. Client ID: Use the same Entity ID from ADFS (e.g., https://app.yourdomain.com/saml)
  2. Client Protocol: SAML
  3. Valid Redirect URIs: The ACS URL from ADFS SAML endpoint
  4. Name ID Format: Match your ADFS NameID claim (typically urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress or unspecified)

Translate Claim Rules to Protocol Mappers

ADFS claim rules become Keycloak Protocol Mappers on the SAML client.

NameID from email — ADFS rule:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
 => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
    Value = c.Value);

Keycloak mapper: Built-in, just set Name ID Format to email and Force Name ID Format to ON.

Group/Role claim — ADFS rule that maps group SID to a role:

In Keycloak, create a Role list mapper or a Group Membership mapper:

  • Mapper Type: Group list
  • Group attribute name: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
  • Full group path: OFF
  • Single Group Attribute: ON

Custom attribute claim — ADFS pulling from AD attribute:

Create a User Attribute mapper:

  • SAML Attribute Name: http://schemas.yourdomain.com/claims/department
  • User Attribute: department (mapped from LDAP federation)

Step 3: Handle WS-Federation Apps

This is the trickiest part. Keycloak doesn’t support WS-Federation natively.

Option A: Convert to SAML or OIDC — The cleanest approach. Most WS-Fed apps (especially .NET apps using WIF) can switch to SAML with minimal code changes. In ASP.NET Core:

// Old: WS-Federation
services.AddAuthentication()
    .AddWsFederation(options => {
        options.MetadataAddress = "https://adfs.corp.local/federationmetadata/...";
        options.Wtrealm = "https://myapp.corp.local";
    });

// New: SAML via Keycloak
services.AddAuthentication()
    .AddSaml2(options => {
        options.SPOptions.EntityId = new EntityId("https://myapp.corp.local");
        options.IdentityProviders.Add(
            new IdentityProvider(new EntityId("https://idp.yourdomain.com/realms/corp"), options.SPOptions)
            {
                MetadataLocation = "https://idp.yourdomain.com/realms/corp/protocol/saml/descriptor"
            });
    });

Option B: Use the keycloak-wsfed extension — The keycloak-wsfed community extension adds WS-Federation protocol support. Note that it lags behind Keycloak releases — verify compatibility with your Keycloak version before relying on it.

Option C: Keep ADFS as a bridge — For a small number of WS-Fed apps, you can federate ADFS as a downstream IdP under Keycloak. Keycloak becomes the primary IdP, and ADFS handles only the remaining WS-Fed apps. Not elegant, but pragmatic.

Step 4: Testing and Cutover

Parallel Run

Run Keycloak alongside ADFS during testing:

  1. Configure your first test application to point to Keycloak’s SAML endpoint instead of ADFS
  2. Verify login works with AD credentials (via LDAP federation)
  3. Check all claims/attributes are present in the SAML response
  4. Test logout — ADFS and Keycloak handle SLO differently

Use Keycloak’s SAML Tracer or browser extensions to compare the SAML assertion structure between ADFS and Keycloak.

DNS Cutover Strategy

For a gradual rollout, use DNS-based switching:

  1. ADFS is at sts.corp.local — keep this active
  2. Keycloak is at idp.corp.local — new endpoint
  3. Migrate apps one by one from the ADFS endpoint to the Keycloak endpoint
  4. Once all apps are migrated, optionally point sts.corp.local to Keycloak for any hardcoded references

What to Validate

  • User login with AD credentials works
  • MFA enrollment and challenge (if applicable)
  • SAML assertions contain correct NameID format
  • All custom claims/attributes present
  • Group-based role claims match ADFS output
  • Single Logout (SLO) functions correctly
  • Session timeout behavior matches expectations
  • Service account / programmatic token requests work

Keycloak Features You Gain

After migration, take advantage of capabilities ADFS lacks:

  • Built-in WebAuthn/Passkey support: No third-party adapter needed
  • Fine-grained authentication flows: Conditional OTP, identity brokering, step-up auth
  • Admin REST API: Full automation of user, client, and realm management
  • Kubernetes-native deployment: Helm charts and the Keycloak Operator for production clusters
  • OIDC as first-class protocol: Modern SPAs and APIs work natively without the OAuth bolt-on that ADFS provides

Cost Comparison

For a 5,000-user organization:

ItemADFSKeycloak
Software LicenseIncluded with Windows ServerFree (Apache 2.0)
Infrastructure2+ Windows Servers + WAP2+ containers (Linux)
Windows Server CALs~$20/userNot needed
SSL CertificatesRequiredRequired
DatabaseWID or SQL ServerPostgreSQL (free)
SupportMicrosoft Premier/UnifiedRed Hat SSO or community

The infrastructure savings alone often justify the migration, particularly for organizations running ADFS on dedicated Windows Server VMs with SQL Server backend.

Keycloak isn’t zero-cost — you still need operational expertise and potentially Red Hat support for the commercial build. But the licensing model is fundamentally different: you pay for support, not per-user fees.