SAML SP for Meteor.JS

SAML v2 login support for existing MeteorJS password based accounts

Project Readme


SAML v2 login support for existing password based accounts


For OpenIDP, see the example app example-openidp and for a demo.

For OpenAM, see the example app openam-example.

Important Notes

  • This package is working but may have issues with various saml providers - it has only been tested and verified with OpenIDP and OpenAM.
  • Most SAML IDPs don't allow SPs with a localhost ( address. Unless you run your own IDP (eg via your own OpenAM instance) you might exprience issues.
  • The accounts-ui loggin buttons will not include saml providers, this may be implemented as a future enhancement, see below for how to build a custom login button.


Put SAML settings in eg server/lib/settings.js like so:

settings = {"saml":[{
    "issuer": "", //replace with url of your app
    "idpSLORedirectURL": "",
     "privateKeyFile": "certs/mykey.pem",  // path is relative to $METEOR-PROJECT/private
     "publicCertFile": "certs/mycert.pem",  // eg $METEOR-PROJECT/private/certs/mycert.pem
     "dynamicProfile": true // set to true if we want to create a user in Meteor.users dynamically if SAML assertion is valid
     "identifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", // Defaults to urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
     "localProfileMatchAttribute": "telephoneNumber" // CAUTION: this will be mapped to profile.<localProfileMatchAttribute> attribute in Mongo if identifierFormat (see above) differs from urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress,
     "attributesSAML": [telephoneNumber, sn, givenName, mail], // attrs from SAML attr statement, which will be used for local Meteor profile creation. Currently no real attribute mapping. If required use mapping on IdP side.


Meteor.settings = settings;

in some template

<a href="#" class="saml-login" data-provider="openam">OpenAM</a>

in helper function

  'click .saml-login' (event) {
    var provider ='data-provider');
    }, function(error, result) {
      //handle errors and result

and if SingleLogout is needed

'click .saml-login': function(event, template){
    var provider = $('provider');
	}, function(error, result){
		//handle errors and result

Setup SAML SP (Consumer)

  1. Create a Meteor project by meteor create sp and cd into it.
  2. Add steffo:meteor-accounts-saml
  3. Create server/lib/settings.js as described above. Since Meteor loads things in server/lib first, this ensures that your settings are respected even on Galaxy where you cannot use meteor --settings.
  4. Put your private key and your cert (not the IDP's one) into the "private" directory. Eg if your meteor project is at /Users/steffo/sp then place them in /Users/steffo/sp/private
  5. Check if you can receive SP metadata eg via curl http://localhost:3000/_saml/metadata/openam. Output should look like:
<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="" entityID="http://localhost:3000/">
  <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
          <ds:X509Certificate>MKA.... lot of funny chars ... gkqhkiG9w0BAQUFADATMREwDwYDVQQDEwgxMC4w
      <EncryptionMethod Algorithm=""/>
      <EncryptionMethod Algorithm=""/>
      <EncryptionMethod Algorithm=""/>
    <AssertionConsumerService index="1" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:3000/_saml/validate/openam"/>

OpenAM Setup

  1. I prefer using OpenAM realms. Set up a realm using a name that matches the one in the entry point URL of the settings.json file:<YOURREALM>/idp; we used zimt above.
  2. Save the SP metadata (obtained in Step 5 above) in a file sp-metadata.xml.
  3. Logon OpenSSO console as amadmin and select Common Tasks > Register Remote Service Provider
  4. Select the corresponding real and upload the metadata (alternatively, point OpenAM to the SP's metadata URL eg If all goes well the new SP shows up under Federation > Entity Providers


The <EncryptedAssertion> element represents an assertion in encrypted fashion, as defined by the XML Encryption Syntax and Processing specification XMLEnc. Encrypted assertions are intended as a confidentiality protection mechanism when the plain-text value passes through an intermediary.

The following schema fragment defines the <EncryptedAssertion> element:

<element name="EncryptedAssertion" type="saml:EncryptedElementType"/>

In case the SAML response contains an <EncryptedAssertion> element and the configuration key privateKey is set, the assertion get's decrypted and handled like it would be an unencrypted one.

OpenIDP setup


  • Introduction of IDP types (eg openam, auth0 etc) to support implementaion specific workarounds.
  • Support for different SAML Bindings
  • Check for better/alternative SAML profile. I have the impression that the SAML Web Browser SSO profile somewhat conflicts with Meteor's DDP/websocket approach. Eg when the browser issues an HTTP request, Meteor apps don't necessarily know from which user/session this request comes from (ja, we could use cookies but that's not the the Meteor-way).


Based Nat Strauser's Meteor/SAML package natestrauser:meteor-accounts-saml which is heavily derived from

Project Information