Skip to content

How to use with ADFS

Chris Barth edited this page May 29, 2023 · 2 revisions

Active Directory Federation Services

This document attempts to describe a complete solution for integrating with AD FS.

Creating a self-signed certificate

Create a folder to contain your keys and certificates.

Download mellon_create_metadata.sh

Create a new key, certificate and relying party XML as follows:

./mellon_create_metadata.sh acme_tools_com https://acme_tools.com/adfs/postResponse

Retrieve AD FS Certificate

Use retrieve_adfs_certificate.sh to get your AD FS server's signing certificate:

./retrieve_adfs_certificate.sh https://adfs.acme_tools.com/ > adfs.acme_tools.com.crt

Create Relying Party

Copy the acme_tools_com.xml to your AD FS server. Use the AD FS management relying party wizard to import this XML, creating a relying party. Create claim rules to pass authentication information to your application.

This example assumes you will pass in the UPN.

Set AD FS Relying Party to sign the message and the assertion

Set-AdfsRelyingPartyTrust -TargetIdentifier "acme_tools_com" -SamlResponseSignature "MessageAndAssertion"

Create a Passport framework

Create a separate file for passport configuration (assumed to be config/passport.js).

var fs = require("fs"),
  passport = require("passport"),
  SamlStrategy = require("passport-saml").Strategy;
passport.serializeUser(function (user, done) {
  done(null, user);
});
passport.deserializeUser(function (user, done) {
  done(null, user);
});

passport.use(
  new SamlStrategy(
    {
      entryPoint: "https://adfs.acme_tools.com/adfs/ls/",
      issuer: "acme_tools_com",
      callbackUrl: "https://acme_tools.com/adfs/postResponse",
      privateKey: fs.readFileSync("/path/to/acme_tools_com.key", "utf-8"),
      cert: fs.readFileSync("/path/to/adfs.acme_tools.com.crt", "utf-8"),
      // other authn contexts are available e.g. windows single sign-on
      // see: https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.authenticationmethods?view=netframework-4.8#fields
      authnContext: [
        "http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password",
      ],
      identifierFormat: null,
      // this is configured under the Advanced tab in AD FS relying party
      signatureAlgorithm: "sha256",
      racComparison: "exact", // default to exact RequestedAuthnContext Comparison Type
      // From the metadata document
      audience: "https://adfs.acme_tools.com/FederationMetadata/2007-06/FederationMetadata.xml",
    },
    function (profile, done) {
      return done(null, {
        upn: profile["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"],
        // e.g. if you added a Group claim
        group: profile["http://schemas.xmlsoap.org/claims/Group"],
      });
    }
  )
);

module.exports = passport;

Express Application

  var passport = require('passport');
  var express = require('express');
  ... etc.

  var app = express();
  require('./config/passport.js');

  ... add the usual express pro-forma

  app.use(passport.initialize());
  app.use(passport.session());

  app.get('/login',
    passport.authenticate('saml', { failureRedirect: '/', failureFlash: true }),
    function(req, res) {
      res.redirect('https://acme_tools.com');
    }
  );
  app.post('/adfs/postResponse',
    passport.authenticate('saml', { failureRedirect: '/', failureFlash: true }),
    function(req, res) {
      res.redirect('https://acme_tools.com');
    }
  );
  app.get('/secure', validUser, routes.secure);

  function validUser(req, res, next) {
    if (!req.user) {
      res.redirect('https://acme_tools.com/login');
    }
    next();
  }

  var server = http.createServer(app);

Troubleshooting

ADFS 2016

If you are setting up an ADFS 2016 server, you might run into the following issue with the previous settings:

An error occurred during an attempt to read the federation metadata. Verify that the specified URL or host name is a valid federation metadata endpoint.

Verify your proxy server setting. For more information about how to verify you proxy sever setting, see the AD FS Troubleshooting Guide http://go.microsoft.com/fwlink/?LinkId=182180).
Error message: EntityDescriptor 'acme_tools_com'. ID0014: The value 'NameIDFormat' must be an absolute URI.

NameIDFormat Error Popup

If you remove the identifierFormat, it works as expected.

Clone this wiki locally