a good thing!
Looping in OGNL take 2
In my previous article on looping, we looked at looping through a collection in an OGNL expression. In this article, we will take a different approach and learn more about what we can do inside the curly braces { } of an OGNL expression.
In the previous example, we set up a loop counter and used it to extract a particular entry from our collection or array. The curly braces served as the loop control like the for
or where
clause in Java. Since the curly braces controlled the loop, you could remove the need for the counter during the loop iteration if there were some other way to get the current value of an attribute. And since the attribute we care about is group, we would want to somehow get the value of the current group.
See the complete list of articles in my OGNL series at the end of this post.
So if we have an array object containing all the groups the user is a member of, we would want to iterate through it and get the group value. If the whole group array is [marketing, sales, IT] then in the first iteration, we'd want to get "marketing," in the second, "sales" and the third, "IT."
There is a way to get those group values without having a loop counter. In my second article we talked about how the #this
variable allowed us to get information from the current context. You could use it to get the value of an attribute that is available for use from PingFederate. Inside the curly braces, you can also use it to get the current group value that is being processed in the loop. This is called "projection" in OGNL and provides a very powerful tool for working with collections, for more information see the OGNL language guide.
Look at the code below and compare it to the example in my last article. You will notice that the counter i
is no longer set or incremented; you don't need it. What has changed is that at the start, we assign a value to #group
with #this
(line 4).
1. #groupCnOnly = new java.util.ArrayList(), 2. #groups = #this.get("ds.LDAP.memberOf")!=null?#this.get("ds.LDAP.memberOf").getValues():{}, 3. #groups.{ 4. #group = #this, 5. #group = new javax.naming.ldap.LdapName(#group), 6. #cn = #group.getRdn(#group.size() - 1).getValue().toString(), 7. #groupCnOnly.add(#cn) 8.}, 9. #this.get("ds.LDAP.memberOf")!=null? new org.sourceid.saml20.adapter.attribute.AttributeValue(#groupCnOnly):null
Let's review the code line by line (line numbers above should of course be removed when you copy this code into your own PingFederate environment):
org.sourceid.saml20.adapter.attribute.AttributeValue
class, we can create an object that takes a java.util.ArrayList
as a collection. We want to return the CN for all the groups, so we create an object to hold those CNs.memberOf
attribute retrieved from the LDAP data source actually exists, in other words, does the user belong to at least one group?ArrayList
) from the current context.{}
braces.groups
object either contains the collection of groups or an empty collection. The curly braces will provide an iteration through each entry in the collection. This is effectively a for
or where
loop that will take us through the number entries in the collection. Inside the curly braces you place the code to process each entry in turn.#this
. It has to be first and standalone; thus, we initialize group
on its own line.javax.naming.ldap.LdapName
that will break down the DN into its separate components.CN=
).ArrayList
that is going to hold our collection of CNs.{
curly brace and continue.null
Now the code:
The results of executing the code:
Stay tuned for more about OGNL. In the meantime please leave a comment on this post and let me know what topics you would like to see. Follow me on Twitter: @jdasilvaPI
*************************
OGNL Blog Series:
John DaSilva develops training and solutions at Ping Identity.