Does LDAP provide a token after binding, so I don't have to send credentials every time? - ldap

I have a web application (PHP, but doesn't matter). It uses LDAP for authentication (already working), and it allows users to search LDAP (already working).
But when searching, I use a generic process account to bind() and then run the search().
What I would like is to use the LDAP account that logs in to be the same account that binds for the searching. But the only way I see to do that is to store the user's credentials in the sessions (bad!).
Nutshell: can I get a "state/session/??" token from LDAP, to bind() and then search() on subsequent http requests?
(btw, using Active Directory.)

Basic LDAP doesn't provide anything like this. The credentials that you present when binding are used for the rest of the connection, so if you could keep an LDAP connection open across multiple HTTP requests (and share LDAP connections among however many server jobs you have running), then you could avoid saving credentials.
There are various extensions to LDAP floating around (including several within Active Directory), so it's possible that one of those adds sessions-across-connections, but if so, I'm not aware of it.
As a sort-of-workaround, because Active Directory supports GSSAPI and because of how Kerberos works, you ought to be able to use the user's credentials to request a Kerberos ticket for accessing LDAP then store that ticket as your "state/session/??" token. This Kerberos ticket would only be valid for accessing LDAP and would auto-expire, so this would avoid the pitfalls of storing the user's credentials in the session. I don't know if your LDAP library supports GSSAPI and would give you enough control to do this or not.

Related

Use keycloak as auth service or IDP?

So, im doing research to know if its a good alternative to implement keycloak on the environment i'm working at.
Im using LDAP to manage users at my workingplace. I was wondering if is there a way to use keycloak as auth service in all upcoming systems and some of the existing ones. We are currently managing it with an IDP that we need to improve or replace, also there are some systems use their own login (this will eventually change).
The main problem i've crossed is that keycloak synchronizes against ldap and i dont want user data to be stored on keycloak, maybe if its only login data. User data is planned to be kept only on ldap's database in case that any userdata needs to be updated.
So is there a way to use keycloak only as an auth service fetching user credentials from ldap on every auth request?
pd: maybe i am mistaken on the meaning of what's an auth service an whats an IDP.
Actually it is not necessary that LDAP users are synced to Keycloak.
Keycloak supports both options
Importing and optionally syncing users from LDAP to Keycloak
or
Always getting the User info from LDAP directly.
But keycloak will always generate some basic federated user in it's database (e.g. for keeping up a session when using OpenID Connect - but you should not really care about that).
As far as I know (but I've not used that myself) you could also use keycloak to maintain the LDAP users data and write changes back to LDAP (see "Edit Mode" in Keycloak documentation)
Check Keycloak documentation regarding LDAP stuff to get more information https://www.keycloak.org/docs/6.0/server_admin/#_ldap
Beside the User-Data Topic, Keycloak provides a lot of different Protocols (like SAML and OpenIDConnect) to provide authentication for your services. So you could use different/multiple authentication protocols depending on your applications with just one "LDAP-Backend"

OpenAM + two LDAP servers

I'm a newbie in the LDAP + Liferay + OpenAM world, so I wonder if someone could point me in the right direction in a problem I have. In a real life environment, there are 2 LDAP servers, a OpenAM server and a Liferay application. What the customer needs is to authenticate users in Liferay against OpenAM, and OpenAM should use the LDAP servers. Problem is, the user exists only in one of the LDAP servers (it will be moved from one to the other in one point of the future). What the customer wants is:
Users must be able to authenticate independently of what LDAP contains the user.
The obtained token must be valid for both LDAP servers, as it will be used in a different service (I have no control over it) against only one of them to validate authentication.
As I said, I'm new to this world so, if the answer is too complex (I'm afraid it will be for me), maybe you could point me to books or docs that could resolve this scenario.
Thanks
You should configure LifeRay to use OpenAM for all authentications and you can configure OpenAM to use both LDAP servers (use different realms).
Details for OpenAM configuration will be in the OpenAM documentation.
As the previous answer states you should route all your authentication requests to the OpenAM server and let it validate the credentials against the right LDAP server. Using two different realms (one for each LDAP server) won't work in your case since that will require LifeRay to know where to find the user before hand. Also, sessions are linked to a specific realm.
There are multiple solutions to your problem. Here are just a couple:
Option 1
If you have control over the authentication flow. That is, if your application uses a custom UI and communicates with OpenAM via REST, you could create two different authentication module instances under a single realm (let's say two instances of the DataStore authentication module) each one pointing to a different LDAP server.
Let's call this module instances DataStore1 and DataStore2. Your application can collect the user credentials (username and password) and submit them to DataStore1. If authentication succeeds the user is already logged in. If it fails, the application can try with DataStore2.
Of course this is not ideal since you'll be making two authentication requests per login instead of just one.
Option 2
A better option (though more complicated to implement) would be creating a custom authentication module. This module can try authenticating the user against LDAP Server 1 and then try with LDAP Server 2 if the first authentication failed. Notice that with this option you don't need custom logic on the application side since it will only send a single authentication request to the OpenAM server. In fact, you can protect your application with an OpenAM Policy Agent.
Another advantage of this approach over Option 1 is that you can migrate your users behind the scenes assuming that the end goal is to migrate users from LDAP Server 1 to LDAP Server 2. If the first authentication succeeds your custom code could read the user entry from LDAP Server 1 and copy it over to LDAP Server 2.
Hope this helps you solve the problem.

How to configure LDAP authentication module instance in OpenAM

I am trying to protect a Java servlet with OpenAM + J2EE tomcat agent. I got this part working by using embedded OpenDJ of OpenAM.
Now I am trying to authenticate against a LDAP server, so I added a LDAP module instance for OpenAM, but I get "User has no profile in this organization" when I am trying use uid/password of an user from that LDAP store.
I checked OpenAM administration guide on this the description is rather brief. I am wondering if it is even possible to do this without using the data store configured for OpenAM?
The login process in OpenAM is made of two stages:
Verifying credentials based on the authentication chain and individual authentication module configurations
User profile lookup
By configuring the LDAP authentication module you took care of the authentication part, however the profile lookup fails as you haven't configured the user data store (see data stores tab). Having a configured data store allows you to potentially expose additional user details across your deployment (e.g. include user attributes in SAML assertions or map them to HTTP headers with the agent), so in most of the scenarios having a data store configured is necessary.
In case you still don't want to configure a data store, then you can prevent the user profile lookup failure by going to Access Control -> <realm> -> Authentication -> All Core Settings -> User Profile Mode and set it to Ignore.
This is unrelated to authentication but it's related to authorization ... you have to configure appropriate policies ... see OpenAM docs.
Agents will enforce authorization, OpenAM determines if the user has the permission to access a protected resource.
As Bernhard has indicated authentication is only part of the process of granting access to a user. He is referring to using a Policy to control access.
Another method is to check if the authenticated user is a member of the desired group programmatically. This can be useful when you want access control over resources that OpenAM doesn't know about (e.g. specific data).
For example, lets say that you want different groups to have access to different rows in a table in a database. You can retrieve the group information associated with the user and add that to your database query, thus restricting the data returned.
I'm sure that you could do this with OpenAM as well using custom modules to allow the policy to use information in the database as resource, but I've found it is much simpler to perform this fine grained access control in your code, and is in all likelihood significantly faster.

User Authentication in hadoop Hdfs

I have integrated milton webdav with hadoop hdfs and able to read/write files to the hdfs cluster.
I have also added the authorization part using linux file permissions so only authorized users can access the hdfs server, however, I am stuck at the authentication part.
It seems hadoop does not provide any in built authentication and the users are identified only through unix 'whoami', meaning I cannot enable password for the specific user.
ref: http://hadoop.apache.org/common/docs/r1.0.3/hdfs_permissions_guide.html
So even if I create a new user and set permissions for it, there is no way to identify whether the user is authenticate or not. Two users with the same username and different password have the access to the all the resources intended for that username.
I am wondering if there is any way to enable user authentication in hdfs (either intrinsic in any new hadoop release or using third party tool like kerbores etc.)
Edit:
Ok, I have checked and it seems that kerberos may be an option but I just want to know if there is any other alternative available for authentication.
Thanks,
-chhavi
Right now kerberos is the only supported "real" authentication protocol. The "simple" protocol is completely trusting the client's whois information.
To setup kerberos authentication I suggest this guide: https://ccp.cloudera.com/display/CDH4DOC/Configuring+Hadoop+Security+in+CDH4
msktutil is a nice tool for creating kerberos keytabs in linux: https://fuhm.net/software/msktutil/
When creating service principals, make sure you have correct DNS settings, i.e. if you have a server named "host1.yourdomain.com", and that resolves to IP 1.2.3.4, then that IP should in turn resolve back to host1.yourdomain.com.
Also note that kerberos Negotiate Authentication headers might be larger than Jetty's built-in header size limit, in that case you need to modify org.apache.hadoop.http.HttpServer and add ret.setHeaderBufferSize(16*1024); in createDefaultChannelConnector(). I had to.

Test an application using LDAP

I am in the preparation phase of testing an application that will be using LDAP for user authentication. What are some tips or advice you might have for this endeavor?
I don't have a great understanding of LDAP but I believe all that will be used is the application client calls to LDAP with a username and sees if the password matches. Is that an accurate description? Also, what are some edge cases to test? Thanks.
LDAP authentication is often (but not always) a 2-step process: first the application does an LDAP query to locate the "distinguished name" (dn) of the account the user's trying to authenticate to, then it tries to log in ("bind", in LDAP parlance) as that dn, using the user-supplied password.
If the "bind" attempt works, the application knows the password is correct. (The LDAP server is likely not configured to allow the application to actually extract the password and do the comparison itself, for obvious security reasons).
An LDAP-enabled application will typically require a way to configure:
hostname/port of LDAP server
search base (e.g., dc=mycompany,dc=org)
user search filter (e.g. "(|(cn=%userid)(mail=%userid))")
application credentials for the initial LDAP query (unless the server allows anonymous queries)
You will most likely need to support SSL, so you don't send the user's password to the LDAP server in cleartext.
This strongly depends on your technology.
If you are directly querying the ldap you have to care about performance e.g. how fast are your queries, how often you have to do them and if you server is sized appropriately.
If you are using some kind of container that it providing SSO then these will usually have some caching features, etc.. There you have to check if everything is working properly.
You would need ldap_connect and ldap_bind functions. Also once you are binded with the ldap server you can search for entries on the ldap and get the user information.
You should surely check if encodings are handled properly (try umlauts or other weird stuff in passwords).
And take care to test with the LDAP servers you care about, Active Directory, OpenLdap, Apaches LDAP Server, and a few others, they might show different behaviours.
Also check if the client handles 'referrals' correct, e.g. when you try to lookup users in a different domain (e.g. two AD forrests with forrest trust installed).