Alex Stevens
Alex Stevens

Reputation: 43

Silent Refresh Still Works After AccessToken Expiry

I've got an ID4 authentication server working well with an Angular app that is implementing angular-oauth2-oidc with SilentRefresh and a PCKE Authorisation flow.

Everything is working great - the ID4 is configured to serve AccessTokens with a 5 minute lifetime and the Angular app will silently refresh the token every minute (will likely change to refresh with 0.75 time elapsed). The problem I am finding however, is that I can close the browser having logged in - then open it again on the site 10 minutes later (after the original AccessToken has expired without being refreshed) - however the Silent Refresh kicks in a refreshes the token and the user remains logged in. This is a significant security hole.

My client side configuration looks like this:

{
    issuer: config.authServerUrl,
    clientId: '<redacted>', // The "Auth Code + PKCE" client
    responseType: 'code',
    redirectUri: window.location.origin,
    silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
    postLogoutRedirectUri: window.location.origin,
    scope: 'openid profile email api',
    useSilentRefresh: true, // Needed for Code Flow to suggest using iframe-based refreshes
    silentRefreshTimeout: 60000, // For faster testing
    sessionChecksEnabled: true,
    showDebugInformation: !config.production, // Also requires enabling "Verbose" level in devtools
    clearHashAfterLogin: false,
    nonceStateSeparator : 'semicolon', // Real semicolon gets mangled by IdentityServer's URI encoding
  }

and My ID4 configuration looks like this:

      {
        "Enabled": true,
        "ClientId": "<redacted>",
        "ClientName": "<redacted>",
        "ClientSecrets": [ { "Value": "<redacted>" } ],
        "AccessTokenLifetime": "300",
        "AllowedGrantTypes": [ "authorization_code" ],
        "AllowedScopes": [ "openid", "profile", "email", "api" ],
        "AllowedCorsOrigins": [
          "http://localhost:4200"
        ],
        "PostLogoutRedirectUris": [
          "http://localhost:4200"
        ],
        "RedirectUris": [
          "http://localhost:4200",
          "http://localhost:4200/silent-refresh.html"
        ]
      }

I would like the behaviour to be that the silent refresh will only work if I open the browser again on the site, within the AccessToken's expiry time - i.e if I open after the AccessToken has expired - then I can't refresh and need to log in.

It seems that the Silent Refresh doesn't use RefreshTokens as the scopes presented on login don't include offline_access and I don't have AllowOfflineAccess set to true on the ID4 side. Are refresh tokens being used here - is the configuration implied in some way - if so, why can you allow a RefreshTokens lifetime to be longer than the AccessTokens?

Upvotes: 1

Views: 2707

Answers (1)

Tore Nestenius
Tore Nestenius

Reputation: 19901

One thought is that your IdentityServer sets its own "session" cookie during your initial login and that one is used allow the application to silently reauthenticate and get a new access token. You can tweak the lifetime of this cookie from IdentityServer.

I would verify this behaviour using a proxy like Fiddler.

Upvotes: 1

Related Questions