Announcement Announcement Module
No announcement yet.
Access Token randomly getting invalid again after refresh? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Access Token randomly getting invalid again after refresh?


    just a short but very strange question. At the moment we are using spring-security-oauth2 (1.0.4) on one of our web services. From time to time I get error reports from the same client developers. What they are seeing is that after the default lifetime of an issued access token (12 hours) if they do a token refresh the new access token is at first valid but shortly after gets invalid (api returns 401 invalid acccess token) again (time difference is supposed to be around 50 seconds from issuance to invalidity). I can't really reproduce this behavior myself, at least not by the use of curl.

    So my question is whether someone experienced in the spring-security-oauth2 code base can think of any circumstances that would lead to this behavior?

    On a further note today I got a new error report from the same client developers that now they even got "invalid refresh token" when trying to do a token refresh. As always there is no sign of any suspicious stuff in our application logs.

  • #2
    I don't know of any issues in recent releases with refresh tokens, and if you can curl the same endpoints and not reproduce the problem it must be a weird one. We use them a bit in production projects I work on but not much, so I'm not sure I'd know for sure. What implementation of TokenStore/TokenServices are you using? Maybe there's a bug in the store implementation that only shows up under load or something? Or maybe you need to be explicit about transactions if you are using a back end store like JDBC, so that token store operations are atomic (you do, but I'd expect to maybe see errors in your logs if that was a problem).


    • #3
      We use DefaultTokenStore (is there even another implementation?) in conclusion with JdbcTokenStore. Actually when I upgraded our application from some RC release of spring-security-oauth2 to 1.0.4-RELEASE I did a quick check whether manually setting transaction isolation to SERIALIZABLE was still necessary with the JdbcTokenStore. As my test results were positive I removed all transaction configuration again. The thing is we use MySQL and it's default transaction isolation happens to be "Repeatable Read". I noticed that other RDBMS default rather to "Read Committed" and I noticed a few rough edges in our application where a lower isolation level would have helped... I'm just not familiar with the db usage pattern that comes out of the JdbcTokenStore. I always thought to replace it with some central key/value store but there hasn't been any time for this endeavor yet.

      Anywho maybe It's worth to reactivate the transaction aspect again and have the client developers see if the problem goes away in the production scenario.

      Thanks for your insight Dave.


      • #4
        So upgrading the transaction isolation apparently hasn't helped with this problem. I think we have a clue though. The last time this was reported two instances of the affected client application were running simultaniously (same client id, same login). What might have happened is that the first client could have done a token refresh and used the newly refresehd token whereas the second client might have done a token refresh some moments later which might have caused the access token of the first client to get invalidated.

        Is this a plausible scenario for such a kind of "refresh race" happening? What would be a good way to get around this? I was thinking of some unique client application IDs that would have to be supplied when initially requesting an access token but I wonder what the cannon OAuth2 way of solving this would be.
        Last edited by a.e; Aug 21st, 2013, 02:40 AM.


        • #5
          That is certainly a plausible scenario for an apparently random invalidated access token. The best way to avoid it would be to make sure access tokens are tied to a single instance of your app (it would be easy and natural if for instance they were simply load-balanced physical instances of the same virtual app - you would only need to use a sticky session cookie to make sure that browser requests go to the same physical instance).