Test Identity Provider (IdP) for SAML 2.0 Web Browser SSO Profile
npm install @smartlook/saml-idpThis app provides a simple SAML Identity Provider (IdP) to test SAML 2.0 Service Providers (SPs) with the SAML 2.0 Web Browser SSO Profile or the Single Logout Profile.
> This sample is not intended for use with production systems!
`` shell`
npm install --global saml-idp
From inside a local copy of this repo
` shell`
npm installor
npm link
` shell`
npm install saml-idp
1. docker-compose build
2. docker-compose up
Simply modify Dockerfile to specify your own parameters.
You must generate a self-signed certificate for the IdP.
> The private key should be unique to your test IdP and not shared!
You can generate a keypair using the following command (requires openssl in your path):
` shell`
openssl req -x509 -new -newkey rsa:2048 -nodes -subj '/C=US/ST=California/L=San Francisco/O=JankyCo/CN=Test Identity Provider' -keyout idp-private-key.pem -out idp-public-cert.pem -days 7300
An IdP server can be started using the exported runServer function. runServer accepts a config object which matches the interface of the saml-idp command.
` javascript
const {runServer} = require('saml-idp');
runServer({
acsUrl: https://foo.okta.com/auth/saml20/assertion-consumer,https://foo.okta.com/auth/saml20/metadata
audience: ,`
});
#### Custom user config (claims)
` javascript
const {runServer} = require('saml-idp');
runServer({
acsUrl: https://foo.okta.com/auth/saml20/assertion-consumer,https://foo.okta.com/auth/saml20/metadata
audience: ,`
config: {
user: userDefaults,
// The auth-service requires at least one AttributeStatement in the SAML assertion.
metadata: [{
id: 'email',
optional: false,
displayName: 'E-Mail Address',
description: 'The e-mail address of the user',
multiValue: false
}, {
id: "userType",
optional: true,
displayName: 'User Type',
description: 'The type of user',
options: ['Admin', 'Editor', 'Commenter']
}],
user: {
email: 'saml.jackson@example.com',
},
},
});
#### SSO Profile
` shell`
saml-idp --acsUrl {POST URL} --audience {audience}
#### SSO & SLO Profile
``
saml-idp --acsUrl {POST URL} --sloUrl {POST URL} --audience {audience}
Open http://localhost:7000 in your browser to start an IdP initiated flow to your SP
#### Example
``
saml-idp --acsUrl https://foo.okta.com/auth/saml20/example --audience https://www.okta.com/saml2/service-provider/spf5aFRRXFGIMAYXQPNV
#### Options
The following options can either be passed as --
Option (* required) | Description | Default
-----------------------: | --------------------------------------------------------------------------------------------------- | ----------
host | IdP Web Server Listender Host | localhost
port | IdP Web Server Listener Port | 7000
cert _*_ | IdP Signature PublicKey Certificate | ./idp-public-cert.pem
key _*_ | IdP Signature PrivateKey Certificate | ./idp-private-key.pem
issuer _*_ | IdP Issuer URI | urn:example:idp
acsUrl _*_ | SP Assertion Consumer URL |
sloUrl | SP Single |
audience _*_ | SP Audience URI |
serviceProviderId | SP Issuer/Entity URI |
relayState | Default SAML RelayState |
disableRequestAcsUrl | Disables ability for SP AuthnRequest to specify Assertion Consumer URL | false
encryptAssertion | Encrypts assertion with SP Public Key | false
encryptionCert | SP Certificate (pem) for Assertion Encryption |
encryptionPublicKey | SP RSA Public Key (pem) for Assertion Encryption (e.g. openssl x509 -pubkey -noout -in sp-cert.pem) |
httpsPrivateKey | Web Server TLS/SSL Private Key (pem) |
httpsCert | Web Server TLS/SSL Certificate (pem) |
https _*_ | Enables HTTPS Listener (requires httpsPrivateKey and httpsCert) | false
configFile _*_ | Path to a SAML attribute config file | saml-idp/config.js
rollSession | Create a new session for every authn request instead of reusing an existing session | false
authnContextClassRef | Authentication Context Class Reference | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
authnContextDecl | Authentication Context Declaration (XML FilePath) |
The default IdP issuer is urn:example:idp. You can change this with the --iss argument.
The signing certificate public key must be specified as a file path or PEM string using the cert argument.
To generate a self-signed certificate for the IdP run
` shell`
openssl req -x509 -new -newkey rsa:2048 -nodes \
-subj '/C=US/ST=California/L=San Francisco/O=JankyCo/CN=Test Identity Provider' \
-keyout idp-private-key.pem \
-out idp-public-cert.pem -days 7300
The signing certificate private key must be specified as a file path or PEM string using the key argument
Signing certificate key/cert pairs can also be passed from environment variables.
``
saml-idp --acsUrl {POST URL} --audience {audience} --cert="$SAML_CERT" --key="$SAML_KEY"
Both SSO POST and Redirect bindings are available on the same endpoint which by default is http://localhost:7000/saml/sso
Binding | URL
------------- | --------------------------------------------------------
HTTP-Redirect | http://localhost:port/saml/ssohttp://localhost:port/saml/sso
HTTP-POST |
Both SSO POST and Redirect bindings are available on the same endpoint which by default is http://localhost:7000/saml/slo
Binding | URL
------------- | --------------------------------------------------------
HTTP-Redirect | http://localhost:port/saml/slohttp://localhost:port/saml/slo
HTTP-POST |
IdP SAML metadata is available on http://localhost:port/metadata
The IdP mints the user's profile as a SAML Assertion Attribute Statement using the metadata property in config.js. Profile properties that match a metadata entry id property will be generated as a SAML Attribute with the same name. The IdP UI will automatically render an input for each entry defined via a metadata entry in config.js with a default value from the matching profile property.
#### Profile Property
`json`
{
"email": "saml.jackson@example.com"
}
#### Metadata Entry
`json`
{
"id": "email",
"optional": false,
"displayName": "E-Mail Address",
"description": "The e-mail address of the user",
"multiValue": false
}
#### SAML Assertion Attribute Statement
`xml`
The default profile mappings are defined in config.js as:
Profile Property | SAML Attribute Name
--------------------- | --------------------------------------------------------
userName | Subject NameID
nameIdFormat | Subject NameID Format
nameIdNameQualifier | Subject NameID Name Qualifer
nameIdSPNameQualifier | Subject NameID SP Name Qualifer
nameIdSPProvidedID | Subject NameID SP ProvidedID
firstName | firstNamelastName
lastName | displayName
displayName |
email | mobilePhone
mobilePhone | groups
groups |
> SAML attribute mappings currently default to Okta (Inbound SAML)
New attributes can be defined at runtime in the IdP UI or statically by modifying the profile and metadata objects in config.js.
1. Add metadata entry for your new attributes. The id property must be the name of the SAML Attribute
`json`
{
"id": "customAttribute",
"optional": false,
"displayName": "Custom Attribute",
"description": "My custom attribute",
"multiValue": false
}
2. Optionally add a default profile attribute value that will be used on startup
Encrypted assertions require both a certificate and public key from the target service provider in the PEM format (base64 encoding of .der, .cer, .cert, .crt). You can convert certificate formats with openssl
` shell`
openssl x509 -inform der -in to-convert.der -out converted.pem
> The following formats or extensions should be convertible to the pem format: .der, .cer, .cert, .crt
PEM files that contain the header -----BEGIN CERTIFICATE----- can also be converted to just the public key which is a file with just the -----BEGIN PUBLIC KEY----- header
`` shell``
openssl x509 -pubkey -noout -in cert.pem > pub.key