News

More than 30 IDM realisations in Czech Republic and abroad

AMI Praha 3 Tips for IdM midPoint
3 Tips for IdM midPoint

3 Tips for IdM midPoint

We assume that the reader of this article has a general understanding of identity management and is familiar with midPoint product.

Example 1: Extended password policy requirements

Anyone who has ever implemented IdM at a customer’s site will have encountered requirements for creating secure user passwords. Typical requirements are: minimum password length, password change frequency, required characters, prohibited characters, etc. All of these conditions can be configured in midPoint without any problems.

However, the customer may require setting additional, less common password creation rules. One such requirement may be that the password must not contain the user’s current login (case insensitive). Such a rule is difficult to configure and midPoint does not even include it in the current version 3.5. However, there is no need to throw in the towel, as we will show how to make such a rule, literally in a few lines of code. Note that we won’t be modifying any “ready-made” midPoint java source code, but we will use a supported and documented procedure in the mapping called “user template” into which we will insert our code. The advantages of this procedure are obvious – such code will work in all future versions of midPoint. Thus, we don’t have to worry about our code when upgrading later and we follow the documentation. If, on the other hand, we were to change the code directly in the midPoint source code, we would have to deal with merging our code with the new version’s code in every future upgrade, which can cause a lot of complications.

Let’s now see how elegantly this requirement can be solved in midPoint.

The part of the object that provides password versus login control – mapping in user template

   <mapping>

      <name>Check Pwd against Login</name>

      <source>

         <c:path>$user/name</c:path>

      </source>

      <expression>

         <variable>

            <name xmlns_my=”http://whatever.com/my”>my:cryptPwd</name>

            <c:path>$user/credentials/password/value</c:path>

         </variable>

         <script>        <language>http://midpoint.evolveum.com/xml/ns/public/expression/language#Groovy</language>

            <code>

import com.evolveum.midpoint.model.api.PolicyViolationException;

 

                // check password against login – if the password contains login, we generate an exception

if(basic.lc(basic.decrypt(cryptPwd)).contains(basic.lc(basic.stringify(name)))) {

                               throw new PolicyViolationException(“The password must not contain your login!”);

            }

            </code>

         </script>

      </expression>

</mapping>

Example 2: Mapping values

Another requirement that a developer implementing IdM may encounter is the requirement to map one list of values to another. Typical examples include language codes and their names (cs_CZ – Czech, en_US – English, sk_SK – Slovak, …), workplace codes and their names (PHA – Prague, BNO – Brno, OVA – Ostrava, …) and so on.

Let’s imagine that a customer has the three-letter workplace codes mentioned above in the source HR application, but in another application we need to convert them to the corresponding full name.

One way to do this is to “hard-code” the code with conditions that will convert the individual three-letter codes to full department names. This of course has a lot of disadvantages – lack of clarity, the need for the developer to change the code when a workstation is created/cancelled, and the inability to edit the code list by the customer.

A far more elegant way in midPoint is to use a “Lookup Table” – a translation table. Such a table contains key-value pairs that can be further manipulated and called from program code. The advantages are obvious – when a workplace is created or disappears, the corresponding entry in the lookup table is only modified. The table can be maintained by the customer himself (no developer is needed) and there is no need to constantly modify the source code for conversion.

Below we will show how such a code for converting workplaces and their three-letter abbreviations could look like. The individual commands are explained directly in the comments of the source code.

Part of the “lookup-workplace” table with workplace mapping

                <row>

                               <key>PHA </key>

                               <label>Praha</label>

                </row>

                <row>

                               <key>BNO</key>

                               <label>Brno</label>

                </row>

The part of the object that maps workstation codes to their full names – mapping in user template.

<mapping>

                <expression>

                <script>

                               <code>

                import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType;

                import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType;

                import com.evolveum.midpoint.schema.GetOperationOptions;

                import com.evolveum.midpoint.schema.RelationalValueSearchQuery;

                import com.evolveum.midpoint.schema.RelationalValueSearchType;

                import com.evolveum.midpoint.schema.SelectorOptions;

 

                  // default value of the return variable

                ret = ‘unknown workplace’;

              

                // query definition and query options, default workplace is Prague

                query = new RelationalValueSearchQuery(LookupTableRowType.F_KEY, ‘PHA’, RelationalValueSearchType.EXACT);

                options = SelectorOptions.createCollection(LookupTableType.F_ROW, GetOperationOptions.createRetrieve(query));

 

                // getting the lookup table object

                LookupTableType lookup = midpoint.getObject(LookupTableType.class, ‘lookup-pracoviste’, options);

                // getting the table row

                lookupRow = lookup.getRow();

 

                // test if the table row exists at all

              if (lookupRow.size() > 0) {

                       // row exists, get the description and set the variable

                    ret = basic.stringify(lookupRow[0].getLabel());

              }

 

                // return the value of the variable – either unknown or set from the table

                return ret;

                               </code>

</script>

                </expression>

                               <target>

                                               <path>fullNameLocality</path>

                               </target>

</mapping>

Example 3: Whisperer in the user form

The third typical request that a developer implementing IdM may encounter is a customer request to create a whisperer for items in a user form in the IdM GUI. An example might be the ability to select from a list of languages, from a list of workplaces, or from a list of locations with a mouse click. The advantage of a whisperer is (besides increasing user convenience) also minimizing typos during input.

The implementation of this functionality is very simple in midPoint. Again, we use a documented and supported procedure and avoid any modification of the midPoint source code. To resolve the request, we use the “Lookup Table” – the translation table mentioned in the second example – and create a whisperer for language selection.

Part of the “lookup-languages” table with language mapping

                <row>

                               <key>cs</key>

                               <label>Czech</label>

                </row>

                <row>

                               <key>en</key>

                               <label>English</label>

                </row>

The part of the object that loads languages from the table and displays them in the whisperer – item in user template

   <item>

      <ref>preferredLanguage</ref>

      <displayName>Language</displayName>

      <valueEnumerationRef oid=”lookup-languages”/>

   </item>

Conclusion

In this article, we have used examples to show how to solve three typical user requirements in Evolveum’s midPoint identity manager. Although at first glance these were quite complex requests, solving them in midPoint was a matter of a few lines of code. In neither case did we have to modify the original IdM source code directly (although we have the option in the case of midPoint and the license allows us to do so), but we used the documented and recommended procedure of modifying XML objects. This demonstrates the tremendous power of this tool and the ease with which it can be implemented by customers.

Author: Roman Pudil works as an IdM solution architect at AMI Praha.