From 8f670a2d715957e166f303214cc6c84fa288f6a6 Mon Sep 17 00:00:00 2001 From: Doron Schwartz Date: Sat, 30 Mar 2019 14:54:21 +0300 Subject: [PATCH 1/2] Add support for overriding default relayState in createLoginRequest() --- src/binding-redirect.ts | 5 +++-- src/entity-sp.ts | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/binding-redirect.ts b/src/binding-redirect.ts index 14fac0d3..82454575 100644 --- a/src/binding-redirect.ts +++ b/src/binding-redirect.ts @@ -72,10 +72,11 @@ function buildRedirectURL(opts: BuildRedirectConfig) { * @param {function} customTagReplacement used when developers have their own login response template * @return {string} redirect URL */ -function loginRequestRedirectURL(entity: { idp: Idp, sp: Sp }, customTagReplacement?: (template: string) => BindingContext): BindingContext { +function loginRequestRedirectURL(entity: { idp: Idp, sp: Sp, relayState?: string }, customTagReplacement?: (template: string) => BindingContext): BindingContext { const metadata: any = { idp: entity.idp.entityMeta, sp: entity.sp.entityMeta }; const spSetting: any = entity.sp.entitySetting; + const relayState = entity.relayState === undefined ? spSetting.relayState : entity.relayState; let id: string = ''; if (metadata && metadata.idp && metadata.sp) { @@ -106,7 +107,7 @@ function loginRequestRedirectURL(entity: { idp: Idp, sp: Sp }, customTagReplacem isSigned: metadata.sp.isAuthnRequestSigned(), entitySetting: spSetting, baseUrl: base, - relayState: spSetting.relayState, + relayState, }), }; } diff --git a/src/entity-sp.ts b/src/entity-sp.ts index d935fde3..ee3c203a 100644 --- a/src/entity-sp.ts +++ b/src/entity-sp.ts @@ -51,11 +51,13 @@ export class ServiceProvider extends Entity { * @param {IdentityProvider} idp object of identity provider * @param {string} binding protocol binding * @param {function} customTagReplacement used when developers have their own login response template + * @param {string} relayState optionally override default SP relayState */ public createLoginRequest( idp: IdentityProvider, binding = 'redirect', customTagReplacement?: (...args: any[]) => any, + relayState?: string ): BindingContext | PostBindingContext { const nsBinding = namespace.binding; const protocol = nsBinding[binding]; @@ -63,15 +65,19 @@ export class ServiceProvider extends Entity { throw new Error('ERR_METADATA_CONFLICT_REQUEST_SIGNED_FLAG'); } + if (relayState === undefined) { + relayState = this.entitySetting.relayState; + } + if (protocol === nsBinding.redirect) { - return redirectBinding.loginRequestRedirectURL({ idp, sp: this }, customTagReplacement); + return redirectBinding.loginRequestRedirectURL({ idp, sp: this, relayState }, customTagReplacement); } if (protocol === nsBinding.post) { const context = postBinding.base64LoginRequest("/*[local-name(.)='AuthnRequest']", { idp, sp: this }, customTagReplacement); return { ...context, - relayState: this.entitySetting.relayState, + relayState, entityEndpoint: idp.entityMeta.getSingleSignOnService(binding), type: 'SAMLRequest', }; From 73be9f281cf740fbc6499c80c56fef21c3c0132e Mon Sep 17 00:00:00 2001 From: Doron Schwartz Date: Sat, 30 Mar 2019 14:54:56 +0300 Subject: [PATCH 2/2] Add support for skipping some validations in parseLoginResponse() --- src/entity-sp.ts | 17 +++++++++++++---- src/flow.ts | 8 +++++++- src/types.ts | 7 +++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/entity-sp.ts b/src/entity-sp.ts index ee3c203a..46bbd8f1 100644 --- a/src/entity-sp.ts +++ b/src/entity-sp.ts @@ -12,6 +12,7 @@ import { IdentityProviderConstructor as IdentityProvider, ServiceProviderMetadata, ServiceProviderSettings, + ValidationSettings, } from './types'; import { namespace } from './urn'; import redirectBinding from './binding-redirect'; @@ -50,7 +51,7 @@ export class ServiceProvider extends Entity { * @desc Generates the login request for developers to design their own method * @param {IdentityProvider} idp object of identity provider * @param {string} binding protocol binding - * @param {function} customTagReplacement used when developers have their own login response template + * @param {function} customTagReplacement used when developers have their own login response template * @param {string} relayState optionally override default SP relayState */ public createLoginRequest( @@ -91,10 +92,12 @@ export class ServiceProvider extends Entity { * @param {IdentityProvider} idp object of identity provider * @param {string} binding protocol binding * @param {request} req request + * @param {ValidationSettings} validation optionally skip some validations */ - public parseLoginResponse(idp, binding, request: ESamlHttpRequest) { + public parseLoginResponse(idp, binding, request: ESamlHttpRequest, validation?: ValidationSettings) { const self = this; - return flow({ + + const options = { from: idp, self: self, checkSignature: true, // saml response must have signature @@ -102,7 +105,13 @@ export class ServiceProvider extends Entity { type: 'login', binding: binding, request: request - }); + }; + + if (validation) { + Object.assign(options, validation); + } + + return flow(options); } } diff --git a/src/flow.ts b/src/flow.ts index 34e185a8..b4871ad8 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -118,7 +118,10 @@ async function postFlow(options): Promise { from, self, parserType, - checkSignature = true + checkSignature = true, + checkIssuer = true, + checkSessionTime = true, + checkTime = true } = options; const { body } = request; @@ -189,6 +192,7 @@ async function postFlow(options): Promise { // unmatched issuer if ( + checkIssuer && (parserType === 'LogoutResponse' || parserType === 'SAMLResponse') && extractedProperties && extractedProperties.issuer !== issuer @@ -198,6 +202,7 @@ async function postFlow(options): Promise { // invalid session time if ( + checkSessionTime && parserType === 'SAMLResponse' && !verifyTime( undefined, @@ -210,6 +215,7 @@ async function postFlow(options): Promise { // invalid time // 2.4.1.2 https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf if ( + checkTime && parserType === 'SAMLResponse' && extractedProperties.conditions && !verifyTime( diff --git a/src/types.ts b/src/types.ts index bad667de..5f0e8471 100644 --- a/src/types.ts +++ b/src/types.ts @@ -118,3 +118,10 @@ export interface IdentityProviderSettings { wantLogoutRequestSignedResponseSigned?: boolean; tagPrefix?: { [key: string]: string }; } + +export interface ValidationSettings { + checkSignature?: boolean; + checkIssuer?: boolean; + checkSessionTime?: boolean; + checkTime?: boolean; +}