Spring boot OIDC Refresh token scenario

Viewed 850

We are currently working on application having micro-service architecture with following components as shown in below image and everything is working fine.However need some clarification on following points.

  1. To secure communication between Gateway and Deep microservice we are passing IDToken and validating it at each microservice level however once IDtoken expires service returns 401 status code and then on Ui we trigger authorization flow which eventually results in full page refresh and if user in middle of submitting very large form then all the data will be lost moroever as per OIDC specificition we can't refresh ID token so not sure how to handle this scenario.
  2. To overcome first problem we could pass access_token to microservice rather than idtoken however we need to call /userinfo end point each time for getting user information from provider and considering high concurrency is it a good practice to proceed with ?

  3. Or we are missing something here and there are better alternatives to fix this problem ?

Any help would be much appreciated

enter image description here

Spring boot OIDC Properties in application.yml file

security:         
    oauth2:
      client:
        registration: 
          pingIdentity: 
            scope:
            - openid
            - profile
            - email
            - phone
            - job_title
            - scoped_entitlement
            - authorization_group
            - entitlement_group
            - organizational_data
            - basic_start_authorization            
            client-id: <Client  ID>
            client-secret:  <Client  Secret>
            provider: pingIdentity
        provider:
          pingIdentity: 
            issuer-uri: <Issuer URI>
2 Answers

I think there is a problem of concept using open id connect.

Open id connect is not an authentication/authorization protocol as oauth2, it is a layer on top of oauth2 to provide user information to a client.

So the intended audience for the information contained in an idtoken is the application which is trying to consume a resource (frontend) and not the resource server (microservice). As you can see here

https://openid.net/specs/openid-connect-core-1_0.html

The token that must be send to the microservice is the access token that is issued along with the idtoken, because this is the token that must be used to authorize the action.

Other problem is that you may need user information to perform some action in the service but this is not part of the same flow.

The authentication/authorization flow only assures that one user is valid and has privileges to do certain action on certain resource server(microservice)

If then, when the auth proceess has ended, you need to obtain user information, I suggest you three possible solutions:

  1. you can use a jwt token (self encoded access token) as access token instead of an opaque one, so you can obtain the user id in sub claim, and with that, query the user service to obtain the other information.

  2. Like the point one, you can use jwt acces token and in addition add custom claims to store additional user information

  3. if you are doing the acces token validation in zuul gateway, you can get user information in the gateway and pass a custom jwt to the microservices with the info you need. This token does not need to be an access token because the authentication/authorization operation has been done by the gateway.

This way you can refresh your access tokens without problem

I think your key issue is token getting expired without any control from the user.

You may consider following options.

  1. Keep a recurring task in your SPA which will check current time with the expiration time of the IDToken. When the token is about to expire (Say in less than 5 minutes), SPA would prompt a small dialog and ask the user to input her credentials. Once the form is submitted, the new token will be received and replaced in the session/local storage or cookie.

    This way when the user submits the form, it will be with the new token.

    This will not need any additional service than current ones and you just need additional function in the SPA.

    Downside of this is, user has to enter the password again.

  2. If you can define another service to receive the refersh_token along with the IDToken and store it, then the SPA can keep sending heartbeat requests at regular interval. The request can be sent while the page is in focus by the user/or user is interacting with the page locally. (e.g. can be sent every 5 minutes on mouse moved/scrolled etc.).

    The backend service will check if the token is about to expire, then it will use refresh token to get the new token and then pass it to SPA. SPA will update the token for subsequent requests at its end. All this will happen in the background without disturbing the user as long as she is working on the page.

    You will have to deal with additional complexity in exchange of user convenience.

Related