Skip to content

Commit

Permalink
validate id_token after using refresh token
Browse files Browse the repository at this point in the history
  • Loading branch information
brockallen committed Dec 13, 2018
1 parent 14ed108 commit edb4b5d
Showing 1 changed file with 47 additions and 10 deletions.
57 changes: 47 additions & 10 deletions src/UserManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import { SilentRenewService } from './SilentRenewService';
import { SessionMonitor } from './SessionMonitor';
import { TokenRevocationClient } from './TokenRevocationClient';
import { TokenClient } from './TokenClient';
import { JoseUtil } from './JoseUtil';


export class UserManager extends OidcClient {
constructor(settings = {},
SilentRenewServiceCtor = SilentRenewService,
SessionMonitorCtor = SessionMonitor,
TokenRevocationClientCtor = TokenRevocationClient,
TokenClientCtor = TokenClient
TokenClientCtor = TokenClient,
joseUtil = JoseUtil
) {

if (!(settings instanceof UserManagerSettings)) {
Expand All @@ -40,6 +43,7 @@ export class UserManager extends OidcClient {

this._tokenRevocationClient = new TokenRevocationClientCtor(this._settings);
this._tokenClient = new TokenClientCtor(this._settings);
this._joseUtil = joseUtil;
}

get _redirectNavigator() {
Expand Down Expand Up @@ -171,24 +175,57 @@ export class UserManager extends OidcClient {
return Promise.reject("No access token returned from token endpoint");
}

Log.debug("UserManager._useRefreshToken: refresh token response success");

return this._loadUser().then(user => {
if (user) {
user.access_token = result.access_token;
user.refresh_token = result.refresh_token || user.refresh_token;
user.expires_in = result.expires_in;
let idTokenValidation = Promise.resolve();
if (result.id_token) {
idTokenValidation = this._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);
}

return this.storeUser(user).then(()=>{
this._events.load(user);
return user;
return idTokenValidation.then(() => {
Log.debug("UserManager._useRefreshToken: refresh token response success");
user.access_token = result.access_token;
user.refresh_token = result.refresh_token || user.refresh_token;
user.expires_in = result.expires_in;

return this.storeUser(user).then(()=>{
this._events.load(user);
return user;
});
});
}
else {
return null;
}
});
});;
});
}

_validateIdTokenFromTokenRefreshToken(profile, id_token) {
return this._metadataService.getIssuer().then(issuer => {
return this._joseUtil.validateJwtAttributes(id_token, issuer, this._settings.client_id, this._settings.clockSkew).then(payload => {
if (!payload) {
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token");
return Promise.reject(new Error("Failed to validate id_token"));
}
if (payload.sub !== profile.sub) {
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub");
return Promise.reject(new Error("sub in id_token does not match current sub"));
}
if (payload.auth_time && payload.auth_time !== profile.auth_time) {
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time");
return Promise.reject(new Error("auth_time in id_token does not match original auth_time"));
}
if (payload.azp && payload.azp !== profile.azp) {
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp");
return Promise.reject(new Error("azp in id_token does not match original azp"));
}
if (!payload.azp && profile.azp) {
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token");
return Promise.reject(new Error("azp not in id_token, but present in original id_token"));
}
});
});
}

_signinSilentIframe(args = {}) {
Expand Down

0 comments on commit edb4b5d

Please sign in to comment.