Symfony 3 LDAP authentication populate database with all users - php

I'm trying to implement an authentication system and I'm unsure of the correct way to components to use in the Symfony security component.
In essence, what I want to do is authenticate users against an LDAP server, but also have access to User objects for the purposes of database queries (e.g. listing all users in a dropdown).
Now in the LDAP tutorial it states:
Checking a user's password against an LDAP server while fetching user information from another source (database using FOSUserBundle, for example).
However, it doesn't really go into any explicit detail about how this is done. How can I create User objects from the LDAP server? I just want to store usernames, emails, and roles - I don't need passwords since I want to do actual authentication with the LDAP server itself.
Or am I better off to not use User entities in a database, and instead grab all the user information from the server whenever someone logs in (so that it's up to date)? If this is the case, how do I fetch this information when someone logs in, and use it in a similar way as I would a set of User entity objects?

Related

How to know the objectGUID of a user that successfully authenticated with LDAP bind

I have:
a PHP application on a linux server
a (windows server 2012) domain controller
I want to make it possible for AD users to log in the PHP application. The PHP application will associate data to the user, so i need to create the user in my database.
When a new user is created in the PHP application, the administrator chooses from a list of the userPrincipalName of the AD users. When a userPrincipalName is chosen, the PHP gets the objectGUID of this user and stores it in the database. Indeed, as the UPN could change, i can not rely on that to uniquely identify the user. Also, i want that if the UPN changes, the user can sill log in seamlessly to the PHP application, with his new UPN.
When a user wants to log in my application, the PHP receives a username and a password, and pass them to ldap_bind to check if the credentials are valid. The problem at that point is that ldap bind gives no clue of what user he actually identified (ldap_bind has a complicated logic of validating a login/password (https://msdn.microsoft.com/en-us/library/cc223499.aspx)).
The most atomic (and hence, reliable) way of doing it would be if ldap bind was returning the objectGUID... But it doesn't, and i won't code the logic of ldap bind in PHP to find which user he has actually identified (it would be buggy anyway because of race condition if the directory change between the ldap bind and my "manual" search)
So what should i do to authenticate AND identify the LDAP user from PHP, if possible, in a single request to the domain controller (to get atomicity) ?
At some point in the process you need to have logic that searches for the UPN being used for the username in the login, obtain its objectGuid, and search for that objectGuid in the database. There is no other way to get that information.
If you're worried about a potential race condition (which seems like quite the edge case, given the timing between the bind and the search would be extremely tight), you could use a separate AD service account that searches for the account by UPN prior to the bind. Then in the ldap_bind for checking the user's credentials you could even use the objectGuid from the account you searched for to do the login, as that's a valid "username" for an AD bind (the GUID with curly braces around it that is).

Wordpress plugin to authenticate on LDAP or NTLM and handle roles

In my company we have some technology restrictions. Currently I have a IIS server with PHP. IIS is configured to authenticate users over our Active Directory using NTLM.
I have installed WordPress on this server and am able to login on it using admin user (id=1), and any user is able to read articles and post comments anonymously.
"Thanks" to NTLM, I can retrieve users' login with $_SERVER['REMOTE_USER']. This way I can identify (in a plugin) users. But WP doesn't automatically logs them and identifies them.
What I need now is to control users permissions inside Wordpress. I need to attribute roles to them, define groups of people allowed to publish, post and edit without being allowed to publish, comment and register their login on their comments, and also users that are allowed only to read articles (guests) and users not allowed to read articles. Maybe I'll also need to attribute read access relating roles to categories, so that a given role is allowed to read articles from a category and not from another category.
Users are related to departments and have one charge (job title). Users are frequently moving over departments and changing charge. I need to use both to define some roles. I can develop a plugin to hook on some WP filter, retrieve their data and dynamically set their role.
To retrieve their department, charge and name, I could use LDAP. If not possible, I have a MSSQL database that also has their data. So, if I can't use LDAP, I'd need to make WordPress connect to MSSQL and query it.
It's unpractical to register tens of thousands of users in WordPress, and even more to request them to keep their passwords. I need WordPress to identify users and automatically add new ones to its wp_users table. I also need to be able to manually register a few users without requiring them to first enter the site. I then can manually manage users to WordPress roles.
I see 3 possible solutions here:
1) Use IIS's NTLM to authenticate users, and use $_SERVER['REMOTE_USER'] to retrieve their login and log them into WordPress. If they aren't yet registered on wp_users, that's done so. I then query MSSQL for their data. This seems to be the easiest solution.
2) Use IIS's NTLM to authenticate users, and use $_SERVER['REMOTE_USER'] to retrieve their login. Then retrieve their names from AD using LDAP, and provide these data to authenticate WordPress and handle wp_users. This is the most desired solution, but also the most complex.
3) Ignore NTLM and require users to manually provide their login and password to WordPress's login form, then authenticate them over LDAP and handle wp_users. Provided password is their AD one. HTTPS is already working and being forced inside backend. This is the least desired solution, because users are already used to be authenticated from NTLM and may not want or understand the login form (yes...).
Has anybody done that and could help me? Is there a plugin that solves this need, or some open source code I can use as basis to develop a plugin?

Laravel LDAP and Database connection

I have several different types of users who use my system. One set of users is unique as all their credentials are accessed via LDAP, the other users are all relatively similar but do have different roles. I am using the built in User class for the regular users (that is, not the ones who login using LDAP) and am using Laravel 4. I query the LDAP and it returns either success or failure but once I've done that I don't have a user logged in per se. I set up a "fake" user in the Users database, which I could then manually authorise by using it's id
Auth::loginUsingId($user_id);
In this case, when I have verified their details via LDAP I manually authorise them using the dummy account. In this sense, every user who logs in with LDAP credentials is authorised as this single dummy user. While this works it means making a redundant User with false information and it is just generally quite messy. Furthermore, I lose the rich information the LDAP provides.
Effectively, I'd like to be able to authorise a user when they are not actually a User according to the Users table. I believe the solution may lie in altering the UserProviderInterface.php or the EloquentUserProvider.php.

Do my web app's users need direct access to my database?

I'm creating a web app that users will create an account for, which allows them to read/write data on a database. I'm about to start creating the login authentication part of the website, and its my first time really doing this part. As I understand it, I'm going to create a users table which will store all the necessary login info for the website.
I know there are also database roles/permissions. My question is about how the 2 relate in this instance. Do I need to authenticate the users on the website and the database? My thought process was that if all of my PHP scripts are set up in such a way that the session data will only allow authenticated users read/write to the DB, then I don't need to do anything on the database end, but I want to make sure I'm thinking about this correctly.
Is that clear as mud?
If I understand correctly, your question is wether or not your users need access to your database.
Your users are not going to communicate with the database directly. Your app will. Your users are only going to use your app which will act as an interface between the user and the database.
Therefore, only the app needs access (and the appropriate permissions) to the database. Because it now has access to the database, it becomes responsible for making sure that only the right people can perform certain actions. (by means of a login- and permission system)
If not all users should have the same permissions within your app (you might have normal users and administrators), you need to create a permission system within your app that checks wether a user has the appropriate permissions to perform a certain action.
For instance if someone tries to delete some important data, you
make sure he's logged in (if he's not, redirect to the login page)
make sure he has the appropriate role / permissions (in this case he should be an administrator - if he's not, cancel the action)
Symfony's page on Security gives some insight. Just skip the Symfony-specific parts and read about the general idea.
Your users will authenticate on your website (by requesting details about their validity from the database). Once authenticated they can do things that the website gives them access to.
The only user that will communicate with the database directly is you/your website. Your database will have a table entitled 'users', but the actual user of the database should be no one else but you - you don't want to give random users free reign. You can then set what database queries you wish the database to perform on certain users actions.
Hope that helps clarify

PHP: Persisting LDAP connection across requests

I have a (I think not so uncommon) scenario:
my PHP app queries an LDAP server to handle authentication. The LDAP server only accepts authenticated access, so the first ldap_bind() call is actually used as the authentication mechanism and to retrieve the logged in user's basic information.
So far so good. But when I want to use the LDAP service to perform other queries (e.g. the logged in user's or other users' extra info) I have to go through LDAP authentication again.
I do not want to store the user's password in session because it might leak, but I can't have the user authenticate at each request either in order to provide the credentials for the LDAP server.
So I thought about the following solutions:
Store the LDAP connection handle in session, so I don't have to provide credentials every time. That won't work because the handle is a resource and can't be serialized for session storage.
Store the password in session, but encrypted. The encryption seed could be derived from some volatile var, e.g. a hash of the session ID, so that it won't be stored in a var and can never leak.
<Your idea here>
Any thoughts?
Thanks
gm
My two cents... First use case I think could be avoided pulling down everything for the user the first time you connect. Store all of it minus the password in session. Second case: Do you need to authenticate as user X to access that data? Can you not create a user with read access and use those credentials (App user) to query these types of things. Alternately maybe that user info should not live in AD. Use it for authentication but keep user data in the DB (master), or synced in DB from AD (slave).
As for storing the password, this is working (using Yii framework, but it's easy to adapt to vanilla PHP):
public function getUserPW(){
if(empty(Yii::app()->user->sneak)) return false;
$seed=sha1(Yii::app()->session->sessionID);
$iv=substr(md5(Yii::app()->session->sessionID),0,16);
return openssl_decrypt(Yii::app()->user->sneak,self::CRYPT_ALGO,$seed,false,$iv);
}
public function setUserPW($pw){
$seed=sha1(Yii::app()->session->sessionID);
$iv=substr(md5(Yii::app()->session->sessionID),0,16);
Yii::app()->user->setState('sneak',
openssl_encrypt($pw,self::CRYPT_ALGO,$seed,false,$iv)
);
}

Categories