Necesito filtrar todas las paginas de mi portlet para permitir el paso solo a aquellas personas que esten logadas.
Existen cuatro tipo de Filtros para los Portlets 2.0 (Render, Action, Resource, Event). Voy a utilizar solo Render y Action.
El problema mas grande que encontre, es que en los filtros Render no se puede redireccionar, por una cuestion de diseño, solo en los action.
Mi solucion: en la fase render repinto el JSP con un enlace a la url de login.
Los filtros son muy sencillos. Solo necesitamos un clase que realiza la accion pertinente y configurar este filtro en el portlet en su portlet.xml
package josemanuel.prietopalacios.net.portlets.filter;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.theme.ThemeDisplay;
public class LoggingFilter implements ActionFilter, RenderFilter {
private static final String URL_LOGIN = "urlLogin";
private static final String USERNAME = "username";
private static final String J_USERNAME = "j_username";
private static final String REPLACE_URL = "$URL$";
private static final String MESSAGE_NOT_LOGGED = "<h3>You must be logged. <a href=""+REPLACE_URL+"">login</a></h3>";
private String urlLogin;
public void init(FilterConfig filterConfig) throws PortletException {
urlLogin = filterConfig.getInitParameter(URL_LOGIN);
if (isBlank(urlLogin)) {
throw new PortletException(
"Not configured login URL in the file portlet.xml");
}
}
public void destroy() {
}
public void doFilter(ActionRequest request, ActionResponse response,
FilterChain chain) throws IOException, PortletException {
String username = getUsername(request);
if (username == null) {
String url = getUrl((PortletRequest) request);
response.sendRedirect(url);
}
chain.doFilter(request, response);
}
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain chain) throws IOException, PortletException {
String username = getUsername(request);
if (username == null) {
String url = getUrl((PortletRequest) request);
response.getWriter().append(MESSAGE_NOT_LOGGED.replace(REPLACE_URL, url));
}else{
chain.doFilter(request, response);
}
}
private String getUrl(PortletRequest request) {
ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
String url = themeDisplay.getPortalURL() + themeDisplay.getPathMain() + urlLogin;
return url;
}
private String getUsername(PortletRequest request) {
String user = (String) request.getAttribute(USERNAME);
if (!isBlank(user)) {
return user;
}
user = (String) request.getAttribute(J_USERNAME);
if (!isBlank(user)) {
return user;
}
user = request.getRemoteUser();
if (!isBlank(user)) {
return user;
}
return null;
}
private boolean isBlank(String str) {
if (str == null) {
return true;
} else if (str.equals("")) {
return true;
} else if (str.trim().isEmpty()) {
return true;
} else {
return false;
}
}
}
<portlet-app>
<!-- ... -->
<filter>
<filter-name>LoggingFilter</filter-name>
<filter-class>josemanuel.prietopalacios.net.portlets.filter.LoggingFilter</filter-class>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
<init-param>
<name>urlLogin</name>
<value>/portal/login</value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoggingFilter</filter-name>
<portlet-name>prueba-portlet</portlet-name>
</filter-mapping>
</portlet-app>
Opciones:
– si quieres i18n puedes recuperar el locate para segun que locate, dar un mensaje u otro.
request.getLocale();
– recuperar el log de la aplicacion para mostrar mensajes.
(He perdido el codigo!!)