Adldap 2 can connect and find a user but cannot authenticate - laravel

Question: why can I not authenticate a known registered user through Adldap despite being able to access information about the user using Adldap on laravel 5.2?
I am attempting to use Adldap on laravel 5.2 to authenticate users at a university. I have successfully managed to connect to the ldap server with the admin credentials and can even retrieve information about the user.
`
namespace App\Http\Controllers;
use Auth;
use Input;
use Adldap;
class AuthController extends Controller
{
public function authenticate()
{
$username = Input::get('username');
$password = Input::get('password');
$authentic = Adldap::authenticate($username,$password);
$userData = Adldap::users()->find($username);
var_dump( $authentic );
dd( $userData );
}
}
`
when I try to log in, dumping $authentic gives me false despite having the correct password (I dumped it as well to check). However, with the same username if I dump $userData i get a massive array of (correct) user information. Using my username, if I open the $userData object up I can see what email groups i'm in, my campus mailing address, my work title etc.
Dumped variables. I am very new to using ldap and am not quite sure how everything works. Also, its probably worth noting that despite me being the guy doing the setup and such I do not have much access to the servers. Everything is on an as needed basis.
One though was that the ldap server took care of any password hashing on that end. However, since i'm getting connected but the authentication fails could it be that I need to hash the password on my end? Please explain any solutions in detail. As an Ag engineer none of this is exactly my field but sometimes branching out is a necessity.
There are no errors. I'm on wamp and in logs/php_error (I assume this is the equivalent local version of /var/log/debug). Additionally, apache_error shows no problems.

You better check the messages created in /var/log/debug while trying to log in. Please add these messages to this post.

There was no "error" on my end. The Ldap server was simply configured to accept the users full email address and not their short id as I was using.

Related

How to implement ForgotPasswordController in SPA application with Laravel/Sanctum?

I'm using Laravel 7.x and sanctum. Logins are working and I would like to create a Forgot Password option from my SPA application.
I'm struggling with the basics as most of the examples in the documentation rely on the auth scaffolding. So far I've managed to get the following:
I have a controller class called ForgotPasswordController with a method called reset that receives the email to be reset via POST.
I've created a object: $user = User::where('email', $email)->get()->first();
At this point I'm too unfamiliar with the architecture to know where to go next, whether it's the Password facade, I see some additional classes in the Illuminat\Auth\Password namespace. My goal is to create an expiring token, email it to the user via the default email config (I know how to send the email / design the template) and then be able to make the webservice call that will allow the password to be resolved.
Here's what I think I know...
I've set CanResetPassword trait on my user models, which I believe are necessary to support the native methods for password reset
I believe the goal is to create a reset token keyed against the user email that expires after a period of time, then send that token appended to a url in an email (I don't know the architectural implications surrounding the generation of the token beyond the table row)
There's a Password facade with a sendResetLink method - but this
method can't work for spa applications because the base url of the
client app will be different, so I'm assuming something native will have to be re-written. In fact, calling this method will return an error of Route [password.reset] not defined.
I'm assuming I will need the password Facade, if so, what is the method to generate the token? Should I just email the link with the token appended or are there other architectural considerations to support the token expiration?
Apologies if my questions are flawed, I'm unclear on the architecture so I'm making assumptions.
Have you tried Laravel authentication? All authentication requirements have been moved to a package called laravel/ui.
By installing that package you can use Laravel authentication. It will take care of your registration, login, and forgot password processes.
This package will create some controllers for all those processes and those you need for forgot password are
ForgotPasswordController: will generate and send reset password links.
ResetPasswordController: will reset the password by getting user's email, new password, and reset password token.
But if you don't want to use the official Laravel package you should take these steps:
Show a "Request reset password form" to the user.
Validate the provided email by the user.
Generate a random reset password token and store it at DB (Need a table with at least two fields: email and token).
Send that token to the user(It's better if you send it as a URL parameter in the reset password link).
When the user navigated to the reset password page, ask for email again and validate the token by checking your DB table and matching the email and token.
Reset the password to whatever the user wants at this point.
Update: I use this piece of code for generating random tokens:
$email = 'user#email.com';
$token = \Illuminate\Support\Str::random(10);
while(\DB::table('reset_password_tokens')->where('token', $token)->exists()) {
$token = \Illuminate\Support\Str::random(10);
}
\DB::table('reset_password_tokens')->insert(compact('email', 'token'));

Laravel Airlock Token

Introduction/Background
I'm looking to enable token authentication for multiple microservices and users. Both applications and users are $user objects.
I need to be able to authenticate once (hence token) using an auth server on a subdomain. I then need to be able to pass around a token that can be managed (revoked/refreshed whatever) by the Auth server.
The microservices are Laravel based, so using Airlock makes sense. Airlock generates tokens easily using:
$token = $user->createToken(now())
However, I see no method to manually check the validity of these tokens... So I assumed they are available in the database.
Airlock suggests that the token be returned as follows:
$token->plainTextToken
This produces a token, as expected. To my understanding, this is a public facing token. It does not match the token in the personal_access_tokens table.
Lets call these PublicToken and PrivateToken.
The private token is actually located in:
$token->accessToken->token
I want to be able to manually switch between a PublicToken. I assume Airlock is doing some security here.. and I want to invoke these secure methods required to check a PublicToken against the PrivateToken.
Please do not say "it's in middleware" ... The point is that I have multiple microservices and usertypes sharing a database. I have an auth server that will end up on secure architecture, and some of the other microservices wont be.... fundamentally I need to do a manual authentication because normal plug and play wont work. Using Airlock as the foundation is great. But I need to be able to know how to convert between public and private tokens.
Essentially I'm looking for the real version of the following psuedocode:
if( someTranslationFunction($public_token) == $private_token ) ...
TLDR: The problem
How do I validate a $token->plainText value against a $token manually?

Laravel passport: Manually create access token

I'm building an SPA using VueJS and Laravel.
I'm using Laravel passport for logins which works fine.
However I would like the ability to send users magic links to log in with. However I'm not sure how to create an access token without sending a request with the password to the oauth route.
It seems like it should be really easy to do, just inserting the right rows into oauth_access_tokens and oauth_refresh_tokens.
But i've been trawling through the code in the Passport repo and Google results and everything seems way more complicated.
What I would like is be able to do something like this:
$user = User::findFromMagicLink($link);
$token = $user->createAccessToken();
return response()->json(['access_token' => $token->token, 'refresh_token' => $token->refresh_token])
I'm guessing that's not possible otherwise it would be documented somewhere. But if it's something more complicated than that I can't figure it out.
Can anyone point me in the right direction?
Try this You can create access token like
$user = User::findFromMagicLink($link)
$token = $user->createToken('UserToken', ['*']);
//or directly access
$token = $user->createToken('UserToken', ['*'])->accessToken;
For more info Read: Manage personal access token

Revoking signature on Laravel temporarysignedroute at the time it accessed

So i was searching about sending a link to allow user login by using that, which is sent to their emails. I tried passport but have no idea how to use it after reading its doc for hours. So i have an idea to allow the user login by signedroute, but i want to revoke its signature on the first time it has been accessed like code below. Is that possible? Any suggestion for this login via link is welcomed , desperate af ::))
return URL::temporarySignedRoute(
'unsubscribe', whenAccessedfortheFirstTime() , ['user' => 1]);

Why doesn't LogonUser(...) work for domain accounts?

I've been trying to use LogonUser(...) to get an access token for a user account, as in this MSDN sample.
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
When I run the sample (with Administrator privileges) it works fine when given a domain of . and a local user account name and password, but no matter what I do I get error code 1326 (Logon failure: unknown user name or bad password) if I try to use a domain account. I get the same result if I enter garbage for the domain, which makes me wonder if it's actually contacting the DC at all.
What could be stopping this from working?
In my case the issue, similar to the question asker, was that the account I was trying to authenticate to was in a domain that my current machine did not belong to. Unlike the original poster, my machine should not and could not be part of this other domain. I wanted the login to perform action on a resource on this domain though.
The answer was the following
bool success = LogonUser(
userName,
domain,
password,
(int)LOGON32_LOGON_NEW_CREDENTIALS, //9
(int)LOGON32_PROVIDER_DEFAULT, //0
out userToken);
with the following constants defined:
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
public const int LOGON32_PROVIDER_DEFAULT = 0;
Hopefully this will help others who are lost in a similar situation.
Edit: As mentioned in the comments below, this logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identifier but uses different credentials for other network connections. As a result of that fact, "success" will return true even if the password is bad. You will need an additional check beyond "success" to confirm that the credentials are actually good.
This was not a concern in my initial use case as we used the current network user's credential in another function to pull the plaintext password from secure storage. So it would have never been wrong unless there was an inconsistency between that system and active directory in which case we had bigger problems.
In my case it was the fact that, although I was logged in to my computer as a domain user, my computer was not itself part of the domain. Once added to the domain the sample started to work.
Use DOMAIN\LOGIN with an empty domainname for that case...

Resources