Announcement Announcement Module
Collapse
No announcement yet.
Re-authorization/confirmation after valid token presented Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Re-authorization/confirmation after valid token presented

    I have an unusual workflow wherein I sometimes need to re-authorize a client even though the client has a valid token by presenting the user/resource-owner with the final authorization/confirmation page (but not the authentication pages) again after receiving the (valid) request from the client which includes a valid token.

    I was thinking I could implement this by using two different 'types' of AccessTokens -- one which provides access normally, and one which requires re-authorization but even with this, I am not sure how to effect the redirect, as the OAuth2AuthenticationProcessingFilter doesn't have a way to forward/redirect the user-agent to the confirmation page (it doesn't even know about the confirmation page which is part of the authentication process).

    My final thought was to add a custom filter which is configured in the secured resource filter chain after the OAuth2AuthenticationProcessingFilter (or extend the OAuth2AuthenticationProcessingFilter) to check the access token type, but I still cannot see how I would get the URL to re-direct the user to the confirmation page (and not sure if that would work if I did anyway).

    I imagine someone may have faced the same requirements. If so, I'd appreciate some direction on how you solved this.

    Thanks,
    Eric

  • #2
    Although on the face of it you have quite an unusual flow, I'm not sure it's all that complicated. Since authentication and authorization are orthogonal, all you really need is to use the incoming token to do authentication on the /oauth/authorize endpoint. So tinkering with OAuth2AuthenticationProcessingFilter seems like the right approach. Whether or not you end up with 2 valid tokens after the flow is up to you (e.g. you can invalidate the incoming one in your authentication filter or not, depending on your needs).

    Comment


    • #3
      Unfortunately I'm still stuck with this.

      The challenge is trying to direct the user to the authorization pag when presented with a valid access token by the user agent. I've tried customizing the OAuth2AuthenticationProcessingFilter to forward the user-agent to the authorization confirmation page, but though the forward seems to be processed correctly, the thread returning back to the OAuth2 client ends up displaying an error anyway (maybe something in the Oauth2 client rest template?).

      The challenge I have is how/where to direct (forward or redirect?) the client to the authorization page when the client requests the secured resource with a valid access token, doing this in the OAuth2AuthenticationProcessingFilter doesn't seem to work.

      Comment


      • #4
        OAuth2AuthenticationProcessingFilter is for authentication and naturally should only redirect if the token is invalid for authentication purposes. Your use case is for user approval/authorization, and the AuthorizationEndpoint is responible for those redirects. You need to use both, in other words. So all you should need to do is send your users to /oauth/oauthorize and include a token in the headers for authentication. Where that token comes from is a bigger problem (it seems to me), but you seem to have solved that one already.

        Comment


        • #5
          Thanks Dave.
          That's pretty much which I'm trying to do. The problem I see is that the request for the secured resource is made from the RestTemplate from the client which doesn't handle a redirect from the Authorization Endpoint. I have modified the OAuth2AuthenticationProcessingFilter such that it forwards the request to the Authorization endpoint (adds the response_type, client_id, and redirect_uri to the request first and forwards to the authorize() method), and the AuthorizationEndpoint successfully forwards the the authorization confirmation page, but upon returning the response to the client, the client throws the following error as it the request was originally called by restTemplate.getForObject(...);

          Could not extract response: no suitable HttpMessageConverter found for response type [java.lang.Object] and content type [text/html;charset=ISO-8859-1]
          org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:894)
          Last edited by strykker; Apr 26th, 2013, 09:27 AM.

          Comment


          • #6
            If you are using Spring OAuth as a client it had better be an OAuth2RestTemplate and you had better have the <oauth:client/> filter in place to handle the redirects. Other clients would have similar features. On the server side you shouldn't have to modify any code - just make sure the OAuth2AuthenticationProcessingFilter is protecting the authorization endpoint.

            Comment


            • #7
              I have been using the <oauth:client/> and OAuth2RestTemplate, but that seems to be what causes the problem.
              Perhaps there's some confusion on my part that you can help clarify. The challenge that I am facing now, is that once the OAuth2 client has successfully obtained a token, it will attempt to call the secure service method (access the secured resource), and present that token.. this appear to be typically accomplished by calling one of the OAuth2RestTemplate.getForObject(...) methods.

              However, in my flow, even with a valid token, I sometimes still need to redirect/forward the user-agent to authorization page, which I appear to be doing successfully on the server side. However, because the client attempted to access the secured resource using OAuth2RestTemplate.getForObject(...), irrespective of the response from the server (the server forwarded request to the authorization page), the client still simply tries to extract an object from the response and continue with it's own page flow rather than displaying the page processed by the server.

              Perhaps the problem is now with how my client is implemented, but I can't find any methods on the OAuth2RestTemplate API which will allow me to do what I want -- i.e. allow the server to force displaying the authorization page as the result of a token0secured request from the client for a secured resource

              Comment


              • #8
                That makes things a little clearer, thanks. How do you know, for a given request on the server, whether or not you need confirmation? Is the decision made on the client or the auth server? Since you are asking for client side APIs I assume the former. If so you would need to clear the OAuth2ClientContext (e.g. by creating a new OAuth2RestTemplate) and obtain a new token. Would that work?

                Comment


                • #9
                  The decision is made on the auth server. There is an authentication parameter persisted with the userAuthentication which is set upon initial authentication which determines whether a re-authorization step should be executed despite the presence of a valid access token. So the server is attempting to forward the client request to the authorization confirm page, but as I described above, the client request is being processed for the content of the response and can't display a page. I'm wondering if there is some kind of exception (RdirectRequiredException?) or such that the server can throw which would inform the client to process another redirect to the authorization page rather than process the response for a result?

                  BTW, what is the latest valid version of the OAuth2 APIs? --- I was using 1.0.0.RC3 and tried switching to 1.0.2.RELEASE but some changes in 1.0.2.RELEASE of how the OAuth2ClientContextFilter is used is no longer setting the request parameters to the currentUri when calculating the currentUri
                  Last edited by strykker; Apr 30th, 2013, 02:19 AM.

                  Comment


                  • #10
                    All you should need to do in theory is throw InvalidTokenException. The client should interpret that as an invitation to get a new token. Normally that would mean trying to use a refresh token if there is one, so you might need to sacrifice the refresh token feature at least in the short term. If it doesn't work I'm happy to look at changing something because the client should respond to 401 and the WWW-Authenticate header (I assume other clients do).

                    1.0.5.RELEASE is in staging, and you really ought not to be using an RC*. Can you identify the change that broke your client?

                    Comment


                    • #11
                      Thanks Dave.

                      The change that broke my code was the change to OAuth2ClientContextFilter.calculateCurrentUri(). In 1.0.0.RC3 it used to add request parameters to the currentUri. In 1.0.2.RELEASE it doesn't.

                      Throwing an InvalidTokenException from the my customized OAuth2AuthenticationProcessingFilter sort of works. The client interprets that as an instruction to request authorization again and redirects to the /authorize Uri. The only problem is that I don't want the user to have to re-authenticate again. i.e. I would like the client to still pass me the valid access token so that I can authentication the user using the access token without taking the user through the authentication process and then simply present the client with the approval page. However, the client interprets the InvalidTokenException as it should and makes a brand new authorization request without the access token (as well it should, I suppose). What I really need is something in-between a normal authorization request and an access request for a secured resource, wherein the client makes an authorization request (for approval) but passes an existing access token.

                      I'm beginning to suspect that the flow I want may be outside of the specification as it requires the client to understand an "authenticated but not approved" state, which isn't per the spec.

                      Another small issue I ran into is that if I do successfully send the client to the approval page, once they approve, I need to store something in the session to flag that they have been approved so that when the OAuth2AuthenticationProcessingFilter intercepts the subsequent request for the secured resource, it knows that the client (which normally requires this re-approval) has just been approved -- and let's it through. There's currently no way for me to extend the AuthorizationEndpoint.approveOrDeny() method in order to add something to the session upon approval. This would be useful...

                      BTW, the site I saw referenced listing the maven resources only shows up to 1.0.0.RC3:
                      http://shrub.appspot.com/maven.sprin...curity-oauth2/. Where should I be to determine the latest release versions?

                      Comment


                      • #12
                        Originally posted by strykker View Post
                        BTW, the site I saw referenced listing the maven resources only shows up to 1.0.0.RC3:
                        http://shrub.appspot.com/maven.sprin...curity-oauth2/. Where should I be to determine the latest release versions?
                        Maven Central is browseable, or if you like shrub you need to look in the releases bucket: http://shrub.appspot.com/maven.sprin...curity-oauth2/. I'll have a think about the other stuff...

                        Comment


                        • #13
                          Hi Dave,
                          Have you had a chance to think about this any further? My present thinking is that I define a non-standard flow for which compliant clients will need to handle a custom response error code for which they will redirect to the authorization URI, but include the access token. I would then implement my auth filter / endpoint to handle this special case and present the authorization confirmation page.

                          Comment


                          • #14
                            I did think about it some, but not enough to really come up with a concrete suggestion. One thing I'm not sure I understand: your client has to send the user to the authorization page using a redirect, but then how does the access token get included (the only way I could think of was in the query parameters, but that's really not a great idea from a token security point of view.

                            Comment

                            Working...
                            X