3

In my current architecture I have an authentication server which provides a JWT token via OpenID Connect to any web application that uses the code flow I implemented.

I went to the hassle of implementing OpenID Connect (mainly thanks to authlib) to let the authenticated web applications being stateless. It also allows me to make requests between apps without reauthenticating users, by passing my JWT around. Thats very handy...

Now I am facing the following problem : If one of the said web application wanted to refresh their token instead of going through the whole code flow again, they would need to store a refresh token somewhere in the backend, where it is secured.

Sadly this would break the stateless authentication I was looking for, which forces me to mount some sort database on each one of my web applications that initially didn't need any.

Is there a way to refresh a JWT in a stateless way ? Or, to rephrase my question, where can I store my refresh token in a stateless application ?

5
  • I've seen this answer that talks about a user session directly in the auth server instead of the web app. Then the app would invoke an iframe that would reconnect the user once his token gets invalid. This requires the implicit grant flow but that's not a problem. security.stackexchange.com/questions/144099/…
    – Leogout
    Jan 23, 2020 at 18:31
  • There is this library that allows a client to keep the refresh token on the client side, claiming (and I quote) While the original standard DOES NOT allow this for SPAs, the mentioned document proposes to ease this limitation. github.com/manfredsteyer/angular-oauth2-oidc
    – Leogout
    Jan 23, 2020 at 19:38
  • I came across this answer which states that an HttpOnly cookie storage would be ok to store a refresh token. That's what I'm heading towards if no one answers me during next week. Thank you all for reading. stackoverflow.com/questions/40309682/…
    – Leogout
    Jan 23, 2020 at 19:59
  • You're quoting authlib which is a flask lib, so your apps are either built using flask directly or are mobile apps/single page applications with Flask used as a ressource server using an API. Which one is it? Because in one case, the relying party would be the flask servers themselves, while in the other case it will be mobile/spa and that changes a lot the whole logic. By the way do you use a PKCE or classical code flow? Jan 28, 2020 at 16:08
  • Thanks for your comment, they are server-side APIs (flask) which are consumed by SPAs (angular) in a browser.
    – Leogout
    Jan 29, 2020 at 6:22

1 Answer 1

5

Put is simply the answer is "Don't use the refresh token" because it's not how the system is supposed to work when you're having SPA, apis and an identity provider. The documentation is a little bit confusing on this point because it has been designed a long time ago, before SPA were dominant. The main issue is that, at first, you probably considered the api servers as the relying parties and the angular application as just "front". At least it was the problem that I had. And it's simply not the case.

The key point here are that:

  • Your SPA is the relying party, not the flask APIs server.
  • Your APIs only need to validate the JWT token, not to take part in the authentication flow or get access to refresh tokens etc.
  • Your SPA doesn't need to obtain/use refresh token as those are mainly use by more "controlled" type of services. Instead openid connect includes an iframe logic in its specs, allowing the RP to get new access and id tokens when the current access token is close to the validation end date time.

The next question is which authorisation grant flow you should use ? The answer is PKCE. You don't want to use implicit because there are known security breaches. You can't use classical code flow because you'll need to put the client secret in the angular app. Luckily that's exactly why PKCE has been created: https://www.rfc-editor.org/rfc/rfc7636

And to implement that you'll need 2 things:

Once you're there, the system will probably suit your needs:

  • Long run authentication is handled by the IP, and as long as the user is logged in at the ip level, the iframe will ensure that his access/id tokens are up-to-date.
  • API servers are stateless and don't require a database.
1
  • Thanks for your reply, I went with a session based auth for the time being. I stumbled upon the implicit flow + iframe system and thought that it was not the answer... I wasn't aware of the PKCE flow. It perfectly fits my needs, thanks !
    – Leogout
    Jan 31, 2020 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .