Oggi vi spiego come risolvere un problema forse non troppo frequente ma che in alcuni contesti potrebbe tornare utile.

La casistica è abbastanza semplice da spiegare: durante la navigazione del sito Liferay come utente Guest ho necessità di impostare delle variabili di sessione e nel momento in cui l'utente fa login, queste variabili devono rimanere in sessione. Sebbene ci siano diversi modi per risolvere il problema con Liferay, vi mostrerò quello che ritengo essere il più sicuro ed elegante.

L'esempio più classico che mi viene in mente è il carrello della spesa di un sito di e-commerce: l'utente anonimo inizia a riempire il carrello e tutti gli articoli finiscono in sessione ma per il pagamento deve fare login e chiaramente il carrello non deve andare perso dopo il login.

Le impostazioni di default di Liferay non consentono di fare questa cosa perché al momento del login la sessione utente (dell'utente anonimo) viene invalidata e quindi tutti i dati sono persi; il motivo di questo comportamento sta nell'esigenza di evitare problemi di phishing quindi viene da pensare che il funzionamento sia corretto così.

Pertanto la prima soluzione che si può mettere in atto è quella di disabilitare completamente la protezione contro il phishing e questo si può fare impostando nel portal-ext.properties la seguente property:

session.enable.phishing.protection=false

Inutile dire che questa soluzione è un pò brutale e sarebbe meglio evitarla; guardando meglio però esiste un'altra property molto più utile:

session.phishing.protected.attributes=\
    CAS_LOGIN,\
HTTPS_INITIAL,\
LAST_PATH,\
OPEN_ID_CONNECT_SESSION,\
SETUP_WIZARD_PASSWORD_UPDATED

Questa property (già prevalorizzata dal portale) non fa altro che elencare il nome delle variabili di sessione che devono essere copiate nella nuova sessione nel momento in cui l'utente fa login; l'unica cosa da tenere a mente è che queste variabili di sessione devono essere memorizzate all'interno della sessione HTTP della request originale del portale, quindi scordatevi la PortalSession!

Vediamo un esempio pratico. Innanzitutto dobbiamo aggiungere la nostra variabile di sessione all'elenco e riavviare il portale:

session.phishing.protected.attributes=\
    CAS_LOGIN,\
HTTPS_INITIAL,\
LAST_PATH,\
OPEN_ID_CONNECT_SESSION,\
SETUP_WIZARD_PASSWORD_UPDATED,\
MY_SESSION_VARIABLE

Dopodiché dobbiamo ricordarci che la variabile deve essere memorizzata all'interno della sessione HTTP della request originale del portale:

import javax.portlet.PortletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.liferay.portal.kernel.util.PortalUtil;

// [...]
 
HttpServletRequest request = PortalUtil.getHttpServletRequest(portletRequest);
request = PortalUtil.getOriginalServletRequest(request);

HttpSession session = request.getSession();

Una volta ottenuta la sessione HTTP possiamo leggere e scrivere la nostra variabile:

MyObject myObject = ...;
session.setAttribute("MY_SESSION_VARIABLE", myObject);

MyObject myObject = (MyObject) session.getAttribute("MY_SESSION_VARIABLE");

Il gioco è fatto!

Buon divertimento!