Announcement Announcement Module
No announcement yet.
Redirecting to original (unauthenticated page) after spring security openid authentic Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Redirecting to original (unauthenticated page) after spring security openid authentic

    I have implemented spring security openid integration using the sample available here:

    The integration works fine. When I request a protected resource I get redirected to a login page and after authentication I'm automagically redirected to the protected resource.

    However, if I am on an unprotected page ( similar to the situation described here: ) and I click on the login button..I get redirected to the homepage after login. I would like to be redirected to the page where I clicked the login button from.

    The spring forum thread suggests overriding the buildReturnToUrl method. I have debugged thru it. It always generates a returnToURL of the form:

    There was some behind the scene communication between op and Rob Winch and I'm not sure how op actually overwrote it.

    Alternatively, I have tried to create another filter with code like this:

    public void doFilter(....) {
    DefaultSavedRequest savedRequest = new DefaultSavedRequest((HttpServletRequest) request, new PortResolverImpl());
    ((HttpServletRequest)request).getSession().setAttribute("SPRING_SECURITY_SAVED_REQUEST", savedRequest);
    If this filter runs before the OpenIDAuthenticationFilter then the savedrequest is removed by RequestCacheAwareFilter ( probably because of this issue:

    If this filter runs after OpenIDAuthenticationFilter then I do run into the issue where post parameters get concatenated after each request.

    Can someone point out the right way forward on this?

  • #2

    A month has passed and there is no response. Can someone on the spring-security team please take a look? I'm happy to dig thru more code, try more things and come back and post my findings here. But I do need some help. If I overlooked something obvious, I'm happy to take a slap on the hand.



    • #3
      Typically the ExceptionTranslationFilter is what updates the RequestCache when an unauthenticated user accesses a page that requires authentication. This means that public pages are not saved. There is no built in support for remembering the public pages, but it can be done fairly easily by using the RequestCache directly. I have outlined the steps below:

      Create a Filter that will save unauthenticated requests in the RequestCache which may look something like this:

      public class UpateSavedRequestFilter extends OncePerRequestFilter {
          private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
          private RequestCache requestCache = new HttpSessionRequestCache();
          private RequestMatcher requestMatcher = new AntPathRequestMatcher("/**/*.jsp");
          protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                  throws ServletException, IOException {
              Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
              if(requestMatcher.matches(request) && trustResolver.isAnonymous(authentication)) {
                  requestCache.saveRequest(request, response);
              filterChain.doFilter(request, response);
      • The point of the RequestMatcher is to ensure that your images, javascript, and css are not saved. Obviously you may need to update this depending on your application.
      • There is an instance of RequestMatcher on the HttpSessionRequestMatcher that could be used instead of having an instance on the Filter (assuming you are using HttpSessionRequestFilter)
      • You may want to inject the members rather than hard coding (I did this for simplicity)
      • The trustResolver ensures that once you are authenticated it does not continue saving the request. This logic could be embedded into a custom RequestMatcher to make it more architecturally sound but for simplicity I just placed in the Filter.

      Next insert the custom filter in your security configuration after the FILTER_SECURITY_INTERCEPTOR. As with all of the Spring Security Filter's the order is important. An example configuration is given below.

      <http ...>
          <custom-filter ref="usrFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
      One thing to keep in mind about this approach is that unauthenticated users will be updating the HttpSession on each page request. This will likely not have a problem, but in a clustered environment where the clusters are synchronizing the Session across the cluster you may need to tune it a bit. If it causes a lot of problems, you can probably just ignore the SPRING_SECURITY_SAVED_REQUEST attribute (i.e. don't replicate it). You will need to refer to your server configuration on how to do this, but for Tomcat you can use the CusterManagement documentation. In the event of a failure, your user will simply go to the default target url (defaults to context root) instead.

      I should note that there are other approaches like passing a parameter around on the URLs, but this is risky since it can lead to Unvalidated Redirects.



      • #4
        Many many thanks for the response. I can confirm that this works. I had tried something like this but didn't think of trustResolver.isAnonymous(authentication) part. I should have though.

        We will be deploying our application in a cluster so thanks for pointing out the pitfall.

        I was away for a while and couldn't look at it immediately. Sorry.