Integrating Verimi with Liferay

How to make Liferay even more extensible and create a custom OpenID connect mapping

Similar to my previous blog post about how to integrate the german Servicekonto with Liferay a customer wanted to create an integration of Verimi with Liferay. Several companies in germany already offer customers to login with a Verimi account. By this people can create one account which can be used to login to different portals.

Verimi uses an OpenID connect mechanism, so integration into Liferay should be rather easy. However after defining a proper OpenID connect provider in Liferay logins were unsuccessful. It seems that Liferay was unable to map certain properties of a user to Liferay. Especially it seems that Verimi does not provide the first name and the last name of a person.

After some research we found that Verimi provides only the full name of a person in a separate field. So we decided to examine how we can extend the Liferay functionality and create a custom mapping of fields from OpenID connect to Liferay users.

Making it extendable

Fortunately the mapping is handled in an OSGi component called OpenIdConnectUserInfoProcessor. Unfortunately it is not possible to extend Liferay functionality in this case because:

  1. The packge of the above component com.liferay.portal.security.sso.openid.connect.internal is a private package
  2. The component is injected into OpenIdConnectServiceHandlerImpl, but that reference is reluctant, i.e. if the reference is already satisfied it will not be replaced even if there is a component with a higher service.ranking.

To overcome issue 1 we wrote a fragment module which makes the above package exported (as shown in this blog post by David Nebinger).

To be able to replace reluctant references we followed the Liferay documentation and created a configuration file for OpenIdConnectServiceHandlerImpl. Reluctant references are be replaced if the configuration of the component changes, so we did that. In that configuration file we explicitly stated that our component should be injected into OpenIdConnectServiceHandlerImpl.

Mapping OpenID connect attributes

After being able to extend the functionality mapping the desired attributes from OpenID connect was rather easy. One Java class of a OpenIdConnectUserInfoProcessor component was enough to handle the attributes from Verimi. To provide the first name and the last name of a person we just split the full name given from Verimi by the last space found in the name.

Additionally we mapped the birthday of the person, too.

Result

By using the above mechanisms it is possible to extend the OpenID connect functionality to your needs. An implementation of the above can be found on github here: https://github.com/convotis/verimi-liferay-integration

Blogs

Dominik, excellent post.  Thank you for the breakdown and source code.  Ran in to a similar issue that also requires overriding the  OpenIdConnectServiceHandlerImpl class to get a successful openid connect sso login.  Verified your implementation works as advertised.  Also, you wouldn't by chance have an example that uses Gradle?  I've tried which much effort to create a Gradle project that does what your Maven project does and I get stuck on build/deployment/runtime errors.  Haven not been able to figure out the correct recipe.