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

SAML IdP-initiated SSO without existing SSO Session - value of 'goto' parameter not URLencoded

    XMLWordPrintable

    Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 13.0.0, 13.5.0, 13.5.1, 13.5.2, 14.0.0, 14.1.0, 14.1.1, 14.5.0, 14.5.1, 5.5.1, 6.0.0, 6.0.0.1, 6.0.0.2, 6.0.0.3, 6.0.0.4, 6.0.0.5, 6.5.0, 6.0.0.6, 6.5.0.1, 7.0.0
    • None
    • SAML
    • Oracle JDK jdk1.8.0_201
      Apache Tomcat/9.0.8
      AM 7.0.0 (c36edcc20aab37e8bc86e092e0552951ba0cc6a5)
    • Rank:
      1|hzxp0f:

      Description

      Bug description

      When performing IdP-initiated SSO without exising SSOSession, the value of the 'goto' parameter as part of the redirect to the authentication URL is not URL encoded. This causes issues with single page applications

      How to reproduce the issue

      1. Configure AM using amster (e.g. install-openam --adminPwd SOME_PASSWORD --acceptLicense --cfgDir /var/AM-Deployments/amMaster --serverUrl http://amMaster.test.xyz:8080/am
      2. create sub-realm
      3. register hosted IdP in sub-realm and CoT
      4. register remote SP in that realm / CoT
      5. Perform IdP-iniated SSO (e.g. http://ammaster.test.xyz:8080/am/saml2/jsp/idpSSOInit.jsp?metaAlias=/sub1/idp&spEntityID=REMOTE_SP_ENTITY
      Expected behaviour
      value of 'goto' parameter in the value of the Location response header value should be URL encoded.
      
      Current behaviour

      value of 'goto' parameter is not URL encoded

      excerpt from network trace - request
      Frame 9: 663 bytes on wire (5304 bits), 663 bytes captured (5304 bits)
      Null/Loopback
      Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
      Transmission Control Protocol, Src Port: 51916, Dst Port: 8080, Seq: 497, Ack: 373, Len: 607
      Hypertext Transfer Protocol
          GET /am/UI/Login?realm=/sub1&spEntityID=idp-proxy-bund&goto=http://ammaster.test.xyz:8080/am/saml2/jsp/idpSSOInit.jsp?metaAlias%3D/sub1/idp%26spEntityID%3Dtest-sp%26redirected%3Dtrue HTTP/1.1\r\n
          Host: ammaster.test.xyz:8080\r\n
      ....
      
      excerpt from network trace - response
      Frame 7: 428 bytes on wire (3424 bits), 428 bytes captured (3424 bits)
      Null/Loopback
      Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
      Transmission Control Protocol, Src Port: 8080, Dst Port: 51916, Seq: 1, Ack: 497, Len: 372
      Hypertext Transfer Protocol
          HTTP/1.1 302 \r\n
          X-Frame-Options: SAMEORIGIN\r\n
          Location: http://ammaster.test.xyz:8080/am/UI/Login?realm=/sub1&spEntityID=idp-proxy-bund&goto=http://ammaster.test.xyz:8080/am/saml2/jsp/idpSSOInit.jsp?metaAlias%3D/sub1/idp%26spEntityID%3Dtest-sp%26redirected%3Dtrue\r\n
      ....
      

      Code analysis

      com.sun.identity.saml2.profile.IDPSSOUtil.java
          static void redirectAuthentication(
                  HttpServletRequest request,
                  HttpServletResponse response,
                  AuthnRequest authnReq,
                  String reqID,
                  String realm,
                  String idpEntityID,
                  String spEntityID)
                  throws SAML2Exception, IOException {
              String classMethod = "IDPSSOUtil.redirectAuthentication: ";
              // get the authentication service url 
              StringBuffer newURL = new StringBuffer(
                      IDPSSOUtil.getAuthenticationServiceURL(
                              realm, idpEntityID, request));
      
              // Pass spEntityID to IdP Auth Module
              if (spEntityID != null) {
                  if (newURL.indexOf("?") == -1) {
                      newURL.append("?");
                  } else {
                      newURL.append("&");
                  }
                  newURL.append(SAML2Constants.SPENTITYID);
                  newURL.append("=");
                  newURL.append(urlEncodeQueryParameterNameOrValue(spEntityID));
              }
      
              // find out the authentication method, e.g. module=LDAP, from
              // authn context mapping 
              IDPAuthnContextMapper idpAuthnContextMapper =
                      getIDPAuthnContextMapper(realm, idpEntityID);
      
              IDPAuthnContextInfo info =
                      idpAuthnContextMapper.getIDPAuthnContextInfo(
                              authnReq, idpEntityID, realm);
              Set authnTypeAndValues = info.getAuthnTypeAndValues();
              if ((authnTypeAndValues != null)
                      && (!authnTypeAndValues.isEmpty())) {
                  Iterator iter = authnTypeAndValues.iterator();
                  StringBuffer authSB = new StringBuffer((String) iter.next());
                  while (iter.hasNext()) {
                      authSB.append("&");
                      authSB.append((String) iter.next());
                  }
                  if (newURL.indexOf("?") == -1) {
                      newURL.append("?");
                  } else {
                      newURL.append("&");
                  }
                  newURL.append(authSB.toString());
                  if (logger.isDebugEnabled()) {
                      logger.debug(classMethod +
                              "authString=" + authSB.toString());
                  }
              }
              if (newURL.indexOf("?") == -1) {
                  newURL.append("?goto=");
              } else {
                  newURL.append("&goto=");
              }
      
              String gotoURL = request.getRequestURL().toString();
              String gotoQuery = request.getQueryString();
      
              //We are appending redirected=true to the goto URL so that we can tell if the user was already redirected
              //to the login interface for authentication.
              if (gotoQuery != null) {
                  gotoURL += "?" + gotoQuery + "&" + REDIRECTED_TRUE;
              } else {
                  gotoURL += "?" + REDIRECTED_TRUE;
              }
              if (reqID != null) {
                  gotoURL += "&ReqID=" + reqID;
              }
      
              if (logger.isDebugEnabled()) {
                  logger.debug(classMethod +
                          "gotoURL=" + gotoURL);
              }
      
              newURL.append(urlEncodeQueryParameterNameOrValue(gotoURL));
      ...
      

        Attachments

          Issue Links

            Activity

              People

              Unassigned Unassigned
              bthalmayr Bernhard Thalmayr
              Votes:
              1 Vote for this issue
              Watchers:
              14 Start watching this issue

                Dates

                Created:
                Updated: