Skip to content

Commit edb4b5d

Browse files
committed
validate id_token after using refresh token
1 parent 14ed108 commit edb4b5d

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

src/UserManager.js

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ import { SilentRenewService } from './SilentRenewService';
1010
import { SessionMonitor } from './SessionMonitor';
1111
import { TokenRevocationClient } from './TokenRevocationClient';
1212
import { TokenClient } from './TokenClient';
13+
import { JoseUtil } from './JoseUtil';
14+
1315

1416
export class UserManager extends OidcClient {
1517
constructor(settings = {},
1618
SilentRenewServiceCtor = SilentRenewService,
1719
SessionMonitorCtor = SessionMonitor,
1820
TokenRevocationClientCtor = TokenRevocationClient,
19-
TokenClientCtor = TokenClient
21+
TokenClientCtor = TokenClient,
22+
joseUtil = JoseUtil
2023
) {
2124

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

4144
this._tokenRevocationClient = new TokenRevocationClientCtor(this._settings);
4245
this._tokenClient = new TokenClientCtor(this._settings);
46+
this._joseUtil = joseUtil;
4347
}
4448

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

174-
Log.debug("UserManager._useRefreshToken: refresh token response success");
175-
176178
return this._loadUser().then(user => {
177179
if (user) {
178-
user.access_token = result.access_token;
179-
user.refresh_token = result.refresh_token || user.refresh_token;
180-
user.expires_in = result.expires_in;
180+
let idTokenValidation = Promise.resolve();
181+
if (result.id_token) {
182+
idTokenValidation = this._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);
183+
}
181184

182-
return this.storeUser(user).then(()=>{
183-
this._events.load(user);
184-
return user;
185+
return idTokenValidation.then(() => {
186+
Log.debug("UserManager._useRefreshToken: refresh token response success");
187+
user.access_token = result.access_token;
188+
user.refresh_token = result.refresh_token || user.refresh_token;
189+
user.expires_in = result.expires_in;
190+
191+
return this.storeUser(user).then(()=>{
192+
this._events.load(user);
193+
return user;
194+
});
185195
});
186196
}
187197
else {
188198
return null;
189199
}
190200
});
191-
});;
201+
});
202+
}
203+
204+
_validateIdTokenFromTokenRefreshToken(profile, id_token) {
205+
return this._metadataService.getIssuer().then(issuer => {
206+
return this._joseUtil.validateJwtAttributes(id_token, issuer, this._settings.client_id, this._settings.clockSkew).then(payload => {
207+
if (!payload) {
208+
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token");
209+
return Promise.reject(new Error("Failed to validate id_token"));
210+
}
211+
if (payload.sub !== profile.sub) {
212+
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub");
213+
return Promise.reject(new Error("sub in id_token does not match current sub"));
214+
}
215+
if (payload.auth_time && payload.auth_time !== profile.auth_time) {
216+
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time");
217+
return Promise.reject(new Error("auth_time in id_token does not match original auth_time"));
218+
}
219+
if (payload.azp && payload.azp !== profile.azp) {
220+
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp");
221+
return Promise.reject(new Error("azp in id_token does not match original azp"));
222+
}
223+
if (!payload.azp && profile.azp) {
224+
Log.error("UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token");
225+
return Promise.reject(new Error("azp not in id_token, but present in original id_token"));
226+
}
227+
});
228+
});
192229
}
193230

194231
_signinSilentIframe(args = {}) {

0 commit comments

Comments
 (0)