I'm trying to use the angular-oauth2-oidc
Silent Refresh implementation in combination with the implicit flow configured in an IdentityServer4 server. I've got a proof of concept working inside an ng new ng-and-ids4 --minimal
application with this component:
import { Component } from '@angular/core';
import { AuthConfig, OAuthService, JwksValidationHandler, OAuthErrorEvent } from 'angular-oauth2-oidc';
@Component({
selector: 'app-root',
template: `<h1>Welcome!</h1>
<p>
<button (click)='login()'>login</button>
<button (click)='logout()'>logout</button>
<button (click)='refresh()'>refresh</button>
</p>
<h2>Your Claims:</h2><pre>{{claims | json}}</pre>
<h2>Your access token:</h2><p><code>{{accessToken}}</code></p>`,
styles: []
})
export class AppComponent {
constructor(public oauthService: OAuthService) {
this.oauthService.configure({
issuer: 'http://localhost:5000',
redirectUri: window.location.origin + '/',
silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
clientId: 'my-spa',
scope: 'openid profile',
silentRefreshTimeout: 5000, // For faster testing
sessionChecksEnabled: true,
});
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.loadDiscoveryDocumentAndLogin();
this.oauthService.setupAutomaticSilentRefresh();
this.oauthService.events.subscribe(e => {
if (e instanceof OAuthErrorEvent) { console.error(e); }
else { console.warn(e) }
});
}
public get claims() { return this.oauthService.getIdentityClaims(); }
public get accessToken() { return this.oauthService.getAccessToken(); }
login() { this.oauthService.initImplicitFlow(); }
logout() { this.oauthService.logOut(); }
refresh() { this.oauthService.silentRefresh(); }
}
On the IDServer4 side I'm configuring my client like this:
new Client
{
ClientId = "my-spa",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 30, // Seconds (for testing purposes)
RedirectUris = { "http://localhost:4200/", "http://localhost:4200/silent-refresh.html" },
PostLogoutRedirectUris = { "http://localhost:4200/" },
AllowedCorsOrigins = { "http://localhost:4200" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
}
}
As you can see, on the server I've whitelisted "http://localhost:4200/silent-refresh.html"
in the Client
's RedirectUris
property.
My question is whether you can configure angular-oauth2-oidc
in a way that it doesn't require me to whitelist the silent-refresh.html
page?
The reason I ask is because I want to use this Silent Refresh approach also in situations where it might not be so easy to change the IdentityServer side. Also, looking at Damien Bod's example of Silent Refresh in an Angular application I feel it should somehow be possible, because there such a whitelisting is not mentioned.
PS. If I don't include the extra option for the RedirectUris
, then I get Invalid redirect_uri: http://localhost:4200/silent-refresh.html
on the server (logs) and a silent_refresh_timeout
OAuthErrorEvent
in the client side library.