{"id":22281610,"url":"https://github.com/clever/saml2","last_synced_at":"2025-05-14T05:10:50.073Z","repository":{"id":14925740,"uuid":"17650054","full_name":"Clever/saml2","owner":"Clever","description":"Node module to abstract away the complexities of the SAML protocol behind an easy to use interface.","archived":false,"fork":false,"pushed_at":"2025-03-18T22:44:43.000Z","size":409,"stargazers_count":360,"open_issues_count":72,"forks_count":167,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-05-10T13:40:34.977Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Clever.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-12T00:23:44.000Z","updated_at":"2025-04-28T07:58:23.000Z","dependencies_parsed_at":"2024-09-24T02:43:55.770Z","dependency_job_id":"bd3253fa-34b1-426b-9ba2-bc7c17be4853","html_url":"https://github.com/Clever/saml2","commit_stats":{"total_commits":283,"total_committers":53,"mean_commits":5.339622641509434,"dds":0.7420494699646643,"last_synced_commit":"0f40b833f55ca227702f864eb17947dd5b78c4be"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clever%2Fsaml2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clever%2Fsaml2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clever%2Fsaml2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clever%2Fsaml2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Clever","download_url":"https://codeload.github.com/Clever/saml2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254076850,"owners_count":22010611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-03T16:19:48.218Z","updated_at":"2025-05-14T05:10:50.013Z","avatar_url":"https://github.com/Clever.png","language":"CoffeeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Maintenance Notice\n\nThis library is currently in maintenance mode. Until further notice, the primary directive is to handle bug reports and security issues with this library.\n\nAny library alternatives and suggestions can be filed under an issue.\n\n# SAML2-js\n\n[![CircleCI](https://circleci.com/gh/Clever/saml2/tree/master.svg?style=svg)](https://circleci.com/gh/Clever/saml2/tree/master)\n\n`saml2-js` is a node module that abstracts away the complexities of the SAML protocol behind an easy to use interface. It achieves this this by helping you implement a service provider for the SAML protocol. It currently does not implement the features to act as an identity provider.\n\n## Usage\n\nInstall with [npm](https://www.npmjs.com/).\n\n```bash\n  npm install saml2-js --save\n```\n\nInclude the SAML library.\n\n```javascript\n  var saml2 = require('saml2-js');\n```\n\n## Documentation\n\nThis library exports two constructors.\n\n- [`ServiceProvider`](#ServiceProvider) - Represents a service provider that relies on a trusted [`IdentityProvider`](#IdentityProvider) for authentication and authorization in the SAML flow.\n- [`IdentityProvider`](#IdentityProvider) - Represents an online service that authenticates users in the SAML flow.\n\n\u003ca name=\"note_options\" /\u003e\n\n**Note:**  Some options can be set on the [SP](#ServiceProvider), [IdP](#IdentityProvider), and/or on a per-method basis. For the options that are set in multiple places, they are overridden in the following order: per-method basis *overrides* [IdP](#IdentityProvider) which *overrides* [SP](#ServiceProvider).\n\n\u003ca name=\"ServiceProvider\" /\u003e\n\n### ServiceProvider(options)\nRepresents a service provider that relies on a trusted [`IdentityProvider`](#IdentityProvider) for authentication and authorization in the SAML flow.\n\n#### Options\nAn object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n\n- `entity_id` - **Required** - Unique identifier for the service provider, often the URL of the metadata file.\n- `private_key` - **Required** - (PEM format string) - Private key for the service provider.\n- `certificate` - **Required** - (PEM format string) - Certificate for the service provider.\n- `assert_endpoint` - **Required** - URL of service provider assert endpoint.\n- `alt_private_keys` - (Array of PEM format strings) - Additional private keys to use when attempting to decrypt responses. Useful for adding backward-compatibility for old certificates after a rollover.\n- `alt_certs` - (Array of PEM format strings) - Additional certificates to expose in the SAML metadata. Useful for staging new certificates for rollovers.\n- `audience` - (String or RegExp) — If set, at least one of the `\u003cAudience\u003e` values within the `\u003cAudienceRestriction\u003e` condition of a SAML authentication response must match. Defaults to `entity_id`.\n- `notbefore_skew` - (Number) – To account for clock skew between IdP and SP, accept responses with a NotBefore condition ahead of the current time (according to our clock) by this number of seconds. Defaults to 1. Set it to 0 for optimum security but no tolerance for clock skew.\n- `force_authn` - (Boolean) - If true, forces re-authentication of users even if the user has a SSO session with the [IdP](#IdentityProvider).  This can also be configured on the [IdP](#IdentityProvider) or on a per-method basis.\n- `auth_context` - Specifies `AuthnContextClassRef`.  This can also be configured on a per-method basis.\n- `nameid_format` - Format for Name ID.  This can also be configured on a per-method basis.\n- `sign_get_request` - (Boolean) - If true, signs the request.  This can also be configured on the [IdP](#IdentityProvider) or on a per-method basis.\n- `allow_unencrypted_assertion` - (Boolean) - If true, allows unencrypted assertions.  This can also be configured on the [IdP](#IdentityProvider) or on a per-method basis.\n\n#### Returns the following functions\n- [`create_login_request_url(IdP, options, cb)`](#create_login_request_url) - Get a URL to initiate a login.\n- [`redirect_assert(IdP, options, cb)`](#redirect_assert) - Gets a SAML response object if the login attempt is valid, used for redirect binding.\n- [`post_assert(IdP, options, cb)`](#post_assert) - Gets a SAML response object if the login attempt is valid, used for post binding.\n- [`create_logout_request_url(IdP, options, cb)`](#create_logout_request_url)- Creates a SAML Request URL to initiate a user logout.\n- [`create_logout_response_url(IdP, options, cb)`](#create_logout_response_url) - Creates a SAML Response URL to confirm a successful [IdP](#IdentityProvider) initiated logout.\n- [`create_metadata()`](#create_metadata) - Returns the XML metadata used during the initial SAML configuration.\n\n#### Example\n```javascript\n\n  var sp_options = {\n    entity_id: \"https://sp.example.com/metadata.xml\",\n    private_key: fs.readFileSync(\"key-file.pem\").toString(),\n    certificate: fs.readFileSync(\"cert-file.crt\").toString(),\n    assert_endpoint: \"https://sp.example.com/assert\",\n    force_authn: true,\n    auth_context: { comparison: \"exact\", class_refs: [\"urn:oasis:names:tc:SAML:1.0:am:password\"] },\n    nameid_format: \"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\",\n    sign_get_request: false,\n    allow_unencrypted_assertion: true\n  }\n\n  // Call service provider constructor with options\n  var sp = new saml2.ServiceProvider(sp_options);\n\n  // Example use of service provider.\n  // Call metadata to get XML metatadata used in configuration.\n  var metadata = sp.create_metadata();\n\n```\n\n#### Service provider function definitions\n\n\u003ca name=\"create_login_request_url\" /\u003e\n\n##### create_login_request_url(IdP, options, cb)\nGet a URL to initiate a login.\n\nTakes the following arguments:\n- `IdP` - [IdP](#IdentityProvider)\n- `options` - An object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n  - `relay_state` - SAML relay state.\n  - `auth_context` - Specifies `AuthnContextClassRef`.  This can also be configured on the [SP](#ServiceProvider).\n  - `nameid_format` - Format for Name ID.  This can also be configured on the [SP](#ServiceProvider).\n  - `force_authn`- (Boolean) - If true, forces re-authentication of users even if the user has a SSO session with the [IdP](#IdentityProvider).  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  - `sign_get_request` - (Boolean) - If true, signs the request.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n- `cb(error, login_url, request_id)` - Callback called with the login URL and ID of the request.\n\n\n\u003ca name=\"redirect_assert\" /\u003e\n\n##### redirect_assert(IdP, options, cb)\nGets a SAML response object if the login attempt is valid, used for redirect binding.\n\nTakes the following arguments:\n- `IdP` - [IdP](#IdentityProvider)\n- `options` - An object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n  - `request_body` - (Object) - An object containing the parsed query string parameters.  This object should contain the value for either a `SAMLResponse` or `SAMLRequest`.\n  - `allow_unencrypted_assertion` - (Boolean) - If true, allows unencrypted assertions.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  - `require_session_index` - (Boolean) - If false, allow the assertion to be valid without a `SessionIndex` attribute on the `AuthnStatement` node.\n- `cb(error, response)` - Callback called with the [request response](#assert_response).\n\n\u003ca name=\"assert_response\" /\u003e\nExample of the SAML assert response returned:\n\n  ```javascript\n  { response_header:\n     { id: '_abc-1',\n       destination: 'https://sp.example.com/assert',\n       in_response_to: '_abc-2' },\n    type: 'authn_response',\n    user:\n     { name_id: 'nameid',\n       session_index: '_abc-3',\n       attributes:\n        { 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname': [ 'Test' ] } } }\n  ```\n\n\u003ca name=\"post_assert\" /\u003e\n\n##### post_assert(IdP, options, cb)\nGets a SAML response object if the login attempt is valid, used for post binding.\n\nTakes the following arguments:\n- `IdP` - [IdP](#IdentityProvider)\n- `options` - An object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n  - `request_body` - (Object) - An object containing the parsed query string parameters.  This object should contain the value for either a `SAMLResponse` or `SAMLRequest`.\n  - `allow_unencrypted_assertion` - (Boolean) - If true, allows unencrypted assertions.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  - `require_session_index` - (Boolean) - If false, allow the assertion to be valid without a `SessionIndex` attribute on the `AuthnStatement` node.\n  - `audience` - (String or RegExp) — If set, at least one of the `\u003cAudience\u003e` values within the `\u003cAudienceRestriction\u003e` condition of a SAML authentication response must match. Defaults to `entity_id`.\n  - `notbefore_skew` - (Number) – To account for clock skew between IdP and SP, accept responses with a NotBefore condition ahead of the current time (according to our clock) by this number of seconds. Defaults to 1. Set it to 0 for optimum security but no tolerance for clock skew.\n- `cb(error, response)` - Callback called with the [request response](#assert_response).\n\n\n\u003ca name=\"create_logout_request_url\" /\u003e\n\n##### create_logout_request_url(IdP, options, cb)\nCreates a SAML Request URL to initiate a user logout.\n\nTakes the following arguments:\n- `IdP` - [IdP](#IdentityProvider).  Note: Can pass `sso_logout_url` instead of IdP.\n- `options` - An object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n  + `name_id` - Format for Name ID.  This can also be configured on a per-method basis.\n  + `session_index` - Session index to use for creating logout request.\n  + `allow_unencrypted_assertion` - (Boolean) - If true, allows unencrypted assertions.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  + `sign_get_request` - (Boolean) - If true, signs the request.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  + `relay_state` - SAML relay state.\n- `cb(error, request_url)` - Callback called with the logout request url.\n\n\n\u003ca name=\"create_logout_response_url\" /\u003e\n\n##### create_logout_response_url(IdP, options, cb)\nCreates a SAML Response URL to confirm a successful [IdP](#IdentityProvider) initiated logout.\n\nTakes the following arguments:\n- `IdP` - [IdP](#IdentityProvider).  Note: Can pass `sso_logout_url` instead of IdP.\n- `options` - An object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n  + `in_response_to` - The ID of the request that this is in response to. Should be checked against any sent request IDs.\n  + `sign_get_request` - (Boolean) - If true, signs the request.  This can also be configured on the [IdP](#IdentityProvider) or [SP](#ServiceProvider).\n  + `relay_state` - SAML relay state.\n- `cb(error, response_url)` - Callback called with the logout response url.\n\n\u003ca name=\"create_metadata\" /\u003e\n\n##### create_metadata()\nReturns the XML metadata used during the initial SAML configuration.\n\n\u003ca name=\"IdentityProvider\" /\u003e\n\n### IdentityProvider(options)\nRepresents an online service that authenticates users in the SAML flow.\n\nReturns no functions, exists solely to be passed to an [SP](#ServiceProvider) function.\n\n#### Options\nAn object that can contain the below options.  All options are strings, unless specified otherwise.  See [note](#note_options) for more information on options.\n\n- `sso_login_url` - **Required** - Login url to use during a login request.\n- `sso_logout_url` - **Required** - Logout url to use during a logout request.\n- `certificates` - **Required** - (PEM format string or array of PEM format strings) - Certificate or certificates (array of certificate) for the identity provider.\n- `force_authn` - (Boolean) - If true, forces re-authentication of users even if the user has a SSO session with the [IdP](#IdentityProvider).  This can also be configured on the [SP](#ServiceProvider) or on a per-method basis.\n- `sign_get_request` - (Boolean) - If true, signs the request.  This can also be configured on the [[SP](#ServiceProvider) or on a per-method basis.\n- `allow_unencrypted_assertion` - (Boolean) - If true, allows unencrypted assertions.  This can also be configured on the [SP](#ServiceProvider) or on a per-method basis.\n\n#### Example\n```javascript\n\n  // Initialize options object\n  var idp_options = {\n    sso_login_url: \"https://idp.example.com/login\",\n    sso_logout_url: \"https://idp.example.com/logout\",\n    certificates: [fs.readFileSync(\"cert-file1.crt\").toString(), fs.readFileSync(\"cert-file2.crt\").toString()],\n    force_authn: true,\n    sign_get_request: false,\n    allow_unencrypted_assertion: false\n  };\n\n  // Call identity provider constructor with options\n  var idp = new saml2.IdentityProvider(idp_options);\n\n  // Example usage of identity provider.\n  // Pass identity provider into a service provider function with options and a callback.\n  sp.post_assert(idp, {}, callback);\n\n```\n\n\n## Example: Express implementation\n\nLibrary users will need to implement a set of URL endpoints, here is an example of [express](http://expressjs.com/) endpoints.\n\n```javascript\nvar saml2 = require('saml2-js');\nvar fs = require('fs');\nvar express = require('express');\nvar app = express();\n// If you're using express \u003c4.0:\n// var bodyParser = require('body-parser');\n// app.use(bodyParser.urlencoded({\n//   extended: true\n// }));\napp.use(express.urlencoded());\n\n// Create service provider\nvar sp_options = {\n  entity_id: \"https://sp.example.com/metadata.xml\",\n  private_key: fs.readFileSync(\"key-file.pem\").toString(),\n  certificate: fs.readFileSync(\"cert-file.crt\").toString(),\n  assert_endpoint: \"https://sp.example.com/assert\"\n};\nvar sp = new saml2.ServiceProvider(sp_options);\n\n// Create identity provider\nvar idp_options = {\n  sso_login_url: \"https://idp.example.com/login\",\n  sso_logout_url: \"https://idp.example.com/logout\",\n  certificates: [fs.readFileSync(\"cert-file1.crt\").toString(), fs.readFileSync(\"cert-file2.crt\").toString()]\n};\nvar idp = new saml2.IdentityProvider(idp_options);\n\n// ------ Define express endpoints ------\n\n// Endpoint to retrieve metadata\napp.get(\"/metadata.xml\", function(req, res) {\n  res.type('application/xml');\n  res.send(sp.create_metadata());\n});\n\n// Starting point for login\napp.get(\"/login\", function(req, res) {\n  sp.create_login_request_url(idp, {}, function(err, login_url, request_id) {\n    if (err != null)\n      return res.send(500);\n    res.redirect(login_url);\n  });\n});\n\n// Variables used in login/logout process\nvar name_id, session_index;\n\n// Assert endpoint for when login completes\napp.post(\"/assert\", function(req, res) {\n  var options = {request_body: req.body};\n  sp.post_assert(idp, options, function(err, saml_response) {\n    if (err != null)\n      return res.send(500);\n\n    // Save name_id and session_index for logout\n    // Note:  In practice these should be saved in the user session, not globally.\n    name_id = saml_response.user.name_id;\n    session_index = saml_response.user.session_index;\n\n    res.send(\"Hello #{name_id}! session_index: #{session_index}.\");\n  });\n});\n\n// Starting point for logout\napp.get(\"/logout\", function(req, res) {\n  var options = {\n    name_id: name_id,\n    session_index: session_index\n  };\n\n  sp.create_logout_request_url(idp, options, function(err, logout_url) {\n    if (err != null)\n      return res.send(500);\n    res.redirect(logout_url);\n  });\n});\n\napp.listen(3000);\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclever%2Fsaml2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclever%2Fsaml2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclever%2Fsaml2/lists"}