164 views

Description

Some IdPs only support HTTP-POST SAML login requests. Currently ServiceNow does not offer any available settings for the SAML login request to use HTTP-POST.

 

Steps to Reproduce

 

Some Identity Providers require an HTTP-POST login request. The baseline version of the Multi_provider SSO plugin does not support HTTP-POST.

 

Workaround

This issue has been identified as a product product enhancement and is under consideration.

The workaround below is the Installation Exit script code that has been approved by SN development to address the HTTP-POST login request issue. It was based on the latest Helsinki code base, and might need to be adapted to later releases.

The implementation should always be tested on a sub-production instance prior to move this change to production.

 

  1. Add the following methods in SAML2_update1 script include - Insert the following code after the "getSAMLAssertion" method:

    // START - Workaround for problem PRB656080
    getAuthnRequestFormString : function(isTestConn) {
    var AuthnRequestMarshaller = Packages.org.opensaml.saml2.core.impl.AuthnRequestMarshaller;
    var samlOptions = null;
    if (isTestConn) {
    samlOptions = {
    forceAuthn: true
    };
    }
     
    var authnRequest = this.createAuthnRequestWithOptions(samlOptions);
     
    var signAuthn = this.ssoHelper.getProperty("glide.authenticate.sso.saml2.require_signed_authnrequest", "require_signed_authnrequest", false);
    if(this.isTrue(signAuthn)) {
    this.signSAMLObject(authnRequest);
    }
     
    var arm = new AuthnRequestMarshaller();
    var elem = arm.marshall(authnRequest);
     
    return SAML2_update1.getEncodedSAMLRequest(elem, false, false);
    },
     
    generateAuthnRequestForm: function(request,isTestConn) {
    try {
    var idpAuthnURL = this.ssoHelper.getProperty("glide.authenticate.sso.saml2.idp_authnrequest_url", "idp_authnrequest_url");
     
    var authReqStr = this.getAuthnRequestFormString(isTestConn);
    var origRelayState = this.generateRelayState(request, isTestConn);
    // always use serviceUrl as relayState, it will lookup the real relayState using "SAML_RelayState" as the key.
    // failed login does not respond a relayState, so we must put the states into session for test corrections. 
    if (isTestConn) 
    request.getSession().setAttribute("Test_SAML_RelayState", origRelayState);
    else
    request.getSession().setAttribute("SAML_RelayState", origRelayState);
     
    var formStr = this.createSAMLRequestPostForm(idpAuthnURL, authReqStr, origRelayState);
     
    var httpSession = request.getSession();
    httpSession.setAttribute("glide.saml2.session_request_id", this.getLastGeneratedRequestID());
     
    //Add this request id to request id array in the session
     
    var requestIDArr = httpSession.getAttribute("glide.saml2.session_request_id_arr");
    if(!requestIDArr){
    requestIDArr = [];
    }
    requestIDArr.push(this.getLastGeneratedRequestID());
    httpSession.setAttribute("glide.saml2.session_request_id_arr", requestIDArr);
     
    return formStr;
    } catch (e) {
    if (e instanceof Packages.java.lang.Throwable){
    var stackTrace = GlideLog.getStackTrace(e);
    this.logError(stackTrace);
    }
    else{
    this.logError(e.name + ": " + e.message);
    }
     
    return null;
    }
    },
    // END - Workaround 1 for problem PRB656080




  2. Modify the script include MultiSSO_SAML2_Update1.

    Old Code:

    // code that uses http redirect binding -- old code
    var redirectURL = this.SAML2.generateAuthnRequestRedirectURL(request, false);
    if (GlideStringUtil.nil(redirectURL))
    return "failed_missing_requirement";


    New Code:
    // START - Workaround for problem PRB656080 
    // Refresh login request
    if(!samlResponseObject && !relayState) {
     
    // code that uses http post binding -- new code starts
    this.ssoHelper.debug("Logging in saml using HTTP POST");
    var formStr = this.SAML2.generateAuthnRequestForm(request, false);
    response.setContentType("text/html");
    response.getWriter().write(formStr);
    var redirectURL = "true"; // trick so it does not fail
    // new code ends
     
    /*
    // code that uses http redirect binding -- old code
    var redirectURL = this.SAML2.generateAuthnRequestRedirectURL(request, false);
    if (GlideStringUtil.nil(redirectURL))
    return "failed_missing_requirement";
    */
     
    SNC.SecurityEventSender.sendSAMLRedirectSentEventData("", "multisso=true,idpsysid=" + this.propertiesGR.getUniqueValue());
    return redirectURL;
    }
    // END - Workaround 2 for problem PRB656080

Related Problem: PRB656080

Seen In

Eureka Patch 11 Hot Fix 2
Eureka Patch 13 Hot Fix 2
Fuji Patch 10
Fuji Patch 7 Hot Fix 5
Fuji Patch 8
Geneva Patch 1
Geneva Patch 1 Hot Fix 5
Geneva Patch 6 Hot Fix 2
Geneva Patch 7
Geneva Patch 7 Hot Fix 2
Geneva Patch 8
Helsinki Patch 2
Helsinki Patch 4
Helsinki Patch 7

Associated Community Threads

There is no data to report.

Article Information

Last Updated:2018-03-23 12:14:06
Published:2018-02-09