2 Replies Latest reply on Dec 16, 2014 5:55 PM by lionelve

    IDP-initiated logout leaves SAMLResponse in the session

    lionelve

      Picketling 2.7.0.CR2 on JBoss EAP 6.3.0.

       

      I can't say that this is breaking anything yet but there is a SAMLResponse being left hanging around in the session.

       

      Using developer quickstarts (https://github.com/jboss-developer/jboss-picketlink-quickstarts).

       

      1. Deploy picketlink-federation-saml-idp-with-signature (PicketLink Identity Provider With Signature)
      2. Deploy picketlink-federation-saml-sp-post-with-signature (PicketLink Service Provider With a Basic Configuration using SAML HTTP POST Binding With Signature Support)
      3. Access the SP at http://localhost:8080/sales-post-sig and login
      4. Start a GLO from the IDP by going to http://localhost:8080/idp-sig/?GLO=true

       

      Upon receiving the LogoutResponse from the SP, the SAML2LogoutHandler generates a Success Status Response that it will send to the original issuer which in this case is itself.

       

      //SAML2LogoutHandler.java Line 205
      generateSuccessStatusResponseType(statusResponseType.getInResponseTo(), request, response, relayState);
      


      It then invalidates the session

       

      //SAML2LogoutHandler.java Line 221
      httpSession.invalidate(); // We are done with the logout interaction
      

       

      So at this point the IDP has effectively logged out but it is going to send a Success Status Response to itself.

       

      When it goes to handle that Success Status Response it populates the session with the SAMLResponse.

       

      //AbstractIDPValve.java Line 373
      populateSessionWithSAMLParameters(request);
      

       

      And then does nothing with it since the user is no longer authenticated.

       

      //AbstractIDPValve.java Line 395
      // we only handle SAML messages for authenticated users.
      if (userPrincipal != null) {
           if (isGlobalLogout(request) && request.getParameter(SAML_REQUEST_KEY) == null) {   
                prepareLocalGlobalLogoutRequest(request, userPrincipal);
         }
      
        handleSAMLMessage(request, response);
      }
      

       

      There. We have an orphan SAMLReponse in the session.

       

      Now if you log back in the SAMLResponse is still floating around waiting to cause trouble. I believe it is only by chance that it doesn't.

       

      For example if you log back into the SP this adds a SAMLRequest to the session and it just so happens that the IDP picks it up instead of the SAMLResponse.

       

      //AbstractIDPValve.java Line 490
      if (isNotNull(samlRequestMessage)) {
        processSAMLRequestMessage(request, response, null, isGlobalLogout(request));
      } else if (isNotNull(samlResponseMessage)) {
        processSAMLResponseMessage(request, response);
      } else if (request.getRequestURI().equals(request.getContextPath() + "/")) {
         // no SAML processing and the request is asking for /.
         forwardHosted(request, response);
      }
      
      

      If the order of this if/else if were swapped the IDP would handle the orphan SAMLResponse and ignore the SAMLRequest.

       

      Even though it doesn't seem to be breaking anything at this point it feels like a big code smell that this SAMLResponse is being left behind.

        • 1. Re: IDP-initiated logout leaves SAMLResponse in the session
          pcraveiro

          Hey Lionel,

           

              Good point. But like you said, I don't think that will bring any issue because requests are always processed first than responses. However, I'm not sure if we really need to store the response in session like we do, but only requests. Something to review and try to improve.

           

          Regards.

          • 2. Re: IDP-initiated logout leaves SAMLResponse in the session
            lionelve

            It's a bit different if you log back into the IDP directly after the GLO.

             

            In this case there is no SAMLRequest added to the session so the orphan SAMLResponse is handled.

             

            Luckily the SAML2LogoutHandler then ignores it.

             

            //SAML2LogoutHandler.java Line 161
            if (statusIssuer.equals(getProviderconfig().getIdentityURL())) {
              response.setDestination(getProviderconfig().getIdentityURL());
              return;
            }
            

             

            The IDP ends up redirecting to itself after which everything flows as normal.