Architecture and Solutioning Series: Persisting Bearer Token Using Liferay DXPs Expendo Table Feature

Problem statement:

In this particular Scenario in the existing application the SSO was implemented using Microsoft OIDC Provider with Liferay DXP. At the time of login the ‘Microsoft OIDC provider’ generated a Bearer Token which was the identifier for the authenticated user .

This Bearer token was needed for all the further API calls to the API Gateway (which in turn called the external data source) . The API gateway used the Bearer Token to further validate the users identity and once validated it Processed the appropriate API response to the API call request .Hence we need to make it available throughout . We were not allowed to save the Token in Sessions because of security reasons.

Swim-lane diagram showing the OpenID Connect protocol's sign-in flow.

Reference : https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc

Conditions:

Bearer Token is Unique to every login .

Bearer Token is only available while OIDC call while login

Bearer Token should be available for the whole logged in period

Solution:

  1. We planned to extract the Bearer token  at the Login time Once at the while SSO event .
  2. To do so we used Liferay Post Login Action Feature to catch the event .
  3. We Extracted the TOKEN using logic local to the application .
  4. We decided to use Expendo Table feature and stored in KEY – VALUE where USERID was KEY and TOKEN was VALUE
  5. This KEY – VALUE was UNIQUE to each user and each login .



Following is the Example Code snippet for the same.

package com.login.event.post;
import com.liferay.expando.kernel.model.ExpandoTableConstants;
import com.liferay.expando.kernel.service.ExpandoValueLocalServiceUtil;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.kernel.exception.PortalException; 
import com.liferay.portal.kernel.model.User; 
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.events.LifecycleAction;
import com.liferay.portal.kernel.events.LifecycleEvent;
import org.osgi.service.component.annotations.Component;
/**
 * 
 * --------Author Details---------
 * Name:    YoungIT Consulting Services GmbH
 * Email:   [email protected]
 * Address: Fleethörn 7, 24103 Kiel, Germany
 * Phone:   +491514 5682025
 * --------Author Details---------
 * 
 */
@Component
(
immediate = true,
property = { "key=login.events.post" },
service = LifecycleAction.class
)
public class LoginPostAction implements LifecycleAction {
    @Override
    public void processLifecycleEvent(LifecycleEvent lifecycleEvent) throws ActionException {
        long userId = Long.parseLong(lifecycleEvent.getRequest().getUserPrincipal().toString());
        User user;
        try {
            user = UserLocalServiceUtil.getUser(userId);
            ExpandoValueLocalServiceUtil.addValue(user.getCompanyId(), User.class.getName(), ExpandoTableConstants.DEFAULT_TABLE_NAME,
                    "bearerToken", user.getPrimaryKey(), "==UPDATE_TOKEN_HERE==");
        } catch (PortalException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("login.event.pre=" + lifecycleEvent);
    }
Language
Scroll to Top