Uploaded image for project: 'OpenAM'
  1. OpenAM
  2. OPENAM-12867

IdP-Proxy - Single Logout fails as LogoutResponse is not signed

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 11.0.0, 11.0.1, 11.0.2, 11.0.3, 12.0.0, 12.0.1, 12.0.2, 12.0.3, 12.0.4, 13.0.0, 13.5.0, 13.5.1, 14.0.0, 14.1.0, 14.1.1, 14.5.0, 14.5.1, 5.5.1
    • Fix Version/s: 13.5.3, 6.0.0.2, 6.5.0, 6.0.1, 5.5.2
    • Component/s: SAML
    • Labels:
    • Environment:
      java version "1.7.0_161"
      Apache Tomcat 8.0.48
      OpenAM 12.0.3
    • Sprint:
      AM Sustaining Sprint 50, AM Sustaining Sprint 51
    • Story Points:
      3
    • Needs backport:
      No
    • Support Ticket IDs:
    • Needs QA verification:
      No
    • Functional tests:
      No
    • Are the reproduction steps defined?:
      Yes and I used the same an in the description

      Description

      Bug description

      SAML SLO flow fails in IdP-Proxy case when response signing is required by upstream IdP

      How to reproduce the issue

      1. Configure OpenAM
      2. Create sub-realm '/sub1'
      3. Configure IdP-Proxy in sub-realm '/sub1' (this is key in reproducing the bug)
      4. Setup some IdP (e.g. OpenAM)
      5. Setup some SP1 (e.g. Spring security SAML sample app)
      6. Setup some SP2 (e.g. Spring security SAML sample app)
      7. Register IdP-Proxy SP at IdP
      8. Register SP2 at IdP
      9. Register IdP-Proxy IdP at SP1
      10. Register IdP at SP2
      11. Register IdP at IdP-Proxy
      12. Register SP1 at IdP-Proxy and configure it for IdP-Proxy
      13. Require Single Logout Response to be signed for IdP-Proxy SP at IdP (this is key in reproducing the bug)
      14. Perform SP-initiated SSO at SP1
      15. Perfom SP-initiated SSO at SP2
      16. Perfom SP-initaited SLO at SP2
      Expected behaviour
      Singe Logout should be successful
      
      Current behaviour
      Single Logout flow fails because the LogoutResponse sent from IdP-Proxy to upstream IdP is not singed
      

       

      Code analysis

      E.g. looking at code of OpenAM 12.0.3

      com.sun.identity.saml2.profile.IDPSingleLogout.java
      ...
      public static boolean processLogoutResponse(
              HttpServletRequest request,
              HttpServletResponse response,
              String samlResponse,
              String relayState) throws SAML2Exception, SessionException {
          String method = "processLogoutResponse : ";
          if (debug.messageEnabled()) {
              debug.message(method + "samlResponse : " + samlResponse);
              debug.message(method + "relayState : " + relayState);
          }
          String rmethod = request.getMethod();
          String binding = SAML2Constants.HTTP_REDIRECT;
          if (rmethod.equals("POST")) {
              binding = SAML2Constants.HTTP_POST;
          }
          String metaAlias =
                  SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI()) ;
          String realm = SAML2Utils.
                  getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
          ...
      
          // IDPProxy
          Map logoutResponseMap = (Map)IDPCache.logoutResponseCache.get(
                  requestId);
          if ((logoutResponseMap != null) && (!logoutResponseMap.isEmpty())) {
              LogoutResponse logoutResp = (LogoutResponse)
                      logoutResponseMap.get("LogoutResponse");
              String location = (String) logoutResponseMap.get("Location");
              String spEntity = (String) logoutResponseMap.get("spEntityID");
              String idpEntity = (String) logoutResponseMap.get("idpEntityID");
              if (logoutResp != null && location != null &&
                      spEntity != null && idpEntity !=null) {
                  LogoutUtil.sendSLOResponse(response, request, logoutResp, location,
                          relayState, "/", spEntity, SAML2Constants.SP_ROLE,
                          idpEntity, binding);
                  return true;
              }
          }
      
          return doRelayState;
      }

      needs to be changed to

      com.sun.identity.saml2.profile.IDPSingleLogout.java
      ...
      public static boolean processLogoutResponse(
              HttpServletRequest request,
              HttpServletResponse response,
              String samlResponse,
              String relayState) throws SAML2Exception, SessionException {
          String method = "processLogoutResponse : ";
          if (debug.messageEnabled()) {
              debug.message(method + "samlResponse : " + samlResponse);
              debug.message(method + "relayState : " + relayState);
          }
          String rmethod = request.getMethod();
          String binding = SAML2Constants.HTTP_REDIRECT;
          if (rmethod.equals("POST")) {
              binding = SAML2Constants.HTTP_POST;
          }
          String metaAlias =
                  SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI()) ;
          String realm = SAML2Utils.
                  getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
          ...
      
          // IDPProxy
          Map logoutResponseMap = (Map)IDPCache.logoutResponseCache.get(
                  requestId);
          if ((logoutResponseMap != null) && (!logoutResponseMap.isEmpty())) {
              LogoutResponse logoutResp = (LogoutResponse)
                      logoutResponseMap.get("LogoutResponse");
              String location = (String) logoutResponseMap.get("Location");
              String spEntity = (String) logoutResponseMap.get("spEntityID");
              String idpEntity = (String) logoutResponseMap.get("idpEntityID");
              if (logoutResp != null && location != null &&
                      spEntity != null && idpEntity !=null) {
                  LogoutUtil.sendSLOResponse(response, request, logoutResp, location,
                          relayState, realm, spEntity, SAML2Constants.SP_ROLE,
                          idpEntity, binding);
                  return true;
              }
          }
      
          return doRelayState;
      }
      extracting the single line to be changed
                  LogoutUtil.sendSLOResponse(response, request, logoutResp, location,
                          relayState, realm, spEntity, SAML2Constants.SP_ROLE,
                          idpEntity, binding);
      

        Attachments

          Activity

            People

            • Assignee:
              sfraser Sam Fraser
              Reporter:
              bthalmayr Bernhard Thalmayr
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: