[SAML2-js] update SAML2-js types for version 2.x (#49787)

* update saml2-js types

* add mathieudutour to definition author

* fix lint

* fix jsdoc alignment
This commit is contained in:
Mathieu Dutour
2020-12-18 20:53:30 +01:00
committed by GitHub
parent ab539dc723
commit 4e78c523d1
2 changed files with 158 additions and 67 deletions

View File

@@ -1,75 +1,172 @@
// Type definitions for SAML2-js 1.6.0
// Type definitions for SAML2-js 2.0.6
// Project: https://github.com/Clever/saml2
// Definitions by: horiuchi <https://github.com/horiuchi>
// mathieudutour <https://github.com/mathiedutour>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
declare module "saml2-js" {
declare module 'saml2-js' {
/** Represents an online service that authenticates users in the SAML flow. */
export class IdentityProvider {
constructor(options: IdentityProviderOptions);
}
export interface IdentityProviderOptions {
/** Login url to use during a login request. */
sso_login_url: string;
/** Logout url to use during a logout request. */
sso_logout_url: string;
certificates: string[];
/** Certificate or certificates (array of certificate) for the identity provider. */
certificates: string | string[];
/** If true, forces re-authentication of users even if the user has a SSO session with the IdP. This can also be configured on the SP or on a per-method basis. */
force_authn?: boolean;
/** If true, signs the request. This can also be configured on the SP or on a per-method basis. */
sign_get_request?: boolean;
/** If true, allows unencrypted assertions. This can also be configured on the SP or on a per-method basis. */
allow_unencrypted_assertion?: boolean;
}
/** Represents a service provider that relies on a trusted IdentityProvider for authentication and authorization in the SAML flow. */
export class ServiceProvider {
constructor(options: ServiceProviderOptions);
create_login_request_url(IdP: IdentityProvider, options: CreateLoginRequestUrlOptions, cb: (error: any, login_url: string, request_id: string) => void): void;
redirect_assert(IdP: IdentityProvider, options: GetAssertOptions, cb: (error: any, response: any) => void): void;
post_assert(IdP: IdentityProvider, options: GetAssertOptions, cb: (error: any, response: any) => void): void;
create_logout_request_url(IdP: IdentityProvider, options: CreateLogoutRequestUrlOptions, cb: (error: any, request_url: string) => void): void;
create_logout_response_url(IdP: IdentityProvider, options: CreateLogoutResponseUrlOptions, cb: (error: any, response_url: string) => void): void;
/** Get a URL to initiate a login. */
create_login_request_url(
IdP: IdentityProvider,
options: CreateLoginRequestUrlOptions,
cb: (error: Error | null, login_url: string, request_id: string) => void,
): void;
/** Gets a SAML response object if the login attempt is valid, used for redirect binding. */
redirect_assert(
IdP: IdentityProvider,
options: RedirectAssertOptions,
cb: (error: Error | null, response: SAMLAssertResponse) => void,
): void;
/** Gets a SAML response object if the login attempt is valid, used for post binding. */
post_assert(
IdP: IdentityProvider,
options: PostAssertOptions,
cb: (error: Error | null, response: SAMLAssertResponse) => void,
): void;
/** Creates a SAML Request URL to initiate a user logout. */
create_logout_request_url(
IdP: IdentityProvider | string,
options: CreateLogoutRequestUrlOptions,
cb: (error: Error | null, request_url: string, request_id: string) => void,
): void;
/** Creates a SAML Response URL to confirm a successful IdP initiated logout. */
create_logout_response_url(
IdP: IdentityProvider | string,
options: CreateLogoutResponseUrlOptions,
cb: (error: Error | null, response_url: string) => void,
): void;
/** Returns the XML metadata used during the initial SAML configuration. */
create_metadata(): string;
}
export interface ServiceProviderOptions {
/** Unique identifier for the service provider, often the URL of the metadata file. */
entity_id: string;
/** Private key for the service provider. */
private_key: string;
/** Certificate for the service provider. */
certificate: string;
/** URL of service provider assert endpoint. */
assert_endpoint: string;
/** Additional private keys to use when attempting to decrypt responses. Useful for adding backward-compatibility for old certificates after a rollover. */
alt_private_keys?: string[];
/** Additional certificates to expose in the SAML metadata. Useful for staging new certificates for rollovers. */
alt_certs?: string[];
/** If set, at least one of the <Audience> values within the <AudienceRestriction> condition of a SAML authentication response must match. Defaults to `entity_id`. */
audience?: string | RegExp;
/**
* 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.
*/
notbefore_skew?: number;
/** If true, forces re-authentication of users even if the user has a SSO session with the IdP. This can also be configured on the IdP or on a per-method basis. */
force_authn?: boolean;
/** Specifies AuthnContextClassRef. This can also be configured on a per-method basis. */
auth_context?: AuthnContextClassRef;
/** Format for Name ID. This can also be configured on a per-method basis. */
nameid_format?: string;
/** If true, signs the request. This can also be configured on the IdP or on a per-method basis. */
sign_get_request?: boolean;
/** If true, allows unencrypted assertions. This can also be configured on the IdP or on a per-method basis. */
allow_unencrypted_assertion?: boolean;
}
export interface CreateLoginRequestUrlOptions {
/** SAML relay state. */
relay_state?: string;
/** Specifies AuthnContextClassRef. This can also be configured on the SP. */
auth_context?: AuthnContextClassRef;
/** Format for Name ID. This can also be configured on the SP. */
nameid_format?: string;
/** If true, forces re-authentication of users even if the user has a SSO session with the IdP. This can also be configured on the IdP or SP. */
force_authn?: boolean;
/** If true, signs the request. This can also be configured on the IdP or SP. */
sign_get_request?: boolean;
}
export interface GetAssertOptions {
request_body?: any;
export interface RedirectAssertOptions {
/** An object containing the parsed query string parameters. This object should contain the value for either a SAMLResponse or SAMLRequest. */
request_body: {
SAMLResponse?: any;
SAMLRequest?: any;
};
/** If true, allows unencrypted assertions. This can also be configured on the IdP or SP. */
allow_unencrypted_assertion?: boolean;
/** If false, allow the assertion to be valid without a SessionIndex attribute on the AuthnStatement node. */
require_session_index?: boolean;
}
export interface PostAssertOptions extends RedirectAssertOptions {
/** If set, at least one of the <Audience> values within the <AudienceRestriction> condition of a SAML authentication response must match. Defaults to entity_id. */
audience?: string | RegExp;
/**
* 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.
*/
notbefore_skew?: boolean;
}
export interface CreateLogoutRequestUrlOptions {
/** Format for Name ID. This can also be configured on a per-method basis. */
name_id?: string;
/** Session index to use for creating logout request. */
session_index?: string;
/** If true, allows unencrypted assertions. This can also be configured on the IdP or SP. */
allow_unencrypted_assertion?: boolean;
/** If true, signs the request. This can also be configured on the IdP or SP. */
sign_get_request?: boolean;
/** SAML relay state. */
relay_state?: string;
}
export interface CreateLogoutResponseUrlOptions {
/** The ID of the request that this is in response to. Should be checked against any sent request IDs. */
in_response_to?: string;
/** If true, signs the request. This can also be configured on the IdP or SP. */
sign_get_request?: boolean;
/** SAML relay state. */
relay_state?: string;
}
export interface SAMLAssertResponse {
response_header: { id: 'string'; destination: string; in_response_to: string };
type: string;
user: {
name_id: string;
session_index?: string;
session_not_on_or_after?: string;
attributes?: { [attr: string]: string | string[] };
};
}
export interface AuthnContextClassRef {
comparison: string;
class_refs: string[];
}
}

View File

@@ -2,19 +2,18 @@ import * as fs from 'fs';
import express = require('express');
import * as saml2 from 'saml2-js';
// Example
{
const sp_options = {
entity_id: "https://sp.example.com/metadata.xml",
private_key: fs.readFileSync("key-file.pem").toString(),
certificate: fs.readFileSync("cert-file.crt").toString(),
assert_endpoint: "https://sp.example.com/assert",
entity_id: 'https://sp.example.com/metadata.xml',
private_key: fs.readFileSync('key-file.pem').toString(),
certificate: fs.readFileSync('cert-file.crt').toString(),
assert_endpoint: 'https://sp.example.com/assert',
force_authn: true,
auth_context: { comparison: "exact", class_refs: ["urn:oasis:names:tc:SAML:1.0:am:password"] },
nameid_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
auth_context: { comparison: 'exact', class_refs: ['urn:oasis:names:tc:SAML:1.0:am:password'] },
nameid_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
sign_get_request: false,
allow_unencrypted_assertion: true
allow_unencrypted_assertion: true,
};
// Call service provider constructor with options
@@ -26,12 +25,12 @@ import * as saml2 from 'saml2-js';
// Initialize options object
const idp_options = {
sso_login_url: "https://idp.example.com/login",
sso_logout_url: "https://idp.example.com/logout",
certificates: [fs.readFileSync("cert-file1.crt").toString(), fs.readFileSync("cert-file2.crt").toString()],
sso_login_url: 'https://idp.example.com/login',
sso_logout_url: 'https://idp.example.com/logout',
certificates: [fs.readFileSync('cert-file1.crt').toString(), fs.readFileSync('cert-file2.crt').toString()],
force_authn: true,
sign_get_request: false,
allow_unencrypted_assertion: false
allow_unencrypted_assertion: false,
};
// Call identity provider constructor with options
@@ -39,80 +38,75 @@ import * as saml2 from 'saml2-js';
// Example usage of identity provider.
// Pass identity provider into a service provider function with options and a callback.
sp.post_assert(idp, {}, (error: any, response: any) => {});
sp.post_assert(idp, { request_body: { SAMLRequest: {} } }, (error: any, response: any) => {});
}
// Example: Express implementation
{
const app = express();
// Create service provider
const sp_options = {
entity_id: "https://sp.example.com/metadata.xml",
private_key: fs.readFileSync("key-file.pem").toString(),
certificate: fs.readFileSync("cert-file.crt").toString(),
assert_endpoint: "https://sp.example.com/assert"
entity_id: 'https://sp.example.com/metadata.xml',
private_key: fs.readFileSync('key-file.pem').toString(),
certificate: fs.readFileSync('cert-file.crt').toString(),
assert_endpoint: 'https://sp.example.com/assert',
};
const sp = new saml2.ServiceProvider(sp_options);
// Create identity provider
const idp_options = {
sso_login_url: "https://idp.example.com/login",
sso_logout_url: "https://idp.example.com/logout",
certificates: [fs.readFileSync("cert-file1.crt").toString(), fs.readFileSync("cert-file2.crt").toString()]
sso_login_url: 'https://idp.example.com/login',
sso_logout_url: 'https://idp.example.com/logout',
certificates: [fs.readFileSync('cert-file1.crt').toString(), fs.readFileSync('cert-file2.crt').toString()],
};
const idp = new saml2.IdentityProvider(idp_options);
// ------ Define express endpoints ------
// Endpoint to retrieve metadata
app.get("/metadata.xml", function(req, res) {
res.type('application/xml');
res.send(sp.create_metadata());
app.get('/metadata.xml', function(req, res) {
res.type('application/xml');
res.send(sp.create_metadata());
});
// Starting point for login
app.get("/login", function(req, res) {
sp.create_login_request_url(idp, {}, function(err, login_url, request_id) {
if (err != null)
return res.send(500);
res.redirect(login_url);
});
app.get('/login', function(req, res) {
sp.create_login_request_url(idp, {}, function(err, login_url, request_id) {
if (err != null) return res.send(500);
res.redirect(login_url);
});
});
// Assert endpoint for when login completes
app.post("/assert", function(req, res) {
const options = {request_body: req.body};
sp.post_assert(idp, options, function(err, saml_response) {
if (err != null)
return res.send(500);
app.post('/assert', function(req, res) {
const options = { request_body: req.body };
sp.post_assert(idp, options, function(err, saml_response) {
if (err != null) return res.send(500);
// Save name_id and session_index for logout
// Note: In practice these should be saved in the user session, not globally.
let name_id = saml_response.user.name_id;
let session_index = saml_response.user.session_index;
// Save name_id and session_index for logout
// Note: In practice these should be saved in the user session, not globally.
let name_id = saml_response.user.name_id;
let session_index = saml_response.user.session_index;
res.send("Hello #{saml_response.user.name_id}!");
});
res.send('Hello #{saml_response.user.name_id}!');
});
});
// Starting point for logout
app.get("/logout", function(req, res) {
let name_id = '';
let session_index = '';
const options = {
name_id: name_id,
session_index: session_index
};
app.get('/logout', function(req, res) {
let name_id = '';
let session_index = '';
const options = {
name_id: name_id,
session_index: session_index,
};
sp.create_logout_request_url(idp, options, function(err, logout_url) {
if (err != null)
return res.send(500);
res.redirect(logout_url);
});
sp.create_logout_request_url(idp, options, function(err, logout_url) {
if (err != null) return res.send(500);
res.redirect(logout_url);
});
});
app.listen(3000);
}