Liferay Custom Authentication by Hook

liferay-custom-authentication


aim

By using Authentication Pipeline we can write our own custom authentication logic. We can conditionally validate user based on some condition. In this article we will create our custom Authenticator implementing liferay com.liferay.portal.security.auth.Authenticator interface in the form of Hook.


1.   liferay-hook.xml

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">

<hook>
	<portal-properties>portal.properties</portal-properties>
</hook>

2.portal.properties

auth.pipeline.pre=com.proliferay.CustomAuthenticator

This classes i.e., CustomAuthenticator will run  before or after the portal authentication begins.

3. CustomAuthenticator .java

package com.proliferay;

import java.util.Map;

import com.liferay.portal.security.auth.AuthException;
import com.liferay.portal.security.auth.Authenticator;

public class CustomAuthenticator implements Authenticator {

	@Override
	public int authenticateByEmailAddress(long companyId, String emailAddress,
			String password, Map<String, String[]> headerMap,
			Map<String, String[]> parameterMap) throws AuthException {
		
		/**
		 * All your logic will go here
		 */
		
		return SKIP_LIFERAY_CHECK;
	}

	@Override
	public int authenticateByScreenName(long companyId, String screenName,
			String password, Map<String, String[]> headerMap,
			Map<String, String[]> parameterMap) throws AuthException {

		return DNE;
	}

	@Override
	public int authenticateByUserId(long companyId, long userId,
			String password, Map<String, String[]> headerMap,
			Map<String, String[]> parameterMap) throws AuthException {
		return DNE;
	}

}

In the above code we have not written any logic. Deploy the hook and try to log in with wrong password. If the user name is correct it will allow to login because we have returned  SKIP_LIFERAY_CHECK.

Note 1:

There are three methods in the above code. Liferay user can be authenticated three ways. First is by emailAddress, second is by screenName and third one is by userId. So based on our portal settings only single method will be called . To know more about it follow the below article

AuthType:3 Ways to Login Liferay

Note 2:

There are 4 constants in the Authenticator interface

public static final int DNE = 0;
public static final int FAILURE = -1;
public static final int SKIP_LIFERAY_CHECK = 2;
public static final int SUCCESS = 1;

The class which implements Authenticator interface must return one of the above constants. Here are the use of all the constants.

SUCCESS : If authentication is successful, return SUCCESS

FAILURE: If the user exists but the  passwords do not match, return FAILURE

DNE: If the user does not exist on  the system, return DNE.

SKIP_LIFERAY_CHECK :  In the pre-authentication pipeline, if you want to skip password checking  by the internal portal authentication, the authenticator should return SKIP_LIFERAY_CHECK. This is needed if passwords are not imported to the portal

Note 3:

In case you have several classes in the authentication pipeline, all of  them have to return SKIP_LIFERAY_CHECK or SUCCESS if you want the user to be able to login. If one of the authenticators returns DNE OR FAILURE, the login fails.

Download Source Code:

authentication-hook

 

About The Author

3 thoughts on “Liferay Custom Authentication by Hook”

  1. Raymond Gardner

    Does this work for Liferay 6.1?

    I have my CustomAuthenticator defined at:
    com.project.hook.events.auth

    I keep getting a hook deployment error:
    com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering hook for plugin-hook
    at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployException(BaseHotDeployListener.java:46)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:277)
    at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:195)
    at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:97)
    at sun.reflect.GeneratedMethodAccessor755.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.liferay.portal.security.lang.DoPrivilegedHandler.doInvoke(DoPrivilegedHandler.java:88)
    at com.liferay.portal.security.lang.DoPrivilegedHandler.invoke(DoPrivilegedHandler.java:56)
    at $Proxy29.fireDeployEvent(Unknown Source)
    at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:27)
    at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164)
    at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:64)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:56)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54)
    at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3926)
    at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
    at java.lang.Thread.run(Thread.java:662)
    Caused by: java.lang.ClassNotFoundException: com.project.hook.events.auth
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:52)
    at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:27)
    at com.liferay.portal.kernel.util.ProxyFactory.newInstance(ProxyFactory.java:38)
    at com.liferay.portal.kernel.util.ProxyFactory.newInstance(ProxyFactory.java:29)
    at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.newInstance(BaseHotDeployListener.java:89)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.initAuthenticators(HookHotDeployListener.java:937)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.initAuthenticators(HookHotDeployListener.java:956)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.initPortalProperties(HookHotDeployListener.java:1560)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.doInvokeDeploy(HookHotDeployListener.java:595)
    at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployListener.java:274)
    … 27 more

    1. Raymond Gardner

      If I deploy my CustomAuthenticator in the ext plugin, then it works. But, I want to deploy it in my hook.

  2. Well explained 🙂

    In this example it is bypassing password check, but the user name is showing from liferay database.
    How can I validate username and password with user defined database ?

    Thanks,
    Vishnu

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top