2

I'm implementing an API gateway using micronaut. One of the gateway's responsibility it to handle user authentication. I want to use external IdP to authenticate users and then propagate JWT token to downstream services. I don't want micronaut to generate its own token, I want the token generated by IdP to be used instead.

The security configuration of my gateway service is similar to the described here: https://guides.micronaut.io/latest/micronaut-oauth2-okta-gradle-java.html

In short:

  security:
    authentication: idtoken 
    oauth2:
      clients:
        provider: 
          client-secret: '${OAUTH_CLIENT_SECRET:yyy}' 
          client-id: '${OAUTH_CLIENT_ID:xxx}' 
          openid:
            issuer: '${OIDC_ISSUER_DOMAIN}/oauth2' 
    endpoints:
      logout:
        get-allowed: true 

After successful authentication I get JWT as a cookie and can use it to authorize my requests. Everything works as a charm until now.

The tokens issued by IdP have short validity period and that's the expected behavior. I want to lifespan of JWT to be short and to get new ones using refresh tokens. I'm looking for a way to implement refresh token flow in micronaut.

The perfect solution would be the following:

  • both JWT and refresh token are returned after successful authentication as cookies,
  • if gateway gets the request with expired JWT it automatically gets new one using refresh token,
  • new JWT (and new refresh token if issued) are set as cookies.

The first question is how to configure micronaut to return the refresh token to the caller (like it return JWTs). It's possible to return refresh token generated by micronaut (for example in a cookie), but I didn't find a way to get the refresh token generate by external IdP.

The second question is whether it's possible to configure micronaut to execute the full refresh token flow automatically (it seems like a quite standard problem). Or maybe there is another library that can be used to achieve that goal?

I'll be grateful for any suggestions.

lutato
  • 21
  • 1
  • 2
  • Have you seen this page? https://guides.micronaut.io/latest/micronaut-security-jwt-gradle-kotlin.html#issuing-a-refresh-token – Tore Nestenius Dec 01 '21 at 10:58
  • Thanks @ToreNestenius for the suggestion, but I don't think this is related to my problem. I don't want micronaut to generate its own refresh token (or even access token), I want it to provide (and preferably even handle) refresh tokens generated by the external IdP. – lutato Dec 01 '21 at 11:46
  • The first step is to get a refresh token at the same as the access token is returned, and you ask for that using the offline_access scope, does that work? – Tore Nestenius Dec 01 '21 at 12:05
  • A refresh token is returned from IdP to micronaut application (acting as API GW) along with access token and JWT. But then the refresh token is ignored by micronaut (in contrary to the JWT, which is returned to the caller as a cookie) – lutato Dec 01 '21 at 12:47
  • 1
    The refresh token should never be returned back to the browser, as this is a very sensitive piece of data, you should keep it in the backend. Preferable the access token should also not be sent to the browser. – Tore Nestenius Dec 01 '21 at 12:49
  • I tend to disagree. I want the API GW (backend) to remain stateless and the user's browser is the only place to store tokens. Refresh token is far less sensitive than JWT - it doesn't get access to any resources, can be invalidated (and JWT cannot) and can be used to request new access token (or JWT) only via back-channel (by providing client credentials). Anyway, we are getting away from the original question, which is about micronaut implementation. – lutato Dec 01 '21 at 14:45
  • If you want to store them in the cookie (as many frameworks including ASP.NET Core) does it, then you need to properly encrypt it before you store them in the cookie. – Tore Nestenius Dec 01 '21 at 14:49

0 Answers0