Foros de discusión

Hooks - Force user logout

thumbnail
Vincent Paranpan, modificado hace 12 años.

Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Hi Everyone,

I have customized a hook-plugin to check whether a user is still logged in or not, I'm having problems forcing the specific users (users who are currently logged in) to logout.

Here's my portal.properties for the hook-plugin.

login.events.post=com.test.CustomClass


Here's the custom class that I've made for forcing users to logout.

package com.test;

public class CustomClass extends Action {

public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {

//Placed code here to check if the user is still logged in or not..
[indent]
//This flag is true if the user is still logged in from another web browser.
if(flagIfUserIsStillLoggedIn){ 
[indent]HttpSession session  = request.getSession();[/indent]
[indent]session.invalidate();[/indent]
}[/indent]
}


Can anyone please guide me? How would I force the users to logout programmatically? Is it possible to force users to logout? Is it even possible in hooks?

Thanks,
Vincent
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
Can't you use the session expiration properties within Liferay to log them out? Seems to be an easier method to handle this...
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Hi David,

Thanks for the reply and sorry let me rephrase the question, how would I force a currently logged in user to logout using hooks? The forced logout will be triggered with a certain condition, like if the user accessed the portal on a specific range of IP address (just an example).

Cheers,
Vincent
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
Still seems to be trying to pound a square peg into a round hole...

For this particular use case, I'd worry about blocking the access either in the firewall or via a fronting web server such as apache httpd. Either of these would be better solutions...
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Hi David,

Yes I agree for that particular case I'd also use that, but it was just an example, anyways, have you tried disabling simultaneous logins for LR version 6x? This is the whole picture of the problem that I'm trying to explain, and solve here.. emoticon

Cheers
Vincent
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
I know that if you had monitoring enabled under 5.2.3, I could whack sessions through the monitoring page of the control panel.

I just checked my 6.0 install, but I don't see the option to kill a session.

I would hope that a) this is an option I would just need to enable in portal-ext.properties and b) the functionality is still there and exposed as a web service.

I don't know that either option is actually true, but this would probably be the path that I'd pursue:

1. enable monitoring on your liferay instance.
2. query for the list of sessions that are currently active.
3. make your determination which one needs to go.
4. kill the session. Hopefully this would prove to be very easy, especially if there is some old code floating around in the monitoring portlet for killing sessions.

Then wrap this in a quartz job, and you should be fine, at least development wise.

Your disconnected users won't know what hit them, but at least your requirement would be satisfied.
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Hi Jay and David,

Thanks for the advice.. I'll try both of your ideas.. emoticon

Cheers,
Vincent
thumbnail
Jay Patel, modificado hace 12 años.

RE: Hooks - Force user logout (Respuesta)

Regular Member Mensajes: 118 Fecha de incorporación: 24/02/10 Mensajes recientes
Vincent Paranpan:
Hi Everyone,

I have customized a hook-plugin to check whether a user is still logged in or not, I'm having problems forcing the specific users (users who are currently logged in) to logout.

Here's my portal.properties for the hook-plugin.

login.events.post=com.test.CustomClass


Here's the custom class that I've made for forcing users to logout.

package com.test;

public class CustomClass extends Action {

public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {

//Placed code here to check if the user is still logged in or not..
[indent]
//This flag is true if the user is still logged in from another web browser.
if(flagIfUserIsStillLoggedIn){ 
[indent]HttpSession session  = request.getSession();[/indent]
[indent]session.invalidate();[/indent]
}[/indent]
}


Can anyone please guide me? How would I force the users to logout programmatically? Is it possible to force users to logout? Is it even possible in hooks?

Thanks,
Vincent


Hi Vincent,
I think just doing session.invalidate() will not be enough to force user to logout as various cookies are stores at client-side browser as well.

Try putting logic from Liferay's Portal Source code from class "LogoutAction.java", this is the class used to logout user.

In this class they have reset several cookies such as password etc. Some line I have pasted as follows:

HttpSession session = request.getSession();

EventsProcessorUtil.process(
PropsKeys.LOGOUT_EVENTS_PRE, PropsValues.LOGOUT_EVENTS_PRE,
request, response);

String domain = CookieKeys.getDomain(request);

Cookie companyIdCookie = new Cookie(
CookieKeys.COMPANY_ID, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
companyIdCookie.setDomain(domain);
}

companyIdCookie.setMaxAge(0);
companyIdCookie.setPath(StringPool.SLASH);

Cookie idCookie = new Cookie(CookieKeys.ID, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
idCookie.setDomain(domain);
}

idCookie.setMaxAge(0);
idCookie.setPath(StringPool.SLASH);

Cookie passwordCookie = new Cookie(
CookieKeys.PASSWORD, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
passwordCookie.setDomain(domain);
}

passwordCookie.setMaxAge(0);
passwordCookie.setPath(StringPool.SLASH);
......................................
......................................

Regards,
Jay.
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Jay Patel:
Vincent Paranpan:
Hi Everyone,

I have customized a hook-plugin to check whether a user is still logged in or not, I'm having problems forcing the specific users (users who are currently logged in) to logout.

Here's my portal.properties for the hook-plugin.

login.events.post=com.test.CustomClass


Here's the custom class that I've made for forcing users to logout.

package com.test;

public class CustomClass extends Action {

public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {

//Placed code here to check if the user is still logged in or not..
[indent]
//This flag is true if the user is still logged in from another web browser.
if(flagIfUserIsStillLoggedIn){ 
[indent]HttpSession session  = request.getSession();[/indent]
[indent]session.invalidate();[/indent]
}[/indent]
}


Can anyone please guide me? How would I force the users to logout programmatically? Is it possible to force users to logout? Is it even possible in hooks?

Thanks,
Vincent


Hi Vincent,
I think just doing session.invalidate() will not be enough to force user to logout as various cookies are stores at client-side browser as well.

Try putting logic from Liferay's Portal Source code from class "LogoutAction.java", this is the class used to logout user.

In this class they have reset several cookies such as password etc. Some line I have pasted as follows:

HttpSession session = request.getSession();

EventsProcessorUtil.process(
PropsKeys.LOGOUT_EVENTS_PRE, PropsValues.LOGOUT_EVENTS_PRE,
request, response);

String domain = CookieKeys.getDomain(request);

Cookie companyIdCookie = new Cookie(
CookieKeys.COMPANY_ID, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
companyIdCookie.setDomain(domain);
}

companyIdCookie.setMaxAge(0);
companyIdCookie.setPath(StringPool.SLASH);

Cookie idCookie = new Cookie(CookieKeys.ID, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
idCookie.setDomain(domain);
}

idCookie.setMaxAge(0);
idCookie.setPath(StringPool.SLASH);

Cookie passwordCookie = new Cookie(
CookieKeys.PASSWORD, StringPool.BLANK);

if (Validator.isNotNull(domain)) {
passwordCookie.setDomain(domain);
}

passwordCookie.setMaxAge(0);
passwordCookie.setPath(StringPool.SLASH);
......................................
......................................

Regards,
Jay.



Hi Jay,

I tried your advice but I encountered an error, see below.

java.lang.NoClassDefFoundError: com/liferay/portal/util/PropsValues


I know this is a simple missing class file error, so what I did was I included the portal-impl.jar to my hooks plugin project, but whenever I deploy my hooks plugin I encounter another error, see below..

ERROR Could not create an Appender. Reported error follows.
java.lang.ClassCastException: org.apache.log4j.ConsoleAppender cannot be cast to org.apache.log4j.Appender
.
.
ERROR Could not parse url [jar:file:/C:/Liferay/liferay-portal-6.0.5/tomcat-6.0.26/webapps/my-test-hook/WEB-INF/lib/portal-impl.jar!/META-INF/portal-log4j.xml].
java.lang.NullPointerException


Is this just a configuration error?

Thanks,
Vincent
thumbnail
Jay Patel, modificado hace 12 años.

RE: Hooks - Force user logout

Regular Member Mensajes: 118 Fecha de incorporación: 24/02/10 Mensajes recientes
Hi Vincent,

To copy portal-impl.jar in hook is not a good practice to follow.

I think. PropsValues & PropsKeys basically get some values out of property file. Just if those are not many values then you should just give it a try by putting them hard-coded or in your property files.

Cheers,
Jay.
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
To copy portal-impl.jar in hook is not a good practice to follow.


It is more than that, it is not supported.

If you need classes from portal-impl.jar, then your only route is to create an ext plugin.
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
Hi Vincent,

To copy portal-impl.jar in hook is not a good practice to follow.

I think. PropsValues & PropsKeys basically get some values out of property file. Just if those are not many values then you should just give it a try by putting them hard-coded or in your property files.

Cheers,
Jay.


Hi Jay,

Yeah I figured this is not a good thing to do, thanks for the info, I'll first try hard-coding the values, if this still doesn't work I'll create a new project to test if this would work on a ext-plugin just as David told us. emoticon


David H Nebinger:
To copy portal-impl.jar in hook is not a good practice to follow.


It is more than that, it is not supported.

If you need classes from portal-impl.jar, then your only route is to create an ext plugin.


Hi David,

What do you mean it's not supported? I see, ok, if my attempt to solve this using hooks won't work I'll try with ext-plugins, I'll let you guys know once I've got some results, It will probably take me some time to do this, I'll do more research on ext-plugins so I can start as soon as I can.

Thanks!
Vincent
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout (Respuesta)

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
It is more than that, it is not supported.

If you need classes from portal-impl.jar, then your only route is to create an ext plugin.


What do you mean it's not supported?


There should be only one portal-impl.jar deployed, and that one belongs in ROOT/WEB-INF/lib. The Liferay Eclipse plugins will prevent you from including portal-impl.jar.

The only way to get access to classes within portal-impl.jar is to build yourself an EXT plugin. These plugins merge the files/code from your plugin directly into the ROOT web folder (the Liferay base code), and gives you the access to the portal-impl.jar contents.
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
David H Nebinger:
It is more than that, it is not supported.

If you need classes from portal-impl.jar, then your only route is to create an ext plugin.


What do you mean it's not supported?


There should be only one portal-impl.jar deployed, and that one belongs in ROOT/WEB-INF/lib. The Liferay Eclipse plugins will prevent you from including portal-impl.jar.

The only way to get access to classes within portal-impl.jar is to build yourself an EXT plugin. These plugins merge the files/code from your plugin directly into the ROOT web folder (the Liferay base code), and gives you the access to the portal-impl.jar contents.



Hi David,

I see, now I understand how it works (although its just a part of the whole picture), thanks for the help David and Jay. I managed to solve this through your help. Thanks a lot.

Cheers,
Vincent
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
If possible, I'd encourage you to share what you did with the forum. Many times folks come back to the forum looking for a solution to a problem that someone else might have solved in the past...
thumbnail
Vincent Paranpan, modificado hace 12 años.

RE: Hooks - Force user logout

New Member Mensajes: 17 Fecha de incorporación: 14/10/10 Mensajes recientes
David H Nebinger:
If possible, I'd encourage you to share what you did with the forum. Many times folks come back to the forum looking for a solution to a problem that someone else might have solved in the past...


Hi David,

Yeah I definitely agree, it's thanks to you and Jay that I have solved the problem to my system requirement.

While I was finding ways to solve this I stumbled upon a discovery that whenever I tried triggering a response.redirect("/c/portal/logout"), it also calls the LogoutAction event of Liferay which is what I actually needed, so inside my event listener for login.events.post whenever a certain condition is met for force logout I just called the response.redirect(), I don't know if it's the best solution for this, but this fits and works for my requirement. emoticon

I hope I can help others with this thread.

Thanks,
Vincent
MICHAIL MOUDATSOS, modificado hace 12 años.

RE: Hooks - Force user logout

Regular Member Mensajes: 110 Fecha de incorporación: 4/10/11 Mensajes recientes
It appears that this approach is very vulnerable, since redirection can be intercepted from client side!
Definitely, not a good feature of this approach. Can anyone propose something different?

In my particular case I would like to restrain users with the Administrator Role from signing in to the portal using an ext plugin. However it didn't work
I tampered with com.liferay.portal.action.LoginAction . I'm not even sure if this was the appropriate place to try to do it. I added some really simple code:


public class LoginAction extends Action
{

	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
	throws Exception
	{

		ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
		WebKeys.THEME_DISPLAY);

		String login = ParamUtil.getString(request, "login");

		/**
		 * Begin overriding code
		 */
		long userId = GetterUtil.getLong(login);

		if(OmniadminUtil.isOmniadmin(userId))
		{
			//System.out.println("User " + userId + " is an omniadmin, hence it is not allowed to login");
			throw new AuthException();
		}

		List<role> roleList = RoleLocalServiceUtil.getUserRoles(userId);

		for(Role role : roleList)
		{
			//System.err.println("role.getName() " + role.getName());
			if(role.getName().compareTo("Administrator") == 0)
			{
				//System.out.println("User " + userId + " is an Administrator, hence it os not allowed to login");
				throw new AuthException();
			}
		}

		/**
		 * End overriding code
		 */
</role>


I couldn't even see my debugging printlns on console...

I'm still troubled if I can do it from hook or if I have to do it from an ext plugin

Any ideas?
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
MICHAIL MOUDATSOS:
In my particular case I would like to restrain users with the Administrator Role from signing in to the portal using an ext plugin.


That's like trying to prevent root from logging in at the console. Why would you want to do this? You would lose the ability to log in and manage your portal instance!


		if(OmniadminUtil.isOmniadmin(userId))
		{
			//System.out.println("User " + userId + " is an omniadmin, hence it is not allowed to login");
			throw new AuthException();
		}

		List<role> roleList = RoleLocalServiceUtil.getUserRoles(userId);

		for(Role role : roleList)
		{
			//System.err.println("role.getName() " + role.getName());
			if(role.getName().compareTo("Administrator") == 0)
			{
				//System.out.println("User " + userId + " is an Administrator, hence it os not allowed to login");
				throw new AuthException();
			}
		}
</role>


I couldn't even see my debugging printlns on console...


Don't know if you're aware of it, but your printlns are commented out...

Omniadmins are a very special class of admin, ones who are supposed to be able to log in even when the LR database is down.

Admins you really should only have a small handfull of them, there's no reason to block them from logging in you just drop em an email saying "don't log in".

Anyway, rather than trying to fix this horribly broken idea, perhaps you could share w/ us what you need to do and we can point you in a better direction.
MICHAIL MOUDATSOS, modificado hace 12 años.

RE: Hooks - Force user logout

Regular Member Mensajes: 110 Fecha de incorporación: 4/10/11 Mensajes recientes
Excuse me in advance, for the lengthy answer ( I know first-hand you personally dont like them)

David H Nebinger:
MICHAIL MOUDATSOS:
In my particular case I would like to restrain users with the Administrator Role from signing in to the portal using an ext plugin.


That's like trying to prevent root from logging in at the console. Why would you want to do this? You would lose the ability to log in and manage your portal instance!

Yeah, more precisely, it is like trying to restrain guests from accessing the access-interface of admins, which in Liferay case is the same for every type of user. However, this is not an one-time, permanent and irreversible change if you do it via hooks, which was my initial approach. Removing the hook from the webapps directory would instantly lift the administrator "embargo". No? So every time it would be needed the abilityto log in as admin would be possible. For the rest of the time it would be impossible, and therefore not having to worry about brute force attacks ctra.....


Don't know if you're aware of it, but your printlns are commented out...

Yeah I know I was implying that they did not show when they were not commented out.

Anyway, rather than trying to fix this horribly broken idea, perhaps you could share w/ us what you need to do and we can point you in a better direction.


Sadly, it is not some capricious idea of mine. Client has really but REALLY strict security considerations. I'm in a quest of trying to shutdown access to everything but the limited things our web application should provide access to. I was even thinking of making an individual post about it, but I thought I should better try to search the forum for every individual case I have to confront, at least I think that is what admins of forum prefer (search before post). And going back to client beliefs, I tried to explain them the philosophy behind the design of Liferay access, at least to the best of my understanding, i.e. that Liferay has a single entry point for all type of users and from that point, their ability to do or not do things (administrative or not) lies in their assigned role. Too bad they used as a counter-example joomla, which has a completely different approach, where the admin panel is accessed from a different interface (trying to point out that you know what and how to control). Hence the need to restrain administrator access.

In a nutshell, our web application, which was built on portlets exposed through liferay, provides access to sensitive information and takes advantage of Liferay's robust user management system, password policies,and its many parameterization possibilities. On the contrary there's no need for any other functionality, especiallly the social-like ones (public private pages, blogs, chats, rss, ctra). I ve managed to restrain access to control panel and per-user pages using hooks and parameters in portal-ext.properties. But I still have a long way to go to find every functionality that could be accessed through urls and find a way (probalby event handling hook) to redirect it to some access denied page. I WOULD like to create a post asking - don't know whether I would get answers though.
thumbnail
David H Nebinger, modificado hace 12 años.

RE: Hooks - Force user logout

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
MICHAIL MOUDATSOS:
Excuse me in advance, for the lengthy answer ( I know first-hand you personally dont like them)


Well, I was in a bad mood that day, I think... emoticon

Yeah, more precisely, it is like trying to restrain guests from accessing the access-interface of admins, which in Liferay case is the same for every type of user.


Oh, I see now. You're looking for the 'simple user' interface, where they can log in but do not get to go to the control panel at all, right? If so, friend me and I'll send you some code that I have that may work for you. Basically it's a hook/theme combo that removes the elements if the user does not have admin and/or power user roles. They can log in and see content, but the entire dockbar is left out.

Removing the hook from the webapps directory would instantly lift the administrator "embargo". No?


Sure, but it ends up being an administrative nightmare - undeploy the hook so you can make admin changes (hope the users don't log in while that's going on), then redeploy the hook when all changes are complete... Ugh...

Sadly, it is not some capricious idea of mine. Client has really but REALLY strict security considerations.


Ours was not due to security reasons, it was usability. We didn't want to have to train our clients on how to use the dock and the contents therein....
MICHAIL MOUDATSOS, modificado hace 12 años.

RE: Hooks - Force user logout

Regular Member Mensajes: 110 Fecha de incorporación: 4/10/11 Mensajes recientes
David H Nebinger:

Basically it's a hook/theme combo that removes the elements if the user does not have admin and/or power user roles. They can log in and see content, but the entire dockbar is left out.


That would be very helpful! Since I have already made a theme which hides dockbar, the hook you mention must be what I want, assuming that it contains all the event handling, triggered by any possible administrative action!!

Thank you again for your time!

PS My ext-code was not working because I had not completely cleaned out the installation of a previous ext plugin, as it is stated in hot deploy ext plugin. After successfully installing the ext-plugin, still it doesn't do what I expected. a) for some reason it changed all my settings (theme, method of login) after rebooting tomcat (Correction: an empty portal-ext.properties file which was forgotten in ext plugin path did the damage), and b) LoginAction runs when I access the login portlet - not when I hit the sign-in button. So guess I'm looking at the wrong place for overriding login authentication code...

PS2 It seems that, indeed, I was looking in the wrong place. I was looking into com.liferay.portal.action.LoginAction. The correct place was com.liferay.portlet.login.action.LoginAction in which I noticed that com.liferay.portlet.login.util.LoginUtil.login() is called. I chose to override the latter class's, login method to do my job with the exact code I presented earlier and it worked.
Joan Fluvia, modificado hace 10 años.

RE: Hooks - Force user logout

New Member Mensajes: 13 Fecha de incorporación: 6/11/13 Mensajes recientes
After 2-3 days of investigating I achieved logging in and out with ajax calls. To logout it is not as simple as calling the session.invalidate() but there is only a little more to configure. I will write how I achieved this:

First edit your portal-ext.properties and add this line:
session.enable.phishing.protection=false

Then in ALL of your portlets you have to set the private-session-attributes to false. The ordering is important so I'll show you mines:

<portlet>
<portlet-name>home</portlet-name>
<icon>/icon.png</icon>
<instanceable>false</instanceable>
<private-session-attributes>false</private-session-attributes>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/home.js</footer-portlet-javascript>
<css-class-wrapper>home-portlet</css-class-wrapper>
</portlet>

Once did this the rest is pretty simple. For log in:

public static void login(ResourceRequest request,ResourceResponse response, String liferayUser, String liferayPassword) throws Exception{
MethodKey key = new MethodKey("com.liferay.portlet.login.util.LoginUtil", "login", HttpServletRequest.class, HttpServletResponse.class, String.class, String.class, boolean.class, String.class);
PortalClassInvoker.invoke(false, key, new Object[] { PortalUtil.getHttpServletRequest(request), PortalUtil.getHttpServletResponse(response), liferayUser, liferayPassword, false, null});
}

And for log out:

public static void logout(ResourceRequest resourceRequest) throws Exception{
HttpServletRequest request = PortalUtil.getHttpServletRequest(resourceRequest);
request.getSession().invalidate();
}

I used ResourceRequest because i was doing Ajax calls. The only "problem" is that if you are logged in and want to logout & login with another user you have to do 2 ajax calls (the second one once returned from the first one).