Support Article
SAML: IDP Initiated request Relaystate parameter Issue
SA-9457
Summary
While using Siteminder and SAML for SSO, user logins to PRPC using an IDP initiated request PRPC is expecting a RelayState parameter.
When providing a RelayState parameter PRPC is not using it properly and displaying an error.
Error Messages
When no relay state is not passed:
Unable to process the SAML WebSSO request : Missing Relaystate information in IDP Response
Message when relay state is passed:
Unable to process the SAML WebSSO request :
Steps to Reproduce
Test SAML authentication with an IDP initiated request.
Root Cause
PRPC does require a RelayState parameter but up to Pega 7.1.7 the AssertionConsumerService is only handling the RelayState in a SP initiated request.
Resolution
This issue is resolved through the following Local-change:
1) Copy the Data-Admin-Security-SSO-SAML.pyAssertionConsumerServiceActivity into a client specific ruleset.
2) Replace the java code in Step 9 with the following code: (Specific changes are in bold)
{
//Parse the response message into SAMLResponse and RelayState
String responseMessage = myStepPage.getString("pyACSPOSTBodyContent");
java.util.Map<String, String> paramsMap = new java.util.HashMap<String, String>();
String[] params = responseMessage.split("&");
for (String param : params)
{
String[] keyValuePair = param.split("=");
String name = keyValuePair[0];
String value = keyValuePair[1];
paramsMap.put(name, value);
}
SAMLResponse = paramsMap.get("SAMLResponse");
//A relaystate identifier is used as a pointer to actual relaystate in order to hide it
relayStateID = paramsMap.get("RelayState");
if(relayStateID == null)
throw new PRRuntimeException("Missing Relaystate information in IDP Response");
relayStateID = java.net.URLDecoder.decode(relayStateID, "UTF-8");
try {
ClipboardPage cbp = tools.createPage("Data-Admin-LoginInfo", "");
cbp.putString("pyRelayStateID", relayStateID );
ClipboardPage page= tools.getDatabase().open(cbp, false);
// Add fallback mechanism to consume the RelayState as it is, example: IDP Initiated request containing RelayState parameter. (Does not get created by PRPC)
if (page == null){
relayState = relayStateID;
oLog.debug("relayState recieved: " + relayState);
}
else {
relayState = page.getString("pyRelayState");
oLog.debug("relayState from pyRelayStateID instance [“+ relayStateID + “]: " + relayState);
//Delete the instance from database
try{
tools.getDatabase().delete(cbp, false);
}catch(DatabaseException ex){
oLog.error("Caught exception while trying to delete the logininfo page" + ex);
}
}
}
catch(DatabaseException e) {
throw new PRRuntimeException(" Invalid relay state ID received. Probable cause being tampered relay state ID, " + relayStateID + e.getMessage());
}
}
catch(Exception e)
{
errorMessage = e.getMessage();
tools.putParamValue("ErrorMessage", errorMessage);
nextBlock = "ERR";
}
3) Update the ServicePackage WebSSO and use an AccessGroup that contains ruleset that contains the copy of the Data-Admin-Security-SSO-SAML.pyAssertionConsumerServiceActivity.
Note: The changes mentioned has been included in Pega 7.1.8.
Published June 12, 2015 - Updated October 8, 2020
Have a question? Get answers now.
Visit the Collaboration Center to ask questions, engage in discussions, share ideas, and help others.