@@ -181,63 +181,73 @@ export default class ResponseValidator {
181181 validateIdToken ( state , response ) {
182182 Log . info ( "ResponseValidator.validateIdToken" ) ;
183183
184- return Promise . resolve ( response ) ;
185-
186- // log("OidcClient.validateIdTokenAsync");
187-
188- // var client = this;
189- // var settings = client._settings;
190-
191- // return client.loadX509SigningKeyAsync().then(function (cert) {
192-
193- // var jws = new KJUR.jws.JWS();
194- // if (jws.verifyJWSByPemX509Cert(id_token, cert)) {
195- // var id_token_contents = JSON.parse(jws.parsedJWS.payloadS);
184+ if ( ! state . nonce ) {
185+ Log . error ( "No nonce on state" ) ;
186+ return Promise . reject ( new Error ( "No nonce on state" ) ) ;
187+ }
196188
197- // if (nonce !== id_token_contents.nonce) {
198- // return error("Invalid nonce");
199- // }
189+ let jwt = this . _jwtUtil . parseJwt ( response . id_token ) ;
190+ if ( ! jwt || ! jwt . header || ! jwt . payload ) {
191+ Log . error ( "Failed to parse id_token" , jwt ) ;
192+ return Promise . reject ( new Error ( "Failed to parse id_token" ) ) ;
193+ }
200194
201- // return client.loadMetadataAsync().then(function (metadata) {
195+ var kid = jwt . header . kid ;
196+ if ( ! kid ) {
197+ Log . error ( "No kid found in id_token" ) ;
198+ return Promise . reject ( new Error ( "No kid found in id_token" ) ) ;
199+ }
202200
203- // if (id_token_contents.iss !== metadata.issuer) {
204- // return error("Invalid issuer");
205- // }
201+ let audience = this . _settings . client_id ;
202+ if ( ! audience ) {
203+ Log . error ( "Invalid audience/client_id value" ) ;
204+ return Promise . reject ( new Error ( "Invalid audience/client_id value" ) ) ;
205+ }
206206
207- // if (id_token_contents.aud !== settings.client_id) {
208- // return error("Invalid audience");
209- // }
207+ return this . _metadataService . getIssuer ( ) . then ( issuer => {
208+ Log . info ( "Received issuer" ) ;
210209
211- // var now = parseInt(Date.now() / 1000);
210+ return this . _metadataService . getSigningKeys ( ) . then ( keys => {
211+ if ( ! keys ) {
212+ Log . error ( "No signing keys from metadata" ) ;
213+ return Promise . reject ( new Error ( "No signing keys from metadata" ) ) ;
214+ }
215+
216+ Log . info ( "Received signing keys" ) ;
212217
213- // // accept tokens issues up to 5 mins ago
214- // var diff = now - id_token_contents.iat;
215- // if (diff > (5 * 60)) {
216- // return error("Token issued too long ago");
217- // }
218+ let key = keys . filter ( key => {
219+ return key . kid === kid ;
220+ } ) [ 0 ] ;
218221
219- // if (id_token_contents.exp < now) {
220- // return error("Token expired");
221- // }
222+ if ( ! key ) {
223+ Log . error ( "No key matching kid found in signing keys" ) ;
224+ return Promise . reject ( new Error ( "No key matching kid found in signing keys" ) ) ;
225+ }
222226
223- // if (access_token && settings.load_user_profile) {
224- // // if we have an access token, then call user info endpoint
225- // return client.loadUserProfile(access_token, id_token_contents).then(function (profile) {
226- // return copy(profile, id_token_contents);
227- // });
228- // }
229- // else {
230- // // no access token, so we have all our claims
231- // return id_token_contents;
232- // }
227+ if ( ! this . validateJwt ( response . id_token , key , issuer , audience ) ) {
228+ Log . error ( "Signature failed to validate" ) ;
229+ return Promise . reject ( new Error ( "Signature failed to validate" ) ) ;
230+ }
233231
234- // }) ;
235- // }
236- // else {
237- // return error("JWT failed to validate" );
238- // }
232+ response . profile = jwt . payload ;
233+ return response ;
234+ } ) ;
235+ } ) ;
236+ }
239237
240- // });
238+ validateJwt ( id_token , key , issuer , audience ) {
239+ Log . info ( "ResponseValidator.validateJwt" ) ;
240+
241+ if ( key . kty === "RSA" ) {
242+ return this . _jwtUtil . validateJwtRsa ( id_token , key , issuer , audience ) ;
243+ }
244+ else if ( key . kty === "EC" ) {
245+ return this . _jwtUtil . validateJwtEc ( id_token , key , issuer , audience ) ;
246+ }
247+ else {
248+ Log . error ( "Unsupported key type:" , key . kty ) ;
249+ return false ;
250+ }
241251 }
242252
243253 validateAccessToken ( response ) {
@@ -258,7 +268,13 @@ export default class ResponseValidator {
258268 return Promise . reject ( new Error ( "No id_token" ) ) ;
259269 }
260270
261- var hashAlg = this . _jwtUtil . getAlg ( response . id_token ) ;
271+ let jwt = this . _jwtUtil . parseJwt ( response . id_token ) ;
272+ if ( ! jwt || ! jwt . header ) {
273+ Log . error ( "Failed to parse id_token" , jwt ) ;
274+ return Promise . reject ( new Error ( "Failed to parse id_token" ) ) ;
275+ }
276+
277+ var hashAlg = jwt . header . alg ;
262278 if ( ! hashAlg || hashAlg . length !== 5 ) {
263279 Log . error ( "Unsupported alg:" , hashAlg ) ;
264280 return Promise . reject ( new Error ( "Unsupported alg: " + hashAlg ) ) ;
0 commit comments