@@ -10,13 +10,16 @@ import { SilentRenewService } from './SilentRenewService';
10
10
import { SessionMonitor } from './SessionMonitor' ;
11
11
import { TokenRevocationClient } from './TokenRevocationClient' ;
12
12
import { TokenClient } from './TokenClient' ;
13
+ import { JoseUtil } from './JoseUtil' ;
14
+
13
15
14
16
export class UserManager extends OidcClient {
15
17
constructor ( settings = { } ,
16
18
SilentRenewServiceCtor = SilentRenewService ,
17
19
SessionMonitorCtor = SessionMonitor ,
18
20
TokenRevocationClientCtor = TokenRevocationClient ,
19
- TokenClientCtor = TokenClient
21
+ TokenClientCtor = TokenClient ,
22
+ joseUtil = JoseUtil
20
23
) {
21
24
22
25
if ( ! ( settings instanceof UserManagerSettings ) ) {
@@ -40,6 +43,7 @@ export class UserManager extends OidcClient {
40
43
41
44
this . _tokenRevocationClient = new TokenRevocationClientCtor ( this . _settings ) ;
42
45
this . _tokenClient = new TokenClientCtor ( this . _settings ) ;
46
+ this . _joseUtil = joseUtil ;
43
47
}
44
48
45
49
get _redirectNavigator ( ) {
@@ -171,24 +175,57 @@ export class UserManager extends OidcClient {
171
175
return Promise . reject ( "No access token returned from token endpoint" ) ;
172
176
}
173
177
174
- Log . debug ( "UserManager._useRefreshToken: refresh token response success" ) ;
175
-
176
178
return this . _loadUser ( ) . then ( user => {
177
179
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
+ }
181
184
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
+ } ) ;
185
195
} ) ;
186
196
}
187
197
else {
188
198
return null ;
189
199
}
190
200
} ) ;
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
+ } ) ;
192
229
}
193
230
194
231
_signinSilentIframe ( args = { } ) {
0 commit comments