Giter VIP home page Giter VIP logo

samlify's Introduction

samlify ·

Build Status npm version NPM Coverage Status

Highly configuarable Node.js SAML 2.0 library for Single Sign On

Welcome PRs

Welcome all PRs for maintaining this project, or provide a link to the repositories especially for use cases alongside with different frameworks.

Installation

Multiple schema validators are currently supported by our system, with couple validator modules available and the option to create custom ones. It is essential to utilize the setSchemaValidator function at the outset to avoid errors.

import * as samlify from 'samlify';
import * as validator from '@authenio/samlify-xsd-schema-validator';
// import * as validator from '@authenio/samlify-validate-with-xmllint';
// import * as validator from '@authenio/samlify-node-xmllint';

samlify.setSchemaValidator(validator);

Now you can create your own schema validator and even suppress it but you have to take the risk for accepting malicious response.

samlify.setSchemaValidator({
  validate: (response: string) => {
    /* implment your own or always returns a resolved promise to skip */
    return Promise.resolve('skipped');
  }
});

For those using Windows, windows-build-tools should be installed globally before installing samlify if you are using libxml validator.

yarn global add windows-build-tools

Development

This project is now developed using TypeScript, also support Yarn which is a new package manager.

yarn global add typescript
yarn

Get Started

const saml = require('samlify');

See full documentation here

Example

react-samlify SP example powered by React, TypeScript and Webpack

Talks

An introduction to Single Sign On

License

MIT

Copyright

Copyright (C) 2016-present Tony Ngan, released under the MIT License.

samlify's People

Contributors

alexeysafronov avatar angelmsger avatar ayzagen avatar blackentropy avatar bsshoham avatar dependabot[bot] avatar duane-talentsonar avatar gitter-badger avatar gtothesquare avatar kiejo avatar killalau avatar kingbin avatar larspederamlie avatar laverya avatar mastermatt avatar mitakuye avatar nflaig avatar peterwillis avatar puneetmakkar avatar raymondsze avatar rossjs avatar sambego avatar sebakerckhof avatar snyk-bot avatar stjeffrey avatar tngan avatar williamli avatar wujjpp avatar wwindcloud avatar yelexin avatar

Stargazers

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

Watchers

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

samlify's Issues

Roadmap to 2.0.0-beta

Current v1.4.1 will be no longer support after v2.0 is released.

------- 2.0.0-beta -------

General

  • Revamp unit testing (ava)
  • Test coverage (nyc) and coverall report.
  • Fix travis trigger
  • Gitbook removal (move to docsify)

Issues

  • #13 Code revamping - modify api for entity constructor
  • #35 Feature - order in xml parser
  • #42 Code revamping - stringify file
  • #43 Code revamping - callback style
  • #45 Code revamping - general
  • #54 Document - time verification
  • #55 Enhancement - recipient should use acl
  • #56 Enhancement - attribute customization

Bug fixes / Others

  • Missing base64 encode in unencrypted response 9a24665
  • Fix unstable replacement of encrypt assertion 61c5bb8
  • Security fix for ejs (one of the dependencies of xml-encryption) f3a968

Issue with initial run

I'm having an issue getting v1.2.6 to run on my system, and was hoping the error was familiar enough to allow an easy suggestion. Here are the steps I took:

  1. Cloned the repo
  2. Ran npm install in the main directory, then ran that command again in examples/idp/, examples/sp1/, and examples/sp2/
  3. Ran node app.js for each of the 3 folders above
  4. Successfully logged into http://localhost:3001, then clicked Sign in application 1 (:4002)
  5. Received error:
Error: Undefined assertion or invalid syntax
    at Object.decryptAssertion (/Users/givemesnacks/repo/express-saml2/lib/SamlLib.js:509:52)
    at Entity.abstractBindingParser (/Users/givemesnacks/repo/express-saml2/lib/Entity.js:202:21)
    at Entity.parseLoginResponse (/Users/givemesnacks/repo/express-saml2/lib/ServiceProvider.js:80:21)
    at /Users/givemesnacks/repo/express-saml2/examples/sp1/routes/sso.js:100:9
    at Layer.handle [as handle_request] (/Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/route.js:131:13)
    at Route.dispatch (/Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/layer.js:95:5)
    at /Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/index.js:277:22
    at param (/Users/givemesnacks/repo/express-saml2/examples/sp1/node_modules/express/lib/router/index.js:349:14)

I am running macOS 10.12.1 and Node v7.2.1 (I also tried Node v5.12.0 but received the same result). Thanks @tngan for any help you can provide!

API changes

There are three types of constructor now, I do think it's a good idea to combine those three overloading into one single constructor, include the metadata file path in the object instead of an argument. e.g.

var IdP = new IdentityProvider({
      privateKeyFile: './privateKey.pem',
      privateKeyFilePass: 'myPassword',
      metadata: './metadata_idp.xml'
});

Remarks: According to the semantic versioning 2, it changes the API and not plan to be backward compatibility, that's why it's bumped to v2.0.

Rewrite the module in ES6 syntax

Use BabelJS as JavaScript compiler to maintain its compatibility and Gulp is added to automate the build process, so keep updating the branch es6.

Guidance on certificate

I've been successful at running the samples and I'm trying to setup my own identity provider in node.js/express/express-saml2 and I'm testing it against a locally run instance of gitlab community. Trying naively, it almost works as from gitlab I can go to my identity provider, login and post the response. But then gitlab reply with:

Could not authenticate you from SAML because "Found an unexpected number of signature element. saml response rejected".

So most likely I'm doing something wrong but not sure what.

One thing that I could not find is a clear explanation of all the certificates and keys. It does not say what they are, how to generate them properly, if they are required. It would be nice to have a little bit of guidance here.

For example are the X509Certificate in the metadata_idp1.xml file related to the key we can find in key/idp?

Not working example sp2

Hi!
When trying to log in with es2-IdP to sp2, get this error:
image
With SP1 everything is good.

API for adding attributes in IdP module

Currently, we don't have API to add attributes to the default login response template. If developers want to add attributes in the login response, they need to use their own custom template.

  • Add API code
  • Add documentation
  • Add unit tests

Add wantMessageSigned into the setting of service provider

Following the standard, three conditions will be added to make sure the response must be signed.

  • wantMessageSigned is true + wantAssertionSigned is true
  • wantAssertionSigned is true (if false, entire message is signed)

default wantMessageSigned could be false

Customize order of xml nodes in metadata

As discussed in #32

Example:

const sp = ServiceProvider({
   // ...
   elementsOrder: ['KeyDescriptor', 'SingleLogoutService', 'NameIDFormat', 'AssertionConsumerService', 'AttributeConsumingService']
});

We can also provide some helpers, put sample order list in urn.js.

module.exports.elementsOrder: {
  onelogin: [/*...*/],
  shibboleth: [/*...*/]
}

Getting undefined on line 148 on file SPmetadata.js

Hi when i define my sp like this:

var spSetting = {
    entityID:'https://tecnologo.edu.uy/',
    privateKeyFile: './ANCAA.pem',
    privateKeyFilePass: 'prueba.0',
    authnRequestsSigned: true,
    encryptCertFile: './ANCAA.pem',
    signingCertFile: './Agesic-Coesys-Testing.cer',
    assertionConsumerService: [{
        Location: 'https://tecnologo.edu.uy/acs',
        Binding: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
    }],
    singleLogoutService:[{
        Location: 'https://tecnologo.edu.uy/slo'
    }],
};

im getting my assertionconsumerservice undefined, i think is because i think is because the line 148 returns false.

Feature request - allow specifying cer/pem/xml strings instead of files.

Some systems may want to store key & cer files in a database instead of on disk.
It would be useful if we could create IDPs/SPs with parameters like:
signingCert \ encryptCertFile \ privateKey \ encPrivateKey
instead of only
signingCertFile \ encryptCertFile \ privateKeyFile \ encPrivateKeyFile

Same thing for XML. Now you have to option to pass a file path string, or a config object. It would be great if you could also pass a raw xml string.

verifyTime is not used nor documented

Hello,

I thought this lib would check the notBefore and notOnOrAfter fields. There's a function called verifyTime that does this. Though this function is never used anywhere. Neither is there documentation about how to use it yourself.

I have done the following (which seems to work):

// simplified example
sp.parseLoginResponse(idp, 'post', req, parseResult => {
    const {conditions} = parseResult.extract;
    const notBefore = conditions.notbefore;
    const notOnOrAfter = conditions.notonorafter;
    const validTimeframe = sp.verifyTime(notBefore, notOnOrAfter);

    if (!validTimeframe) {
      console.warn(`SAML message has expired. notBefore: ${notBefore} notOnOrAfter: ${notOnOrAfter}`);
      res.sendStatus(500);
    } else {
      res.send(parseResult.extract.nameid);
    }
  });

Roadmap of v2.0-alpha pre-release

Current v1.2.5 will be no longer support after v2.0 is released.

------- 2.0.0-alpha -------

  • Support Yarn package manager (development)
  • Support and run tests in Node v6
  • Rewrite and refactor the module using TypeScript v2.0
    • Basic configuration (tslint, definitions)
    • Rewrite scripts under lib folder
      • Entity.js
      • SamlLib.js
      • Utility.js
      • urn.js
      • IdPMetadata.js
      • Metadata.js
      • RedirectBinding.js
      • ServiceProvider.js
      • IdentityProvider.js
      • PostBinding.js
      • SPMetadata.js
      • index.js
  • API breaking change #13
  • Passing test examples
  • Passing test cases

Follow general callback style

Although not really a requirement, it's somewhat an unwritten rule for callback signatures to follow (error, result). This makes it easy to use them with flow-control libraries or to transform them into promises with libraries like promisify.

There are several callbacks in this library which do not follow this style, like:
https://github.com/tngan/express-saml2/blob/f5c19bdd3d12d4a6c818dc87eef4e3b48c155897/lib/RedirectBinding.js#L74

Even if they can't return an error it helps in above mentioned aspects to return them as (null, result)

Invalid signature after decrypting SamlAssertion

Sorry, me again. :) But this time I don't have a suggested solution. :-/

I receive an encrypted SamlResponse, that SamlTool validates as OK, given the IdP certificate, and my private key.
However, it does not validate the decrypted file.

When SamTool decrypts the file, I get a slightly different result, then when I decrypt with express-saml2.

The express-saml2 stops with the error message:

Error: invalid signature: for uri #s22bedd198efd004dfff0b7aaf262d7144a81737be calculated digest is bWi39A0An6TWdnxr5FJJNZnkteg= but the xml to validate supplies digest rrW6cELtwOggZggY9ylh6EaHoDg=

I have tried to manually update the xml-cert to 0.9.0 (express-saml2 package.json specifies 0.8.5).

Confused about idp1 vs idp2..?

I'm certainly not an expert in saml, but I'm trying to understand your full example and I'm confused why there's a different idp1 vs idp2? Those instances are both set to the same configuration, why are both required and what might the actual difference be in how they're used.. Thanks!

Support encrypted assertion in SAML Response

A new API for encrypt/decrypt assertion in SAML Response will be included in v1.1.

// Prototyping
SamlLib.encryptAssertion(idp,sp,response,function(res) { ... }); // encryption
SamlLib.decryptAssertion(sp,idp,response,function(res) { ... }); // decryption

The flow is typical signature-then-encrypt in IdP and decrypt-then-verify in SP. The following encryption algorithms are included:

// In urn.js
encryption: {
        // Data encryption
        data: {
            AES_128: 'http://www.w3.org/2001/04/xmlenc#aes128-cbc',
            AES_256: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
            TRI_DEC: 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'
        },
        // Key encryption
        key: {
            RSA_OAEP_MGF1P: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
            RSA_1_5: 'http://www.w3.org/2001/04/xmlenc#rsa-1_5'
        }
}

Developers can choose the algorithms when they configure the entity.

// Checkout the branch v1.1 later on, the following code is just for sample
var saml = require('express-saml2');
var encAlg = saml.urn.algorithms.encryption;
var sp = saml.ServiceProvider({
        // ...
        isAssertionEncrypted: true, // set flag to encrypt asserion
        dataEncryptionAlgorithm: encAlg.data.AES_256, // default value
        keyEncryptionAlgorithm: encAlg.key.RSA_1_5 // default value
});

A sample SAML response with signature and encryption

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="_c6fd6427e8c5f8e8d1ff3cc472f95ce346069a91e6">
  <saml:Issuer>https://idp.example.com/metadata</saml:Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </samlp:Status>
  <saml:EncryptedAssertion><xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
  <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
  <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
    <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5">
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    </e:EncryptionMethod>
    <KeyInfo>
      <X509Data><X509Certificate>MIIDozC...</X509Certificate></X509Data>
    </KeyInfo>
    <e:CipherData>
      <e:CipherValue>gvOB36e...</e:CipherValue>
    </e:CipherData>
  </e:EncryptedKey>
</KeyInfo>
  <xenc:CipherData>
    <xenc:CipherValue>31LjNeztL...</xenc:CipherValue>
  </xenc:CipherData>
</xenc:EncryptedData></saml:EncryptedAssertion>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>upUaQ....</DigestValue></Reference></SignedInfo><SignatureValue>T3eM5Sx...</SignatureValue></Signature></samlp:Response>

Customization of AttributeStatement in template

Even though a callback function is exposed, allowing users to customize their own template and dynamically fill in during runtime, we could also provide a better way to handle the attribute mapping.

https://github.com/tngan/express-saml2/blob/783847d786391c6d0117574d4ee04c893eee6c20/lib/PostBinding.js#L111-L112

Proposal

When the entity is being constructed, make the customized template property more generic.

loginResponseTemplate: {
  context: "<..{AttributeStatement}.>",
  attributes: [{
    name: "uid",
    valueTag: "user.email",
    nameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
    valueXsiType: "xs:string"
  }]
}

Then the AttributeStatement will be replaced and the template becomes,

<saml:AttributeStatement>
  <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
    <saml:AttributeValue xsi:type="xs:string">{attrUserEmail}</saml:AttributeValue></saml:Attribute>
</saml:AttributeStatement>

the tag attribute value is named as CAMEL(attributes.valueTag) with prefix attr, and before passing template for tag replacement here, it would go through the default tag replacement once.

Examples for well-known Entities

Apart from our own IdP implementation, examples will be included to show how to work with other 3rd party Identity Providers. You can see the list of IdP as follow:

  • Azure Active Directory
  • OneLogin
  • Okta (support started from v2)
  • Shibboleth
  • SimpleSAMLphp

Inbounded SAML (Examples using express-saml2's IdP)

  • Okta (In progress)
  • Gitlab #62

Rewriting idp and sp1 example with vue.js

Currently, the sample entities are using default express application, we are considering to revamp it using Vue or React, here is the discussion thread.

The design is to separate the frontend view and backend services and use API to control the state and intermediate redirections. Service Provider will allow dynamic configuration, in other words, users can customise which identity provider is being used to do authentication, and other preferences like signature & encrpytion algorithms, binding type, etc.

Service Provider

Frontend (driven by Vue)

  • Setup vue project with vue-cli
  • State management design (Auth, Preference)
  • API connector
  • Pages design (Login, SSO, Home)
  • Testings

API side

  • POST /login
  • GET /logout
  • POST /configure (configure according to preference)
  • GET /metadata (metadata distribution)
  • POST /acs (service endpoint)
  • GET /spinitsso/:binding (endpoint for initiate sign on from SP)
  • GET /slo (service logout endpoint for redirect binding)
  • POST /slo (service logout endpoint for post binding)

Identity Provider

Pending

Future

The examples (both IdP and SP) will eventually become a separate open source product and allow developers to configure and customise according to their preferences.

Getting help using the library

Sorry to use this space to ask for help - I couldn't find any other way to contact.
I've been given the task of adding SAML support to a static website (serverless JavaScript Angular app) and I'm trying to figure out if your library will do the job.
I downloaded the code and looked in the examples for places with require('express-saml2') as shown in the readme, but I can't find any. I've been going over the examples and I believe what I need is what is demonstrated in SP2 with the redirect option (because their SSO already uses the redirect to a login). Of course I'd have to customize the IdP metadata.
Will this lib work with a serverless app? Am I on the right track using SP2 /sso/router.post('/acs' ...)? Is there a bare-bones example of using the saml lib to authenticate a user and redirect to IdP's login?
TIA,
Mike

Code revamping discussion

Approved part for code revamping

  • Enhancement for import method of cert/key (#42)
  • Standardized callback style (#43)
  • Promisify some async processes
  • Review of name convention
  • Use tslint to do code linting and make git pre-push hook

Continuous improvement

  • New class for normalizing error and propagate to end users
  • Group function arguments as one single object if more than 3

NameIDFormat incorrectly replaced

In RedirectBinding.js, loginRequestRedirectURL() the replace for NameIDFormat is:

NameIDFormat: namespace.format[spSetting.logoutNameIDFormat] || namespace.format.emailAddress,

Is spSetting.logoutNameIDFormat the correct attribute?

Decrypt Assertion, mismatch?

I guess this is more of a question, than anything else. It might be a bug, the documentation might need some clarification, or I've just doen something wrong. :)

Service Provider settings (my side)

After an SP initiated AuthnRequest, I receive an Encrypted SamlResponse. It has been encrypted by the IdP using the my public key, which was included in my metadatafile. That is:

var spSetting = { ...
    privateKeyFile: './cert/private-key.pem',
    privateKeyFilePass: 'xxxx'
};
var sp = saml.ServiceProvider(spSetting);
sp.exportMetadata('./metadata/sso_metadata_sp.xml');

Identity Provider settings (other side)

In my case, I have to use the same private key, when decrypting the SamlResponse from the IdP.

The way I understand the docs, I need to specify:

 var idpSetting = {
    isAssertionEncrypted: true,
    encPrivateKeyFile:  './cert/private-key.pem',
    encPrivateKeyFilePass: 'xxxx'
};
var idp = saml.IdentityProvider(idpSetting, './metadata/idp-metadata.xml');

Decrypt

Now deep diving into SamlLib.js, decryptAssertion(type, here, from, entireXML, callback)

xmlenc.decrypt(encryptedData, {
   // use this entity's private to decrypt
   key: Utility.readPrivateKeyFromFile(hereSetting.encPrivateKeyFile, hereSetting.encPrivateKeyFilePass) 

The variable here.entitySetting contains SPs privateKeyFile, and from.entitySetting contains encPrivateKeyFile.
But we are reading the variable here.entitySetting.encPrivateKeyFile.

What is wrong?

There are several candidates for change, I guess.
Maybe the code should be using either from.entitySetting.encPrivateKeyFile?
Or here.entitySetting.privateKeyFile, and update the docs?
Or define encPrivateKeyFile in the spSetting?

sendLoginRequest creates invalid URL when SSO url contains a query

When a SSO url contains a query like Google's SSO Urls:

<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://accounts.google.com/o/saml2/idp?idpid=xxx"/>

This library generates an invalid url:

sp.sendLoginRequest(idp, 'redirect', redirectUrl => {
  console.log(redirectUrl); // => https://accounts.google.com/o/saml2/idp?idpid=xxx?SAMLRequest=zzz
})

Notice the two ? in the url

To get around this we wrote the code:

const baseUrl = idp.getSingleSignOnService('redirect');
const hasQuery = url.parse(baseUrl).query.length > 0;
sp.sendLoginRequest(idp, 'redirect', redirectUrl => {
  if (!hasQuery) return res.redirect(redirectUrl);
  const newRedirectUrl = replaceAt(redirectUrl, baseUrl.length, '&');
  return res.redirect(newRedirectUrl);
});

But it would be great for this library to handle this corner case rather than hack around it in userland.

Thanks!

Expose request/response ID

On single page applications (e.g. if we want this: #46 ) it is common to do the single sign on in a pop-up window, so the user doesn't leave the SPA and the page doesn't refresh when the user is logged in.

The way this works is usually pretty hacky, but afraid this is the common way of doing this:

  1. Create a unique ID on the client
  2. Open a pop-up window requesting the login page, passing the unique ID (e.g. as a query variable) + have an interval checking if the pop-up is still open.
  3. The login page stores the unique ID together with the SAML request ID
  4. Normal SAML-authentication flow to the IDP and back.
  5. When the assertion consumer URL receives a login response. It matches the SAML response ID with the request ID and unique ID (saved in step 3) and adds the login response data.
  6. Close popup
  7. Client notifies the pop-up is closed
  8. Client asks the server to log in with the unique ID generated in step 1
  9. Server logs in the client and returns user info to the client

To make this flow possible we need sendLoginRequest and parseLoginResponse to return respectively the request ID and response ID.

Unless @tngan you know a better way to make the popup flow work.

[DRY] Code enhancement

When I was young a little dev, I create this module ...

Some old practices should be removed and we don't want to reinvent the wheel.

We will try hard to avoid API change at this stage until v2.0.

List of proposed features and modifications

  • Better and precise error messages
  • Log system
  • Workflow simplification
  • ES6 syntax

Roadmap to 2.0.0-release

Issues

  • #50 Expose request ID and response ID for SPA (Another API break)
  • #66 Fix typo
  • #67 Fix the NameIDFormat replacement in redirect binding
  • #68 Handling extra query parameters in binding location
  • #69 Generic replacement of tags

Documentation

  • Review (including #70)

Enhancements

  • #64 Add trigger for signing entired message
  • #63 Options in signature construction

Tests

  • Coverage (#84)

REMARKS: Examples will be separated into new repositories

v2.0.0-rc.1 is released and v1 is deprecated from now

v2.0.0-rc.2 is released

v2.0.0-rc.3 is released

v2.0.1-rc.3 is released

Onelogin - Parse logout response: parserType

Hi there, first of al tnx for the great lib and examples.

Now, I am having an issue trying to do logout, the problem seems to be this line:
https://github.com/tngan/express-saml2/blob/master/lib/Entity.js#L329

that value for parser type is causing this error to be thrown:
https://github.com/tngan/express-saml2/blob/master/lib/Entity.js#L164

because, the only key in requestQuery object is 'SAMLResponse', there is not 'LogoutResponse' key in the object. I don't know if this lib should be updated to handle that situation or if I am doing something wrong and that is why I am not getting 'LogoutResponse' key in the requestQuery object.

What do you think?

Confusion in recipient attribute

As discussed in #12

Depending on different implementations, and it's optional in documentation P.18-19 in doc.

A URI specifying the entity or location to which an attesting entity can present the assertion. For
example, this attribute might indicate that the assertion must be delivered to a particular network
endpoint in order to prevent an intermediary from redirecting it someplace else.

So should be reconfigured to the ACS URL by default instead of the entity identifier.

<EncryptedAssertion> is not replaced correctly

In SamlLib.js, the function decryptAssertion(type, here, from, entireXML, callback) fails replacing saml:EncryptedAssertion, if the element contains any attributes, e.g. namespace attributes, such as this real life case:

<saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">

My case was solved by changing:

.replace('saml:EncryptedAssertion', '')

with a reg exp search:

.replace(/saml:EncryptedAssertion[^]*>/, '')

However, doing text matches on XML with namespaces is not robust, because the prefix could just as well have been:

<assert:EncryptedAssertion xmlns:assert="urn:oasis:names:tc:SAML:2.0:assertion">

`undefined` on X509Certificate

I'm constructing an IDP with settings data. The resulting metadata includes the signing certificate data as expected, but the string undefined is appended to the end. This seems incorrect.

<X509Certificate>...
Tfq+Hb+5g/UZsWfMY/czR+0mYawjundefined</X509Certificate>

What am I doing wrong?

Support more signing algorithms

Support RSASHA256, RSASHA512, developer can choose the signing algorithm when configuring the entity. See the following example:

// Checkout the branch v1.1
var saml = require('express-saml2');
var sigAlg = saml.urn.algorithms.signature;
var sp = saml.ServiceProvider({
        // ...
        requestSignatureAlgorithm: sigAlg.RSA_SHA256 // or sigAlg.RSA_SHA512
});

See more detail in 3f76bf7, branch v1.1.

Invalid SPMetadata result

Hi! @tngan, I found the problem in metadata method in the code SPMetadata.js#L98

Look at this

const conf = {
  sp: {
    entityID: metaUrl,
    nameIDFormat:["urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"],
    assertionConsumerService:[{
      Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
      Location: acsUrl,
      Index: 1
    }, {
      Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
      Location: acsUrl,
      Index: 2
    }],
    singleLogoutService:[{
      Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
      Location: sloUrl,
      Index: 1
    }, {
      Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
      Location: sloUrl,
      Index: 2
    }]
  }
};
const sp = new saml.ServiceProvider(conf.sp);

const xml = sp.getMetadata();

I get this

<EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:assertion="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://localhost:3000/sso/metadata">
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<NameIDFormat>
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
</NameIDFormat>
<SingleLogoutService index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:3000/sso/slo/callback"/>
<SingleLogoutService index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:3000/sso/slo/callback"/>
<AssertionConsumerService index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:3000/sso/acs"/>
<AssertionConsumerService index="0" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:3000/sso/acs"/>
</SPSSODescriptor>
</EntityDescriptor>

xml param data is not valid if i try to validate it in www.samltool.com

Line: 1 | Column: 0 --> Element 'EntityDescriptor': No matching global declaration available for the validation root.

"md" prefix must be in any xml tag, like this

<md:EntityDescriptor  xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"" />

or "md" is useless and we must use tags without prefix, like this

<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" />

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.