Skip to content

ADFS Authentication Setup

This guide walks you through integrating RAMP with Active Directory Federation Services (ADFS) for federated authentication and single sign-on.

Active Directory Federation Services (ADFS) provides federated identity and access management across organizational boundaries. Benefits include:

  • Single Sign-On (SSO) — Users authenticate once for multiple applications
  • Federated authentication — Works across organizations and trusts
  • Claims-based access — Fine-grained authorization based on user attributes
  • Integration with Active Directory — Leverage existing user directory

Best For: Organizations with existing ADFS infrastructure, federated access scenarios (partners, subsidiaries), compliance requirements for centralized authentication, Windows Server environments.

Before you begin, ensure you have:

  • ADFS Server (version 2016 or later for OIDC support)
  • Active Directory domain
  • SSL Certificate installed on ADFS server
  • Admin access to ADFS Management Console
  • RAMP deployment (backend + frontend)
+--------------+ +--------------+
| Browser |---(1) Access RAMP------>| RAMP Web |
| (Client) | | (Frontend) |
+--------------+ +--------------+
| |
| (2) Redirect to ADFS |
v |
+--------------+ |
| ADFS |<---(3) Auth request------------+
| Server |
+--------------+
|
| (4) User authenticates
v
+--------------+ +--------------+
| Active |<---(5) Verify user------| ADFS |
| Directory | | Server |
+--------------+ +--------------+
|
(6) Return tokens |
<-----------------------------+

    1. Open ADFS Management Console (adfs.msc)
    2. Navigate to Application Groups
    3. Right-click -> Add Application Group…
    4. Configuration:
      • Name: RAMP Application
      • Description: RAMP Runbook Automation Platform
      • Template: Select Web browser accessing a web application
      • Click Next

    Native Application Settings:

    • Name: RAMP Web Client
    • Redirect URI: https://ramp.yourdomain.com/_auth/callback
    • Client Identifier: (Auto-generated — save this for later, e.g., abc123-def456)
    • Click Next

    Access Control Policy:

    • Select Permit everyone (or create custom policy)
    • Click Next

    Summary:

    • Review settings
    • Click Next -> Close

    For development and additional endpoints:

    1. Right-click RAMP Application -> Properties
    2. Select the Web browser application
    3. Click Edit…
    4. Click Add to add additional redirect URIs:
      • https://ramp.yourdomain.com/_auth/callback (production)
      • http://localhost:5173/_auth/callback (development)
      • https://localhost:5173/_auth/callback (development with SSL)
    5. Click OK -> Apply
  1. Claims rules map Active Directory attributes to tokens that RAMP receives.

    1. In ADFS Management, expand Application Groups
    2. Right-click RAMP Application -> Properties
    3. Select the application -> Click Edit…
    4. Go to Issuance Transform Rules tab
    5. Click Add Rule…
    6. Rule Template: Send LDAP Attributes as Claims
    7. Click Next
    8. Claim rule name: Send AD Attributes
    9. Attribute store: Active Directory
    10. Configure mappings:
    LDAP AttributeOutgoing Claim Type
    SAM-Account-NameName ID
    E-Mail-AddressesE-Mail Address
    Display-NameName
    Given-NameGiven Name
    SurnameSurname
    User-Principal-NameUPN
    1. Click Finish -> OK -> Apply

    OIDC requires a sub claim:

    1. Click Add Rule… again
    2. Rule Template: Transform an Incoming Claim
    3. Click Next
    4. Claim rule name: Transform Name ID to sub
    5. Incoming claim type: Name ID
    6. Outgoing claim type: Subject (or type sub if not in dropdown)
    7. Outgoing name ID format: (leave blank)
    8. Pass through all claim values: Checked
    9. Click Finish -> OK -> Apply
  2. Open browser and navigate to:

    https://adfs.yourdomain.com/adfs/.well-known/openid-configuration

    Expected: JSON document with OIDC endpoints

    Important Values to Note:

    • Authority: https://adfs.yourdomain.com/adfs
    • Authorization endpoint: https://adfs.yourdomain.com/adfs/oauth2/authorize
    • Token endpoint: https://adfs.yourdomain.com/adfs/oauth2/token
    • UserInfo endpoint: https://adfs.yourdomain.com/adfs/userinfo

    The Client ID was auto-generated in the first step. To find it:

    1. ADFS Management -> Application Groups -> RAMP Application
    2. Double-click the application -> Properties
    3. Copy the Client Identifier (e.g., abc123-def456-ghi789)
  3. Create or update .env.production in src/RAMP.Web/:

    Terminal window
    # Enable OIDC Authentication
    VITE_OIDC_ENABLED=true
    # ADFS OIDC Configuration
    VITE_OIDC_AUTHORITY=https://adfs.yourdomain.com/adfs
    VITE_OIDC_CLIENT_ID=your-client-id-from-step-1
    VITE_OIDC_REDIRECT_URI=https://ramp.yourdomain.com/_auth/callback
    VITE_OIDC_POST_LOGOUT_REDIRECT_URI=https://ramp.yourdomain.com
    VITE_OIDC_SCOPE=openid profile email allatclaims
    VITE_OIDC_RESPONSE_TYPE=code
    # API endpoint
    VITE_API_BASE_URL=https://ramp.yourdomain.com/api

    Configuration Notes:

    • allatclaims scope requests all configured claims from ADFS
    • code response type uses Authorization Code flow (most secure)
  4. The backend validates tokens but doesn’t require ADFS-specific configuration. Update appsettings.json:

    {
    "Jwt": {
    "Secret": "YourSecretKeyAtLeast32CharactersLong!",
    "Issuer": "RAMP.API",
    "Audience": "RAMP.Web",
    "AccessTokenExpirationMinutes": 480,
    "RefreshTokenExpirationDays": 30
    }
    }
  5. Start RAMP frontend:

    Terminal window
    cd src/RAMP.Web
    npm run dev

    Navigate to RAMP:

    • Development: http://localhost:5173
    • Production: https://ramp.yourdomain.com

    Expected flow:

    • Redirected to ADFS login page
    • Enter your domain credentials
    • Redirected back to RAMP after successful auth
    • Your name and email appear in RAMP UI

    Verify Claims:

    1. Open browser Developer Tools (F12)
    2. Go to Network tab
    3. Find the callback request (e.g., /_auth/callback?code=...)
    4. Inspect the JWT token (decode at jwt.io)
    5. Verify claims include: sub, email, name

Restrict RAMP access to specific Active Directory groups:

Terminal window
# PowerShell - Run on ADFS server
$rule = @"
@RuleName = "Permit RAMP Users Only"
exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid",
Value =~ "RAMP-Users"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit",
Value = "true");
"@
Set-AdfsRelyingPartyTrust -TargetName "RAMP Application" `
-IssuanceAuthorizationRules $rule

This means only users in the “RAMP-Users” AD group can authenticate. Others will be denied at ADFS (before reaching RAMP).

Require MFA for RAMP access:

Terminal window
# Require MFA for all RAMP users
Set-AdfsRelyingPartyTrust -TargetName "RAMP Application" `
-AdditionalAuthenticationRules 'c:[] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn");'

This forces an MFA challenge (SMS, Microsoft Authenticator, etc.) on login. MFA policy is enforced by ADFS, not RAMP.

Map AD groups to role claims:

Terminal window
# Example: Map AD group to role claim
$ruleText = @"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid",
Value =~ "(?i)^RAMP-Administrators$"]
=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
Value = "Administrator");
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid",
Value =~ "(?i)^RAMP-Coordinators$"]
=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
Value = "Coordinator");
"@
Set-AdfsRelyingPartyTrust -TargetName "RAMP Application" `
-IssuanceTransformRules $ruleText

Configure how long tokens remain valid:

Terminal window
# Set access token lifetime to 1 hour (60 minutes)
Set-AdfsRelyingPartyTrust -TargetName "RAMP Application" `
-TokenLifetime 60
# Disable "always require authentication" to allow refresh tokens
Set-AdfsRelyingPartyTrust -TargetName "RAMP Application" `
-AlwaysRequireAuthentication $false

Error: AADSTS50011: The reply URL specified in the request does not match

Solution:

  1. Verify VITE_OIDC_REDIRECT_URI exactly matches ADFS configuration
  2. Check in ADFS: Application Groups -> RAMP -> Properties -> Edit -> Redirect URIs
  3. Ensure protocol matches (http vs https)
  4. Check trailing slashes (some systems are strict)
  5. Port numbers must match (include :5173 for dev, omit for standard HTTPS port 443)

Error: invalid_client

Solution:

  1. Verify VITE_OIDC_CLIENT_ID matches exactly (case-sensitive)
  2. Check in ADFS: Application Groups -> RAMP -> Properties -> Client Identifier
  3. Ensure you’re using the correct environment (dev vs prod client ID)

Problem: User authenticates but email/name don’t appear in RAMP.

Solution:

  1. Verify claims rules exist:

    • ADFS Management -> Application Groups -> RAMP -> Properties -> Edit
    • Issuance Transform Rules tab should show “Send AD Attributes” rule
  2. Check user’s AD attributes:

    Terminal window
    Get-ADUser -Identity username -Properties mail, displayName, givenName, sn

    Ensure user has populated attributes

  3. Test claims in token:

    • Decode JWT token at jwt.io
    • Check if claims are present: email, name, given_name, family_name
  4. Add missing claims rules (see Step 2)

Problem: Browser console shows CORS policy errors.

Solution:

ADFS doesn’t support CORS for the token endpoint by design. Ensure you’re using:

  • Authorization Code flow (not Implicit flow)
  • OIDC library that handles token exchange server-side
  • RAMP’s frontend is using oidc-client-ts library correctly

Verify in .env:

Terminal window
VITE_OIDC_RESPONSE_TYPE=code # NOT "id_token" or "token"

Problem: User logs in successfully but has no permissions in RAMP.

Solution:

This is expected for first-time ADFS users. An administrator must assign roles:

  1. Log in as RAMP administrator
  2. Navigate to Admin -> Users
  3. Find the user (search by email)
  4. Click Assign Roles
  5. Assign appropriate roles (e.g., User, Coordinator, Administrator)

Alternatively, configure Bootstrap Administrators to auto-assign admin roles.


  • Use HTTPS everywhere — RAMP and ADFS
  • Valid SSL certificates — From trusted CA (not self-signed)
  • Short token lifetimes — 60 minutes for access tokens
  • Enable MFA — For all users or sensitive roles
  • Group-based access control — Restrict to authorized AD groups
  • Minimal claims — Only send necessary user attributes
  • Audit logging — Enable in ADFS (Applications and Services Logs -> AD FS -> Admin)
  • Regular updates — Apply ADFS and Windows Server patches
  • Network security — Firewall rules, limit ADFS access

Include in claims:

  • User ID (sub)
  • Email address
  • Display name
  • High-level roles (optional)

NEVER include in claims:

  • Social Security Numbers
  • Passwords or password hashes
  • Sensitive personal information
  • Detailed access permissions (use RAMP’s role system instead)

RAMP stores tokens in browser session storage:

  • Cleared when browser tab/window closes
  • Not accessible to other websites
  • Not persisted to disk
  • Users must re-login after browser restart (by design)

When a user authenticates via ADFS for the first time:

  1. RAMP receives claims from ADFS (sub, email, name)
  2. RAMP checks if user with this ProviderSubjectId exists
  3. If not, RAMP creates a new user account:
    • Username: From sub or upn claim
    • Email: From email claim
    • Display Name: From name claim
    • IdentityProvider: ADFS
    • ProviderSubjectId: Unique identifier from ADFS
  4. User is logged in but has no roles by default
  5. Administrator must assign roles (or use Bootstrap Admins)

ADFS must provide these claims for RAMP to work:

ClaimPurposeLDAP Source
subUnique user identifierSAM-Account-Name or UPN
emailUser’s email addressE-Mail-Addresses
nameDisplay nameDisplay-Name

If any are missing, user auto-provisioning will fail.


If you’re currently using WS-Federation with an older ADFS version:

  • Modern standard — Industry-standard authentication protocol
  • Better SPA support — Designed for single-page applications
  • JSON-based — Easier than XML (SAML/WS-Fed)
  • Wider ecosystem — More libraries and tools
  • Mobile-friendly — Better support for native apps
  1. Upgrade ADFS to 2016 or later (required for OIDC)
  2. Add OIDC application in ADFS (parallel to existing WS-Fed)
  3. Test OIDC in development environment
  4. Update RAMP frontend to use OIDC configuration
  5. Deploy and monitor
  6. Decommission WS-Fed application after successful migration

After configuring ADFS authentication: