<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    Hello,<br>
    <br>
    Our current environment is running IdP v5.1.3 with the following
    OIDC plugins:<br>
    <br>
    - oidc.op (v4.2.0)<br>
    - oidc.common (v3.2.0)<br>
    - oidc.config (v2.2.0)<br>
    <div class="moz-signature"><br>
      We're experiencing an issue with an OIDC RP (configured with
      response_types: "code", scope: "openid offline_access", and
      grant_types: "authorization_code","refresh_token").  After
      authentication, the RP successfully receives the expected access,
      ID, and refresh tokens, and the end-user is able to get into the
      application without any problems.  The access token is set to
      expire in 10 minutes:<br>
      <br>
      2024-12-03 22:06:03,118 - DEBUG [PROTOCOL_MESSAGE.OAUTH2:135]
      - [RP Client IP] - OIDCTokenResponse{customParameters={},
      tokens={"access_token":"*****","refresh_token":"*****","scope":"openid
offline_access","id_token":"*****","token_type":"Bearer","expires_in":600}}<br>
      <br>
      <br>
      However, after the 10 minutes has passed and an action is taken
      inside the app, the RP attempts to use the refresh token to get a
      new access token to maintain its login session, but is unable to
      do so, leading to the end-user getting forcibly logged out of the
      RP and potentially losing their work.  Of course, the end-user is
      able to easily get back into the app by going through the cached
      authentication process again (and receiving new tokens), but after
      another 10 minutes, the same issue occurs.  So, as you can
      imagine, this cyclic behavior is rather disruptive to the
      end-users.<br>
      <br>
      The RP reports that they receive an "Unauthorized client" error
      message when trying to get a new access token using the refresh
      token, but we still see the inbound request containing the refresh
      token:<br>
      <br>
      2024-12-03 22:17:00,253 - DEBUG [PROTOCOL_MESSAGE.OAUTH2:114] -
      [RP Client IP] -
OIDCTokenRequestDecoder{authorizationGrant=RefreshTokenGrant{refreshToken=RefreshToken{parameterNames=[refresh_token],
      value=*****}, type=refresh_token},
      clientAuthentication=ClientAuthentication{clientId=*****,
      method=client_secret_basic}, customParameters={},
      endpointURI=https://[test IdP URL]/idp/profile/oidc/token,
      scope=offline_access openid}<br>
      <br>
      <br>
      However, we don't see anything obvious in our logs indicating a
      failure when exchanging a refresh token for a new access
      token...except for perhaps these?<br>
      <br>
      2024-12-03 22:17:00,255 - DEBUG
[net.shibboleth.idp.saml.profile.impl.InitializeAuthenticationContext:226]
      - [RP Client IP] - Profile Action InitializeAuthenticationContext:
      Created authentication context:
      AuthenticationContext{initiationInstant=*****, isPassive=false,
      forceAuthn=false, requiredName=null, hintedName=null, maxAge=null,
      potentialFlows=[], activeResults=[], attemptedFlow=null,
      signaledFlowId=null, authenticationStateMap={},
      resultCacheable=true, authenticationResult=null,
      completionInstant=null}<br>
      2024-12-03 22:17:00,257 - DEBUG
      [net.shibboleth.idp.authn.impl.InitializeRequestedPrincipalContext:146]
      - [RP Client IP] - Profile Action
      InitializeRequestedPrincipalContext: Profile configuration did not
      supply any default authentication methods<br>
      <br>
      <br>
      Eventually, we see this:<br>
      <br>
      2024-12-03 22:17:00,262 - DEBUG
[net.shibboleth.idp.plugin.oidc.op.authn.impl.OIDCClientInfoCredentialValidator:154]
      - [RP Client IP] - Credential Validator oauth2-clientinfo:
      Attempting to authenticate effective client ID '****' <br>
      2024-12-03 22:17:00,262 - INFO
[net.shibboleth.idp.plugin.oidc.op.authn.impl.OIDCClientInfoCredentialValidator:163]
      - [RP Client IP] - Credential Validator oauth2-clientinfo: Login
      by '[client ID]' succeeded<br>
      2024-12-03 22:17:00,265 - DEBUG
      [net.shibboleth.idp.authn.impl.FinalizeAuthentication:114] - [RP
      Client IP] - Profile Action FinalizeAuthentication: Canonical
      principal name was established as '[client ID]'<br>
      2024-12-03 22:17:00,265 - DEBUG
      [net.shibboleth.idp.authn.impl.FinalizeAuthentication:175] - [RP
      Client IP] - Profile Action FinalizeAuthentication: Request did
      not have explicit authentication requirements, result is accepted<br>
      2024-12-03 22:17:00,265 - INFO
      [net.shibboleth.idp.authn.impl.FinalizeAuthentication:201] - [RP
      Client IP] - Profile Action FinalizeAuthentication: Principal
      [client ID] authenticated<br>
      2024-12-03 22:17:00,265 - DEBUG
[net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy:124]
      - [RP Client IP] - Profile Action ValidateClientIDAgainstPolicy:
      OIDC metadata context is populated: client ID has already been
      validated against metadata<br>
      2024-12-03 22:17:00,266 - DEBUG
      [net.shibboleth.idp.plugin.oidc.op.profile.impl.ValidateGrant:270]
      - [RP Client IP] - Profile Action ValidateGrant: Validating grant
      type: refresh_token<br>
      2024-12-03 22:17:00,268 - DEBUG
[net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeSubjectContext:73]
      - [RP Client IP] - Profile Action InitializeSubjectContext:
      Created subject context for principal '[user principal]'<br>
      <br>
      and then the new tokens get successfully generated and sent back
      to the RP, but at the cost of first having been forcibly logged
      out of the OIDC app.  After another 10 minutes, the same issue as
      above happens all over again.<br>
      <br>
      Is there something that we missed in the Shib/OIDC configuration
      that needs to be specifically enabled/tweaked to allow the refresh
      token exchange for the access token, or is this flow already
      working as expected on our end?  Has anyone else ever run into a
      similar issue?  It's just not clear to us whether this issue the
      RP is reporting is something on our end or theirs.<br>
      <br>
      <br>
      Thanks,<br>
      Gabor<br>
      <br>
    </div>
  </body>
</html>