angular-auth-oidc-client: Cannot read property 'replace' of undefined

I’ve implemented the AutoLogin feature and after successful login in the following code I receive an error in browser console which says “Cannot read property replace of undefined”

Is it a bug or I’m missing something in code?

OidcSecurityValidation.prototype.urlBase64Decode = function (str) {
        var /** @type {?} */ output = str.replace('-', '+').replace('_', '/');
        switch (output.length % 4) {
            case 0:
                break;
            case 2:
                output += '==';
                break;
            case 3:
                output += '=';
                break;
            default:
                throw 'Illegal base64url string!';
        }
        return window.atob(output);
    };
    return OidcSecurityValidation;
}());

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 26 (16 by maintainers)

Most upvoted comments

I’m using version 1.17 (planning on upgrading to the latest soon) and I get the same issue. I’ve turned on the logging and I seem to get that error whenever the nonce fails validation. I’ve checked the server logs and I can confirm it returns the correct nonce. What I think is happening from reading the logs is that the client sends an authorize request to the server with a nonce which it stores on the local storage but then I think it sends another authorize request (before the other one gets its response) this time with a different nonce which overwrites the one on the local storage. The response for the first authorize request then returns but now that nonce is invalid because it is expecting the nonce of the second authorize request.

I’m not sure if this is exactly whats happening but it is what I can piece together from the logs.

Hope this helps.

Please note, that it also happen when user is signed out of STS, and the Angular app does silent_renew.

IsAuthorized: id_token isTokenExpired, start silent renew if active
17:03:00.668 angular-auth-oidc-client.es5.js:695 BEGIN refresh session Authorize
17:03:00.671 angular-auth-oidc-client.es5.js:695 RefreshSession created. adding myautostate: 15145533147370.5138137561867451
17:03:00.676 angular-auth-oidc-client.es5.js:695 startRenew for URL:https://localhost:44360/connect/authorize?client_id=angular&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fcallback&response_type=id_token%20token&scope=openid%20email%20profile%20api1&nonce=N0.170677065630323141514563380671&state=15145533147370.5138137561867451&prompt=none
17:03:02.097 angular-auth-oidc-client.es5.js:695 onUserDataChanged: last = undefined, new = 
17:03:02.257 angular-auth-oidc-client.es5.js:695 onUserDataChanged: last = , new = [object Object]
17:03:02.261 angular-auth-oidc-client.es5.js:695 STS server: https://localhost:44360
17:03:02.262 angular-auth-oidc-client.es5.js:695 {issuer: "https://localhost:44360", jwks_uri: "https://localhost:44360/.well-known/openid-configuration/jwks", authorization_endpoint: "https://localhost:44360/connect/authorize", token_endpoint: "https://localhost:44360/connect/token", userinfo_endpoint: "https://localhost:44360/connect/userinfo", …}
17:03:02.265 angular-auth-oidc-client.es5.js:695 AuthWellKnownEndpoints already defined
17:03:02.278 core.es5.js:2925 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
17:03:02.370 angular-auth-oidc-client.es5.js:695 onWellKnownEndpointsLoaded
17:03:02.671 angular-auth-oidc-client.es5.js:695 BEGIN authorizedCallback, no auth data
17:03:02.676 angular-auth-oidc-client.es5.js:695 {error: "login_required", state: "15145533147370.5138137561867451"}
17:03:02.681 angular-auth-oidc-client.es5.js:695 authorizedCallback created, begin token validation
17:03:02.684 angular-auth-oidc-client.es5.js:695 jwks_uri: https://localhost:44360/.well-known/openid-configuration/jwks
17:03:02.711 angular-auth-oidc-client.es5.js:695 authorizedCallback, token(s) validation failed, resetting
17:03:02.715 angular-auth-oidc-client.es5.js:695 onUserDataChanged: last = [object Object], new = 
17:03:02.718 angular-auth-oidc-client.es5.js:695 onUserDataChanged: Logout detected.
17:03:02.805 unauthorized.component.ts:38 --isAuthorizedSubscription isAuthorized: false
17:03:03.683 core.es5.js:1020 ERROR TypeError: Cannot read property 'replace' of undefined
    at OidcSecurityValidation.urlBase64Decode (angular-auth-oidc-client.es5.js:1079)
    at OidcSecurityValidation.getPayloadFromToken (angular-auth-oidc-client.es5.js:907)
    at OidcSecurityValidation.isTokenExpired (angular-auth-oidc-client.es5.js:724)
    at SafeSubscriber.eval [as _next] (angular-auth-oidc-client.es5.js:2151)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
    at SafeSubscriber.next (Subscriber.js:187)
    at Subscriber._next (Subscriber.js:128)
    at Subscriber.next (Subscriber.js:92)
    at TakeSubscriber._next (take.js:83)
    at TakeSubscriber.Subscriber.next (Subscriber.js:92)

I have this problem occasionally when the token refresh happens and another request is done while the token refresh has not yet completed:

TypeError: str is undefined

Stacktrace:

OidcSecurityValidation.urlBase64Decode
OidcSecurityValidation.getPayloadFromToken
OidcSecurityValidation.isTokenExpired
OidcSecurityService.runTokenValidation

This is what happens on the local storage: (I’ve replaced the token with the string TOKEN for clarity)

The storage_silent_renew_running key has been changed from "running" to "".
The userData key has been changed from {"http://schemas.microsoft.com/ws/2008/06/identity/claims/role":["Administrator"],"sub":"eeda22f3-5cbb-4298-9ade-11364f7f9cfc"} to "".
The authorizationResult key has been changed from {"id_token":"TOKEN","token_type":"Bearer","expires_in":"3600","scope":"openid%20email%20roles","state":"15120513517320.8940695338043914","session_state":"TOKEN"} to "".
The session_state key has been changed from "SESSION STATE" to "".
The _isAuthorized key has been changed from true to false.
The authorizationData key has been changed from "TOKEN" to "".
The authorizationDataIdToken key has been changed from "TOKEN" to "".
The redirectUrl key has been changed from  to /.
The authNonce key has been changed from "N0.429912304392828461513690042961" to "N0.2803600694724051513690043469".

Then I make a GET request to the identity server:

GET https://localhost:5001/connect/authorize?client_id=portal&redirect_uri=https://localhost:4430&response_type=id_token token&scope=openid email roles portal&nonce=N0.2803600694724051513690043469&state=15120513517320.8940695338043914

Which returns with a 302: Found status code. At this time another XHR request from the applications starts to make a database request, which fails because the Bearer token is not set at this point.

Also, from this point on, the token refresh does not work anymore besides the CheckSession ist constantly polling in the background, because the ID Token is not set in the local storage anymore.

(Version used: Commit e537d7403d6bf544c70913dea0af0fce79b72af4)

@damienbod I’m pretty sure this is not a server issue. I’ve just seen the error occur again on the client, and the server logs all look fine. I haven’t been able to trace beyond this.