Spring Social
  1. Spring Social
  2. SOCIAL-328

Filter to automatically handle invalid tokens

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: None
    • Fix Version/s: 1.1.0.M3
    • Component/s: None
    • Labels:
      None

      Description

      Based on the discussion at https://github.com/SpringSource/spring-social/pull/57#issuecomment-5659060.

      I've done another sweep of tests and confirmed that the initial token granted to the server side is a long-lived 60-day token. I've also confirmed that calling the aforementioned endpoint with that token does nothing to extend the life of it. (Of course, I really should try again tomorrow to be certain that I'm not just hitting the once-per-day rule...but I have confirmed this in the past.)

      It seems that no matter how you end up with a long-lived token (client or server), you're going to need to freshen it up before the 60 days is up and the only way to do that is to go through the authorization flow again (because you can only extend the life of short-lived tokens, not long-lived tokens). Fortunately, this doesn't bother the user because as long as the user has not revoked access, the authorization will still be good and Facebook will immediately redirect back to the app with a new authorization code to exchange for a fresh new access token.

      Therefore, whether the token has expired or not, the only way to get a fresh long-lived token after the initial long-lived token (as I understand it) is to go through the authorization flow again.

      So, one approach is for you to purposefully take the user through the authorization flow when they first come to your app on a given day and replace the existing connection with the new connection data. Or, you could wait until an ExpiredAuthorizationException is thrown and go through the process then. (Actually, it might be good to do this for any NotAuthorizedException.)

      At the moment, there's no support for either case in Spring Social. But here's how it might work (none of this is confirmed...just some sketchings I made):

      For the once-per-day case, you could have a servlet filter or Spring MVC interceptor that checks to see when the last refresh was performed and if it hasn't been done yet for that day, store away the original request, take the user through the authorization flow (replacing the existing connection, if any), then bring them back and re-issue the original request.
      For the NotAuthorizedException/ExpiredAuthorizationException case (which, btw, would be useful for more than just Facebook), you could have the same filter or interceptor catch the exception, stores away the current request, goes through the authorization flow (replacing the existing connection, if any), then reissues the original request.
      These descriptions are purposefully brief so as not to get lost in the details of what should happen. I'm certain that gotchas will be encountered that I haven't thought of.

      One potential gotcha is dealing with the transactionality of the original request. Spring's transaction support should rollback anything that can be rolled back when a runtime exception is thrown, but what about non-transactional work that may have been done prior to the exception being thrown? Say, if a tweet was posted to Twitter and then an attempt to post to a person's Facebook wall is met with a NotAuthorizedException...how would that be handled? (Truth is, that's a problem right now and not only with Spring Social, but with any app that could perform non-transactional work before a transaction-killing exception is thrown.)

        Activity

        Hide
        marc schipperheyn added a comment -

        Great!

        Show
        marc schipperheyn added a comment - Great!
        Hide
        Claudio Pomo added a comment -

        In spring-social-showcase-xml how I configure this feature?

        Show
        Claudio Pomo added a comment - In spring-social-showcase-xml how I configure this feature?
        Hide
        Craig Walls added a comment -

        The ReconnectFilter can be configured (in JavaConfig) like this:

        @Bean
        public ReconnectFilter apiExceptionHandler() {
        	return new ReconnectFilter(usersConnectionRepository(), userIdSource());
        }
        
        Show
        Craig Walls added a comment - The ReconnectFilter can be configured (in JavaConfig) like this: @Bean public ReconnectFilter apiExceptionHandler() { return new ReconnectFilter(usersConnectionRepository(), userIdSource()); }
        Hide
        Craig Walls added a comment -

        Now that ReconnectFilter is available in 1.1.0.BUILD-SNAPSHOT, I'm closing this issue and inviting the community to try it out. Any bug fixes or improvements stemming from this can be addressed by opening new issues.

        Show
        Craig Walls added a comment - Now that ReconnectFilter is available in 1.1.0.BUILD-SNAPSHOT, I'm closing this issue and inviting the community to try it out. Any bug fixes or improvements stemming from this can be addressed by opening new issues.
        Hide
        marc schipperheyn added a comment - - edited

        I've been playing around with the reconnectfilter and it turns out it's not that easy to get it working.
        For one thing, my general exception handler has dibs on the exception as it takes care of the exception before ReconnectFilter has a chance to get into play.

        I think it might be better if the reconnectfilter would hook into the processHandlerException method of the DispatcherServlet as an ExceptionResolver.

        You can work around this by excluding these kinds of exception from being handled but that just feels a bit hacky.

        Show
        marc schipperheyn added a comment - - edited I've been playing around with the reconnectfilter and it turns out it's not that easy to get it working. For one thing, my general exception handler has dibs on the exception as it takes care of the exception before ReconnectFilter has a chance to get into play. I think it might be better if the reconnectfilter would hook into the processHandlerException method of the DispatcherServlet as an ExceptionResolver. You can work around this by excluding these kinds of exception from being handled but that just feels a bit hacky.

          People

          • Assignee:
            Craig Walls
            Reporter:
            Craig Walls
          • Votes:
            6 Vote for this issue
            Watchers:
            10 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: