Comparing version 1.12.3 to 2.0.0
@@ -695,5 +695,11 @@ // Generated by CoffeeScript 1.12.7 | ||
this.entity_id = options.entity_id, this.private_key = options.private_key, this.certificate = options.certificate, this.assert_endpoint = options.assert_endpoint, this.alt_private_keys = options.alt_private_keys, this.alt_certs = options.alt_certs; | ||
if (options.audience == null) { | ||
options.audience = this.entity_id; | ||
} | ||
if (options.notbefore_skew == null) { | ||
options.notbefore_skew = 1; | ||
} | ||
this.alt_private_keys = [].concat(this.alt_private_keys || []); | ||
this.alt_certs = [].concat(this.alt_certs || []); | ||
this.shared_options = _(options).pick("force_authn", "auth_context", "nameid_format", "sign_get_request", "allow_unencrypted_assertion"); | ||
this.shared_options = _(options).pick("force_authn", "auth_context", "nameid_format", "sign_get_request", "allow_unencrypted_assertion", "audience", "notbefore_skew"); | ||
} | ||
@@ -763,2 +769,5 @@ | ||
} | ||
if (!_.isNumber(options.notbefore_skew)) { | ||
return setImmediate(cb, new Error("Configuration error: `notbefore_skew` must be a number")); | ||
} | ||
saml_response = null; | ||
@@ -776,3 +785,3 @@ response = {}; | ||
return function(response_buffer, cb_wf) { | ||
var err, saml_response_abnormalized; | ||
var attribute, audience_restriction, audiences, condition, conditions, err, j, len, ref3, saml_response_abnormalized, validAudience; | ||
debug(saml_response); | ||
@@ -797,2 +806,34 @@ saml_response_abnormalized = add_namespaces_to_child_assertions(response_buffer.toString()); | ||
response.type = 'authn_response'; | ||
conditions = saml_response.getElementsByTagNameNS(XMLNS.SAML, 'Conditions')[0]; | ||
if (conditions != null) { | ||
if (options.ignore_timing !== true) { | ||
ref3 = conditions.attributes; | ||
for (j = 0, len = ref3.length; j < len; j++) { | ||
attribute = ref3[j]; | ||
condition = attribute.name.toLowerCase(); | ||
if (condition === 'notbefore' && Date.parse(attribute.value) > Date.now() + (options.notbefore_skew * 1000)) { | ||
return cb_wf(new SAMLError('SAML Response is not yet valid', { | ||
NotBefore: attribute.value | ||
})); | ||
} | ||
if (condition === 'notonorafter' && Date.parse(attribute.value) <= Date.now()) { | ||
return cb_wf(new SAMLError('SAML Response is no longer valid', { | ||
NotOnOrAfter: attribute.value | ||
})); | ||
} | ||
} | ||
} | ||
audience_restriction = conditions.getElementsByTagNameNS(XMLNS.SAML, 'AudienceRestriction')[0]; | ||
audiences = audience_restriction != null ? audience_restriction.getElementsByTagNameNS(XMLNS.SAML, 'Audience') : void 0; | ||
if ((audiences != null ? audiences.length : void 0) > 0) { | ||
validAudience = _.find(audiences, function(audience) { | ||
var audienceValue, ref4, ref5; | ||
audienceValue = (ref4 = audience.firstChild) != null ? (ref5 = ref4.data) != null ? ref5.trim() : void 0 : void 0; | ||
return !_.isEmpty(audienceValue.trim()) && ((_.isRegExp(options.audience) && options.audience.test(audienceValue)) || (_.isString(options.audience) && options.audience.toLowerCase() === audienceValue.toLowerCase())); | ||
}); | ||
if (validAudience == null) { | ||
return cb_wf(new SAMLError('SAML Response is not valid for this audience')); | ||
} | ||
} | ||
} | ||
return parse_authn_response(saml_response, [_this.private_key].concat(_this.alt_private_keys), identity_provider.certificates, options.allow_unencrypted_assertion, options.ignore_signature, options.require_session_index, cb_wf); | ||
@@ -799,0 +840,0 @@ case saml_response.getElementsByTagNameNS(XMLNS.SAMLP, 'LogoutResponse').length !== 1: |
{ | ||
"name": "saml2-js", | ||
"version": "1.12.3", | ||
"version": "2.0.0", | ||
"description": "SAML 2.0 node helpers", | ||
@@ -5,0 +5,0 @@ "author": "Clever", |
@@ -46,2 +46,4 @@ # SAML2-js | ||
- `alt_certs` - (Array of PEM format strings) - Additional certificates to expose in the SAML metadata. Useful for staging new certificates for rollovers. | ||
- `audience` - (String or RegExp) — If set, at least one of the `<Audience>` values within the `<AudienceRestriction>` condition of a SAML authentication response must match. Defaults to `entity_id`. | ||
- `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. | ||
- `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. | ||
@@ -143,2 +145,4 @@ - `auth_context` - Specifies `AuthnContextClassRef`. This can also be configured on a per-method basis. | ||
- `require_session_index` - (Boolean) - If false, allow the assertion to be valid without a `SessionIndex` attribute on the `AuthnStatement` node. | ||
- `audience` - (String or RegExp) — If set, at least one of the `<Audience>` values within the `<AudienceRestriction>` condition of a SAML authentication response must match. Defaults to `entity_id`. | ||
- `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. | ||
- `cb(error, response)` - Callback called with the [request response](#assert_response). | ||
@@ -230,2 +234,6 @@ | ||
var app = express(); | ||
var bodyParser = require('body-parser'); | ||
app.use(bodyParser.urlencoded({ | ||
extended: true | ||
})); | ||
@@ -232,0 +240,0 @@ // Create service provider |
Sorry, the diff of this file is not supported yet
182208
39
921
304