BUG report: Oauth2 `tryLogin` doesn't call `callOnTokenReceivedIfExists` function
See original GitHub issueHi fellow coders!
Awesome library for integration Angular app and Oauth / Oidc, thanks for the hard work!
I think we may have found a bug here. First, little bit background:
Setup
Angular: 6.0 Identity Provider: OWIN Oauth2 Authorization Server Protocol: Oauth2
Auth Configuration
authConfig: {
issuer: 'http://localhost:1000/',
loginUrl: 'http://localhost:1000/oauth/authorize',
oidc: false,
redirectUri: window.location.origin + '/redirect',
silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
clientId: 'd68c39fa-7d73-4785-8be7-8074c2d905a4'
}
Background
There are 2 occasions where we notice the onTokenReceived
login option is not being called in our case (Oauth2 - oidc: false
):
-
Calling
tryLogin
withonTokenReceived
option.- Code:
this.oauthService.tryLogin({ onTokenReceived: () => { console.log('onTokenReceived'); } });
- In this case, after the login, we don’t see
console.log
message. - Getting the state using this approach is also not possible.
-
Calling
silentRefresh
- Code
this.oauthService.silentRefresh();
- The
silently_refreshed
event was never returned. - Instead, we always get
silent_refresh_timeout
. - We make sure
silent-refresh.html
is registered and accessible by browsing to the URL. - We also register a customer listener to ensure
silent-refresh.html
post message to parent window. We see the event is emitted and it contains necessary data in a correct format (ie:e.data
starts with#
)
let testListener = (e: MessageEvent) => { console.log(e); }; window.addEventListener( 'message', testListener );
The Bug
Looking through the code, we notice tryLogin
function doesn’t call callOnTokenReceivedIfExists
function like it did on when using OIDC implicit flow.
if (!this.oidc) {
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {
location.hash = '';
}
return Promise.resolve();
}
Where as in OIDC implicit flow, it is.
this.callOnTokenReceivedIfExists(options);
This kinda explains why we always get silent_refresh_timeout
when calling silentRefresh()
. We thought it was because tryLogin
in silentRefreshPostMessageEventlistener
is using onTokenReceived
and it’s never called in our case.
this.tryLogin({
customHashFragment: message,
preventClearHashAfterLogin: true,
onLoginError: err => {
this.eventsSubject.next(
new OAuthErrorEvent('silent_refresh_error', err)
);
},
onTokenReceived: () => {
this.eventsSubject.next(new OAuthSuccessEvent('silently_refreshed'));
}
}).catch(err => this.debug('tryLogin during silent refresh failed', err));
Thought?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:5 (1 by maintainers)
Top GitHub Comments
Hi @jeroenheijmans , thanks for your response. Yeah, I love MD, so MD-fy everything. 😃
Yes, I saw your workaround on #424 and it’s super helpful, thanks for this! We ended using your workaround to get the
state
However, we still don’t have a workaround for
silent_refresh_timeout
issue. It’s outside of control at this point as the library is not invokingcallOnTokenReceivedIfExists
function at the moment. For now, we could technically just ignore the error message because the token is actually being refreshed.Thanks!
That is one well-written GitHub issue! ❤️
I’m not sure if I can help you with your concrete issue, but some loosely coupled remarks nonetheless:
onTokenReceived
didn’t work reliably and documented my workaround/solution with a different flow in #424 - basically I just.then(() => ...)
at the end of the chain (somewhere aftertryLogin()
this.oAuthService.events.pipe(filter(e => e.type === 'token_received')).subscribe...
to handle events, which (for us at least) can work a lot more reliableHope that helps a bit.