@@ -12,6 +12,7 @@ var path = require('path');
1212var saml20 = fs . readFileSync ( path . join ( __dirname , 'saml20.template' ) ) . toString ( ) ;
1313
1414var NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion' ;
15+ var TIME_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ;
1516
1617var algorithms = {
1718 signature : {
@@ -102,15 +103,21 @@ exports.create = function(options, callback) {
102103 }
103104
104105 var now = moment . utc ( ) ;
105- doc . documentElement . setAttribute ( 'IssueInstant' , now . format ( 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ) ) ;
106+
107+ // Optionally, back up the issue instant to accommodate for clock skew in the assertion consumer
108+ if ( ! isNaN ( options . issueInstantSkewInSeconds ) ) {
109+ now . subtract ( options . issueInstantSkewInSeconds , 'seconds' ) ;
110+ }
111+
112+ doc . documentElement . setAttribute ( 'IssueInstant' , now . format ( TIME_FORMAT ) ) ;
106113 var conditions = doc . documentElement . getElementsByTagName ( 'saml:Conditions' ) ;
107114 var confirmationData = doc . documentElement . getElementsByTagName ( 'saml:SubjectConfirmationData' ) ;
108115
109116 if ( options . lifetimeInSeconds ) {
110- conditions [ 0 ] . setAttribute ( 'NotBefore' , now . format ( 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ) ) ;
111- conditions [ 0 ] . setAttribute ( 'NotOnOrAfter' , now . clone ( ) . add ( options . lifetimeInSeconds , 'seconds' ) . format ( 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ) ) ;
117+ conditions [ 0 ] . setAttribute ( 'NotBefore' , now . format ( TIME_FORMAT ) ) ;
118+ conditions [ 0 ] . setAttribute ( 'NotOnOrAfter' , now . clone ( ) . add ( options . lifetimeInSeconds , 'seconds' ) . format ( TIME_FORMAT ) ) ;
112119
113- confirmationData [ 0 ] . setAttribute ( 'NotOnOrAfter' , now . clone ( ) . add ( options . lifetimeInSeconds , 'seconds' ) . format ( 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ) ) ;
120+ confirmationData [ 0 ] . setAttribute ( 'NotOnOrAfter' , now . clone ( ) . add ( options . lifetimeInSeconds , 'seconds' ) . format ( TIME_FORMAT ) ) ;
114121 }
115122
116123 if ( options . audiences ) {
@@ -168,7 +175,7 @@ exports.create = function(options, callback) {
168175 }
169176
170177 doc . getElementsByTagName ( 'saml:AuthnStatement' ) [ 0 ]
171- . setAttribute ( 'AuthnInstant' , now . format ( 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' ) ) ;
178+ . setAttribute ( 'AuthnInstant' , now . format ( TIME_FORMAT ) ) ;
172179
173180 if ( options . sessionIndex ) {
174181 doc . getElementsByTagName ( 'saml:AuthnStatement' ) [ 0 ]
0 commit comments