Ping Federate- Attribute Fulfillment with OGNL Expression

I have been working with Ping Federate few years and I kind of know the ins and outs of the product. The SSO Guy, that’s what people call me at work! Ping Federate is 3rd party product and my objective is not to inject too much custom codes as best practice. Custom code can break upon upgrades and you don’t have express warranty on custom code. However, there comes time you should create your own adapter to fit your needs or at the minimum write OGNL (Object Graph Navigation Library) Expressions.

Let me share my specific requirements for which I opted for OGNL expression. My customer wanted to create as many connections with hard coded attributes to simulate SAML responses- in non-prod environments. Their goal is to cover maximum test coverage. While we can add more connections, it becomes maintenance problem. So, I tossed the idea to my customer and asked- how about you provide the inputs in query string at TargetResource (relay state)? You would be in greater control over the inputs. They liked the idea and I am up to learning a new coding language (java)! You can search for java classes on internet but you would not find internal packages/classes used by Ping Federate publicly. Your only choice is to use jar (-tvf) command to explore the classes. I was able to collect the ones I needed to work with and reviewed few expression guides on Ping documentations.

Without delay, let’s look at the expression that can capture multiple query strings and use them to fill the attributes.

It’s important to see the format of TargetResource in IdP initiated SSO. Here is an example-https://<pingfederate-server>/idp/startSSO.ping?PartnerSpId=XXX&TargetResource=https://localhost/?MYATTRIBUTE=1234%26Query2=value2%26Query3=value3. As you have noticed, you have to replace “&” with “%26” if you have more than one query parameters in the url. You have to encode the & character if the url has multiple query parameters.


#log = @org.apache.commons.logging.LogFactory@getLog(“com.pingidentity.ognl.logger”),
#paramList = new java.util.HashMap(),
#TargetResource = #this.get(“context.TargetResource”).getObjectValue(),
#URL = new java.net.URL(#TargetResource),
#queryParams = #URL.getQuery().split(“&”),
#iCount=0,
#queryParams.{
#log.debug(“queryParam in loop iteration ” +#iCount +” ” +#queryParams[#iCount]),
#queryParam = #queryParams[#iCount].split(“=”),
#log.debug(“key=” +#queryParam[0] +” value=” +#queryParam[1]),
#paramList.put(#queryParam[0],#queryParam[1]),
#iCount = #iCount +1
},
#MYATTRIBUTE=#paramList.get(“MYATTRIBUTE”)


Every line must end with a comma. Actually, there is no line separator after you copy the scripts in Ping Federate UI! You can declare variable with a # before the name. You can iterate in a loop as well and we will see example here. Let me explain line by line!

Line 1: Load the logger into a variable.

Line 2: Declare a HashMap object. I could not use generic type in this line as UI will not accept <> characters needed to declare generics!

Line 3: Get the value of target resource url along with it’s query parameters and store into a variable.

Line 4: Create an instance of URL object to be able to parse query strings.

Line 5: Split the query strings and store into a variable.

Line 6: We are going to need to enumerate through the array of string. So, we need to declare a counter (zero based).

Line 7: This is the starting of our loop and you place your codes within a curly braces. Notice, there is a dot before the opening curly brace.

Line 8: You can add logging on any line and as many lines as you need. We are logging to get some debugging data. You can look them up in server.log to see if you are on right track!

Line 9: We split each pair of query string.

Line 10: We do some logging for debugging.

Line 11: We add the key/value to HashMap here.

Line 12: We increment the loop counter.

Line 13: This is where loop is closed.

Line 14: Read the query param by it’s name from HashMap. This is what gets added to the attribute.

You will need to repeat the script for each attribute and make sure you return the right param from HashMap. I tried to get the query parameters from httpRequest itself but they are lost in multiple directions.

Happy OGNL Scripting!

Reference: https://www.pingidentity.com/content/dam/developer/downloads/Resources/OGNL%20Series%2009192014.pdf

 

 

 

Leave a Reply