I have implemented authentication using Liferay LDAP.The problem is LDAP only imports users:
On startup of server
When a modified user try to login (only data specific to it is imported\updated)
I want to import/update users whenever there is a change in my active directory
What I have tried:
Import interval property
This will cause my application to slow down when there will be a large set of users
If you want to trigger an update on change of AD, you'll have to extend AD to push to Liferay. Liferay has an API (even a remote one) that you can trigger on every change in AD. As you say that you can't pull (through a more frequent import), this is your option.
On the other hand: Most of the time, it's not necessary to have the very latest information in Liferay at all times. Latest when a user logs in, their data will be updated anyways. If a user is deactivated in AD, they will be deactivated in Liferay latest when they try to log in.
Edit: As you state that your Liferay-Users are acting on data of the other uses, it feels like you should rather develop an appropriate LDAP frontend, maintaining or using the underlying data in LDAP (AD) instead of the Liferay user database. This is yet another option.
And no, sorry, I can't provide any references for AD. As of Liferay's API, it depends what you need: User, UserGroup, Organization, Roles etc. all have their own services that you can use to implement whatever you need. An abstract description on what you need to do goes well beyond what's possible in a simple answer on SO though, especially given the amount of details that you provide in your question.
Related
I have been testing a web application with Spring MVC, and I'm currently developing a editor page for accounts. This JSP page is able to edit one or more accounts, serving for different purposes. For example, a common user can edit account data on this page. On the other hand, administrator users can edit multiple accounts on this page. In terms of logic (for me), the edition of multiple accounts to an administrator user works like this:
The user selects a list of accounts.
The list reaches the controller.
The controller stores the list of accounts.
The controller directs the user to the edit page.
The user fills out the editing form.
The form is sent to the controller.
The controller retrieves the list of accounts previously saved.
Editing form data is reflected in the list of records.
The list is deleted from storage.
My problem appears when the user does not perform step 5, and decides to do something else. Without the removal of the list from storage, the server will suffer from memory leak. It would be very important to detect the user's exit, which would cause the system to remove the list automatically.
I'm choosing to save the list of accounts to be edited on the server side to prevent it from being saved on the user side, where the user could well tamper the data.
I might as well use JavaScript to detect when a user leaves a page, but he/she may well turn off Javascript, which results in the same problem. Therefore, this is an impractical solution.
I have not yet developed the implementation of it, so I'm just projecting right now. Can anyone help me with this? Am I doing something wrong?
Is there an error in my logic, or am I leaving something of use?
OBS: I'm using Tomcat 8.0, and Spring MVC 4.1.1, with the Java JDK 8.
That's the whole purpose of session management. Your web server does it for you.
When you use Java EE or any other session technology, the server is supposed to deal with timeouts, cleaning the session objects. This happens based on user idle time. How does the server know users are idle? Because for every request sent by the browser, his session id is sent in a cookie.
Usually, the timeout threshold is a changeable period of time (usually defined at web.xml). This value may need to be tuned, based on the available network/memory resources and expected simultaneous users.
In fact, sessions+cookies are the only flexible and secure way to deal with the stateless nature of HTTP.
There are variations of this, namely, conversation or view scopes, where the user may have a session per tab. But the principle is the same: put stuff in session and get them later by session id (a cookie at client side).
Finally, you should not rely on the browser to do server stuff. This would not be reliable.
I have two Java wepapps potentially on different domains/servers using Spring Security for authentication. The first is handling authentication locally storing users in the application database. For the second, I would like to authenticate users using the same users accounts than the first webapp with single sign on (if a user is authenticated in the first webapp, it shouldn't have to enter his info again in the second).
I identified three potential ways to do this but it doesn't seem very straightforward:
Shared cookies: Using a shared session cookie and the same database for the two applications. It seem relatively easy to do but the two webapps need to be on the same domain which isn't necessarily the case for my applications.
Directory service: Using a central directory service (LDAP) which would be used by the two webapps to handle authentication. It seem pretty heavy to implement and the users can't be stored in the first webapp database anymore. The existing users accounts would need to be migrated into the LDAP and it would not be possible to create new users using the first webapp.
OAuth: It seem to be be possible to make the first webapp handle external authentications requests by providing an OAuth api (like Google sign on kind of service). That would allow the second webapp to use this api to authenticate the users, but I'm not sure that the signin process would be totally transparent to handle single sign on. It doesn't seem very easy to implement either, as it would necessitate the development of a complete OAuth api in the first webapp.
I also looked at this service https://auth0.com that seem to provide an authentication api that can be interfaced with an external database, but I'm not sure that it can be interfaced with Spring Security and it also mandate the use of an online solution which isn't ideal. I'm not sure that it would handle single sign on either, only shared accounts.
Is there any other way to handle this use case that would be more straightforward?
CAS is a good candidate indeed as a SSO system for your need and it has several CAS clients for Spring Security. You can try for free a CAS server v4.0 at CAS in the cloud: http://www.casinthecloud.com...
As you mentioned, a shared cookie won't work across domains.
LDAP would give you shared credentials (single name/pw works for both systems), but not single sign on, and you notice you'll have provisioning issues.
Not knowing anything about Spring Security, odds are high you won't find a painless solution to this. Integrating SSO is fraught with workflow issues (user provisioning, password recovery, user profile maintenance, etc.)
We had a classic DB managed authentication scheme. Later, when we added LDAP support, we added the capability for "auto-provisioning". This basically consisted of having the application pull down the relevant demographics from the LDAP store during login, and simply updating fields each time user logged in. If the user didn't exist, we'd create one on the fly.
This worked well, because the rest of the application had no awareness of LDAP. It simply worked with the user profile we managed already and if it needed something from the DB, the data was there.
Later, when we integrated SSO, we just leveraged the existing LDAP logic to pull from the SSO server and do the same thing.
This workflow helped a lot with provisioning and management. We could maintained the authoritative source (LDAP, SSO), and the app just kept up. What it hindered was local editing of the user profile, so we simply disabled that. Let them view the profile, but they could go to the other systems portal for management. Inelegant, but it's a rare use case anyway, so we just muddled through it. We eventually worked out two way pushing and replication, etc. but it's a real pain if you don't need it.
You can look here if you want an overview of how to do cross domain SSO: Cross Domain Login - How to login a user automatically when transferred from one domain to another
For our SSO, we use SAML v2 Web Profile, but we ended up writing our most of our own code to pull it off.
But, bottom line, no matter what the web sites say, integrating this is non-trivial. The edge cases and workflow/help desk issues that surround it are legion. And it can be a bear to debug.
I am developing a java web application using JSF and I will like to find out if it is possible for me to hold (and save) user information in an different location, say a file, and then when the user confirm their email before the date is save to the database.
I don't yet understand certain thing. What I intend to know is if it is possible to use serialization for this problem.
You need to persist the user on the database before it has confirmed its email.
You need to set him a status NOT_CONFIRMED which can be transformed to CONFIRMED.
Until he has confirmed, you should not allow the application login for users which are found, but having an illegal status like NOT_CONFIRMED.
There's no benefit in saving the user data somewhere else for most usecases.
HTML5 proposes the local storage API which permits storing data in the browser of your client. Since the user is not logged, you'll be unable to recognize him from another computer, so it's fair that the data will be available only on the browser he wrote it in.
You can then transfer the data to your server once the user is connected (htis feature is used by Google documents, offline gmail etc...). If you're using GWT, a java API is available to access the native browser API, otherwise, you'll need some js coding
Best Regards,
Zied Hamdi
http://1vu.fr
RESOLVED. This question can be deleted by moderators
I have a very simple site written using Java EE (JSPs, Java, Tomcat server). I want to implement a simple login system. I thought I got the registration and login working; however, there is a huge problem with the way I'm doing it.
Let's say Alice logs in. She is able to view her profile with her information, everything looks normal so far for Alice.
Then Eve comes around and wants to log on. She does and is taken to her profile, everything looks normal for Eve.
Then Alice reloads her profile to find that the site now has her logged in as Eve!
So to reiterate: after one person is logged in, anyone is able to go to the site and be logged on to that account. And the most recent person to log on is the active account.
How do you keep track of session information like this so that multiple different accounts can be logged on using the site at the same time?
Thanks!
EDIT:
This ended up being a very simple fix.. I just need to use setAttribute("EMAIL", userId); rather than the stupid way I did it which was just using a global String variable
Rather than try to roll your own security, use an existing framework, like Spring Security. Out of the box, it gives you basic login capabilities and handles securing pages using a role-based authentication scheme.
Reading your problem, I think that you store the last logged user's credentials in an instance variable of one of your servlets. This causes the last person to log in to overwrite everyone's credentials...
If you want a simple authentication, you can use Java EE's provided system :
http://docs.oracle.com/javaee/5/tutorial/doc/bncbx.html
Once a user logs in, put his own credentials in his Http session (request.getSession().put(username, )). Then, everyone will have a distinct profile.
I have an application built on Spring MVC that uses Hibernate for all of it's DB interaction needs. There is now a need to update the application to use our LDAP infrastructure to drive the user information, including basic user data, such as name and email, as well as authentication and authorization needs as well.
Since everything has been in one spot (the DB) up to now, the reports are all fairly straightforward, since Hibernate is managing retrieval of information as needed when starting with the required queries. Grabbing the users' name, etc. is very simple, since Hibernate loads the data lazily.
With the desire to drive the user information with LDAP, Hibernate will no longer be able to populate the user information on the fly, since it won't be managing the users' data. How should we use LDAP to drive the user data and deal with authentication / authorization without causing to much pain when we need to grab user data like Name, etc.?
We have considered using a hybrid approach where LDAP is treated as the "source" for the data and the current system is left as-is. This would require changes to the transaction processing code to update against LDAP so that the live transaction is using up-to-date information, and also a periodic sync against LDAP to keep the application DB up-to-date for reporting purposes.
This solution seems a bit hacky, and seems to have a lot of moving parts, but I could not find much on this subject elsewhere on the web.
How should user information be handled / how should the app be structured so that all of the user information is still easily accessible and can be easily tied to the rest of the system for reporting purposes? Is there a way to integrate Spring LDAP and Hibernate so that layers above the data layer don't have to know? Or is pulling the info from LDAP into the existing database the easiest way to go?
If you can not drop the user table at all, because it is used from other entities, then my suggestion is to separete the security stuff from the business stuff.
This mean remove the only for security needed information from the user table (login, password, ...), so that only the stuff remains that is needed to implement the buiness cases.
Then rewrite the security stuff so that is is based on the LDAP. I guess you find a way to get the user data base object for an given prinipal.
Only one thing will remain, how to create new user database entities if a new person get a new login. You have 3 choices, what is the best one strongly depends on your application:
Create the database entity if the users first login
Create the database entity if you first need it
Create the database entity when it is created in the LDAO (or some minites later) for example with an cron job, or some Spring Scheduling service.