Git Product home page Git Product logo

passport-saml-metadata's Introduction

passport-saml-metadata

Build Status Download Status

Utilities for reading configuration from SAML 2.0 Metadata XML files, such as those generated by Active Directory Federation Services (ADFS).

Installation

npm install passport-saml-metadata

Usage Example

const os = require('os');
const fileCache = require('file-system-cache').default;
const { fetch, toPassportConfig, claimsToCamelCase } = require('passport-saml-metadata');
const SamlStrategy = require('passport-wsfed-saml2').Strategy;

const backupStore = fileCache({ basePath: os.tmpdir() });
const url = 'https://adfs.company.com/federationMetadata/2007-06/FederationMetadata.xml';

fetch({ url, backupStore })
  .then((reader) => {
    const config = toPassportConfig(reader);
    config.realm = 'urn:nodejs:passport-saml-metadata-example-app';
    config.protocol = 'saml2';

    passport.use('saml', new SamlStrategy(config, function(profile, done) {
      profile = claimsToCamelCase(profile, reader.claimSchema);
      done(null, profile);
    }));

    passport.serializeUser((user, done) => {
      done(null, user);
    });

    passport.deserializeUser((user, done) => {
      done(null, user);
    });
  });

See compwright/passport-saml-example for a complete reference implementation.

API

fetch(config = {})

When called, it will attempt to load the metadata XML from the supplied URL. If it fails due to a request timeout or other error, it will attempt to load from the backupStore cache.

Config:

  • client Axios instance
  • url (required) Metadata XML file URL
  • timeout Time to wait before falling back to the backupStore, in ms (default = 2000)
  • backupStore Any persistent cache adapter object with get(key) and set(key, value) methods (default = new Map())

Additional configuration options supported: https://github.com/axios/axios#request-config

Returns a promise which resolves, if successful, to an instance of MetadataReader.

toPassportConfig(reader, options = { multipleCerts: false })

Transforms metadata extracts for use in Passport strategy configuration. The following strategies are currently supported:

Config:

  • multipleCerts (boolean): causes the full array of signing certificates to be passed to the passport config instead of assuming the last certificate is the most recent one. Note: this option is not compatible with passport-wsfed-saml2.

claimsToCamelCase(claims, claimSchema)

Translates the claim identifier URLs to human-friendly camelCase versions. Useful in Passport verifier functions.

claimSchema should be an object of the following format, such as from MetadataReader.claimSchema():

{
  [claimURL]: {
    name: claimUrl,
    camelCase: 'claimIdentifierInCamelCase',
    description: 'Some description'
  },
  ...
}

Example:

function verifier(profile, done) {
  profile = passportSamlMetadata.claimsToCamelCase(profile, reader.claimSchema);
  done(null, profile);
}

new MetadataReader(metadataXml, options)

Options parameter details:

  • authnRequestBinding: if set to HTTP-POST, will attempt to load identityProviderUrl/logoutUrl via HTTP-POST binding in metadata, otherwise defaults to HTTP-Redirect
  • throwExceptions: if set to true, will throw upon exception

Parses metadata XML and extracts the following properties:

metadata(app)(config = {})

Returns a function which sets up an Express application route to generate the metadata XML file for your application at /FederationMetadata/2007-06/FederationMetadata.xml. ADFS servers may import the resulting file to set up the relying party trust.

Config:

  • issuer (required) The unique application identifier, used to name the relying party trust; may be a URN or URL
  • callbackUrl (required) The absolute URL to redirect back to with the SAML assertion after logging in, usually https://hostname[:port]/login/callback
  • logoutCallbackUrl The absolute URL to redirect back to with the SAML assertion after logging out, usually https://hostname[:port]/logout

See compwright/passport-saml-example for a usage example.

passport-saml-metadata's People

Contributors

compwright avatar danroot avatar esacteksab avatar esvinson avatar garryone avatar greenkeeper[bot] avatar leachim2k avatar oliverlockwood avatar rafaelmaeuer avatar tigerc10 avatar tsuesun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

passport-saml-metadata's Issues

pem_read_bio_pubkey failed, started sometime after 1.4 series

This morning I deployed an application that had been using passport-saml with passport-saml-metadata successfully. On deployment I began to see:

pem_read_bio_pubkey failed

The stack shows this is ultimately happening in SAML.validateSignatureForCert.

On a hunch, I downgraded passport-saml-metadata to 1.4.x, and everything worked fine with no other changes. I am pinning to that series for now.

The idP is running Shibboleth.

Let me know if there is anything else that would be particularly helpful that I might be able to supply.

Adding option for adding a CA

For use in a corperate environment the option for a custom CA should be added.

At the Moment the Error "UNABLE_TO_VERIFY_LEAF_SIGNATURE" appears.

An in-range update of core-js is breaking the build 🚨

The dependency core-js was updated from 2.6.1 to 2.6.2.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

core-js is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build passed (Details).
  • continuous-integration/travis-ci/pr: The Travis CI build could not complete due to an error (Details).

Release Notes for 2.6.2 - 2019.01.10
  • Fixed handling of $ in String#replace, #471
Commits

The new version differs by 4 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

A file extension must be provided when using the import keyword to resolve relative or absolute specifiers.

When trying to run a project using passport-saml-metadata I am getting the following error:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/usr/src/app/node_modules/lodash/camelCase'
imported from /usr/src/app/node_modules/passport-saml-metadata/dist/index.mjs
Did you mean to import lodash/camelCase.js?

It seems that based on docs all imports should include file extensions, which seems not to be the case unfortunately though:
https://nodejs.org/api/esm.html#mandatory-file-extensions

Could you please have a look at this and try to fix it?
Thank you very much.

Please expose `#query()` function on `MetadataReader` class - or at least, expose a function which retrieves the Entity ID

We have been happily using this library for a while. Thanks for sharing it with the community, and for keeping it maintained.

We support passport-saml's MultiSamlStrategy, using the EntityID in the SAML Metadata as a distinguishing tool between different IdPs.

In order to get hold of the Entity ID, we have this little block of code:

    private static extractEntityId(metadataReader: MetadataReader): string {

        let entityId: string;

        try {
            entityId = metadataReader.query('//md:EntityDescriptor/@entityID')[0].nodeValue;
        }
        catch (err) {
            // N.B. the library debug logs in error cases
            entityId = metadataReader.query('//EntityDescriptor/@entityID/')[0].nodeValue;
        }

        return entityId;
    }

The catch clause may or may not be overly defensive, but that's not the point here 😄

I tried upgrading to use the newly released version 3.0.0 of this library - as part of upgrading to use the new co-ordinates of passport-saml - but unfortunately I was unable to succeed, because the # prefix that was added to the query() function makes it inaccessible.

Would you be willing to consider exposing this query function again? Or if not, at least to add a new wrapper function which uses it to retrieves the '//md:EntityDescriptor/@entityID' ?

I would be happy to contribute a PR, but I thought I'd first seek your approval in principle and guidance over which path you'd prefer.

Update Dependencies

Trying to use this and my webpack/babel build is complaining about an illegal assignment.

ERROR in server.js from UglifyJs
    Invalid assignment [./node_modules/passport-saml-metadata/node_modules/node-forge/js/util.js:1885,0]

--> define = function(ids, factory) {

This is coming from an outdated digitalbazaar/forge#353, which is in turn coming from an outdated auth0/node-xml-encryption#28, which is coming from an outdated node-saml/passport-saml#222.

Long term, it may be best to declare passport-saml as a peerDependency instead. But for now, better to just update.

reader.claimSchema dosn't find any claims in my metadata.xml

Hi,
I am using your code for parsing my ADFS metadata.xml, my problem is that in the metadata.xml link ADFS generated for me there are no claims under IDPSSODescriptor section like yours... i configured the claims in ADFS UI and i can see them in the profile object (after the user authenticated), but not in my metadata.xml.
What am i missing?
ADFS does not put the claim in the metadata and i need to add them manually?
My metadata.xml (ADFS generate me this xml automatically and give me a link to it):

<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>
MIIC8DCCAdigAwIBAgIQEqXVk9...
</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/12345.../saml2"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/12345.../saml2"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.microsoftonline.com/12345.../saml2"/>
</IDPSSODescriptor>

Your metadata:

<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <KeyDescriptor>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                <X509Data>
                    <X509Certificate>MIIC4jCCAcqgAwIBAgIQXYcAQ3jZkL...</X509Certificate>
                </X509Data>
            </KeyInfo>
        </KeyDescriptor>
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://adfs.server.url/adfs/ls/Redirect" />
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://adfs.server.url/adfs/ls/POST" />
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://adfs.server.url/adfs/ls/Artifact" />
        <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://adfs.server.url/adfs/ls/Redirect" />
        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://adfs.server.url/adfs/ls/POST" />
        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://adfs.server.url/adfs/ls/Artifact" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="E-Mail Address" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Given Name" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Name" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="UPN" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/claims/CommonName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Common Name" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/claims/EmailAddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="AD FS 1.x E-Mail Address" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/claims/Group" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Group" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/claims/UPN" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="AD FS 1.x UPN" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Role" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Surname" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="PPID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Name ID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Authentication time stamp" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Authentication method" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Deny only group SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Deny only primary SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Deny only primary group SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Group SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Primary group SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Primary SID" />
        <Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Windows account name" />
</IDPSSODescriptor>

As you can see no <Attribute xmlns..> in mine...
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.