Ldaprecord-laravel: [Feature] Support for Jetstream

Created on 8 Sep 2020  路  17Comments  路  Source: DirectoryTree/LdapRecord-Laravel

Will there be any support Fortify in Jetstream?

enhancement

Most helpful comment

Okay we're all set! v1.2.0 of Fortify has been released, and you can now authenticate with LdapRecord-Laravel by placing the following in your AuthServiceProvider::boot() method:

// app/Providers/AuthServiceProvider.php

public function boot()
{
    $this->registerPolicies();

    Fortify::authenticateUsing(function ($request) {
        $validated = Auth::validate($credentials = [
            'mail' => $request->email,
            'password' => $request->password
        ]);

        return $validated ? Auth::getLastAttempted() : null;
    });
}

I'll be writing up some documentation specifically for Laravel Jetstream & Fortify, but this works out-of-the-box with no changes to Jetstream or Fortify :tada:

All 17 comments

Hi @msutexas-matt-s,

I just jumped into a new install of Jetstream. Unfortunately it doesn't support customizing the AttemptToAuthenticate action, which is going to make things extremely tricky and complicated to implement:

https://github.com/laravel/fortify/blob/f29ed3f63d6da006fb540e2894e4aa387ccabde2/src/Actions/AttemptToAuthenticate.php#L48-L53

I'm working on a couple ways of possible implementations, but don't expect a release supporting Fortify for a bit.

Actually, this won't work at all with Jetstream. Fortify doesn't use authentication user providers at all for logging in or verifying passwords:

https://github.com/laravel/fortify/blob/f29ed3f63d6da006fb540e2894e4aa387ccabde2/src/Actions/RedirectIfTwoFactorAuthenticatable.php#L41-L80

It performs its own hash validation and doesn't even touch the user provider besides retrieving the model. It's completely incompatible with any other provider besides eloquent.

Without core changes to Fortify allowing extensibility, this is a no-go with either of the included LdapRecord user providers.

Hi @stevebauman Thanks for looking into that so quickly. Still a great product and will continue to use it.

Thanks @msutexas-matt-s! Appreciate the kind words :smile:

I've opened an issue up on the Fortify repository to see if this is in the works, or if it's something they are open to get PR'ed in 馃憤

@stevebauman I was about to raise the exact same issue with Fortify; seems weird it does a manual auth check instead of handing it off to the provider.

@msutexas-matt-s If you use database synchronisation you can (sort of) get Jetstream to work by overriding the auth routes with the built in Laravel ones; however this means as you aren't using Fortify's controllers it will bypass the two-factor check. Not sure what else gets broken by not using the Fortify authentication routes but I'll update if there's anything else.

Okay we're all set! v1.2.0 of Fortify has been released, and you can now authenticate with LdapRecord-Laravel by placing the following in your AuthServiceProvider::boot() method:

// app/Providers/AuthServiceProvider.php

public function boot()
{
    $this->registerPolicies();

    Fortify::authenticateUsing(function ($request) {
        $validated = Auth::validate($credentials = [
            'mail' => $request->email,
            'password' => $request->password
        ]);

        return $validated ? Auth::getLastAttempted() : null;
    });
}

I'll be writing up some documentation specifically for Laravel Jetstream & Fortify, but this works out-of-the-box with no changes to Jetstream or Fortify :tada:

Came here looking to ask this very question but looks like it's already been solved. Wasn't expecting that so fast. Just tested today, working as expected!

That鈥檚 awesome @poxin13! Glad you鈥檙e up and running 馃槃

@poxin13 How did you tie it into your login? I am having a heck of a time getting username to pass though

Hi @Findarato -- have you changed everything from email to username inside of your application? Such as migrations, sync_attributes, views, login request etc. Using usernames requires a couple extra steps to get going. Let me know and I can help you 馃憤

@stevebauman I was just about to delete my comment. I fixed it in my configfortify.php Now to get the users to sync

Ah great to hear! Glad you're up and running @Findarato 馃帀

Still looking forward to the documentation on how to get jetstream to hand off validation that part is not working. I know my ldap connection works, and I can import users.

It could be just that I am still getting used to the whole jetstream setup, I had this all working on Laravel 6 for a previous project.

Working on it @Findarato! 馃憤 I'm also still working through Jetstream myself -- there's a lot to digest for sure.

If you're trying to use usernames instead of email addresses, you'll have to modify several areas of your Jetstream application to allow for this, such as:

  • Fortify username option (inside of the config/fortify.php configuration file)
  • Fortify authentication callback (Fortify::authenticateUsing())
  • Your sync_attributes (inside of your config/ldap.php file)
  • Your users database table migration (inside database/migrations 2014_10_12_000000_create_users_table.php)
  • The Jetstream login view resources/auth/login.blade.php (if using Livewire)

I've just tested it and it works great. Jetstream having 2 separate front-ends and many configurable features complicates things a little bit, but should have something ready next week.

@stevebauman Thanks for all of your work on this! We're just using Fortify (no Jetstream), and the authentication process is working just as expected. The only thing we seem to be missing now is a way to handle LDAP error messages like we could when using Laravel UI. Is there a way to do this yet, or not?

Hi @aaronhuisinga! Happy to help :smile:

The only thing we seem to be missing now is a way to handle LDAP error messages like we could when using Laravel UI. Is there a way to do this yet, or not?

I'm working on a patch for this (should be out soon) but you can actually do this right now by performing the following:

  1. Create a class named BindFailureListener and use the ListensForLdapBindFailure trait.
    > We'll create it in our app/Ldap directory:
// app/Ldap/BindFailureListener.php

namespace App\Ldap;

use LdapRecord\Laravel\Auth\ListensForLdapBindFailure;

class BindFailureListener
{
    use ListensForLdapBindFailure;
}
  1. Then, in your app/Providers/AuthServiceProvider.php file, instantiate this class and initiate the listener when the Fortify LoginRequest is resolved inside of the boot() method:
// ...
use App\Ldap\BindFailureListener;

class AuthServiceProvider extends ServiceProvider
{
    // ....

    public function boot()
    {
        // ...

        if (class_exists($loginRequest = 'Laravel\Fortify\Http\Requests\LoginRequest')) {
            app()->resolving($loginRequest, function ($request) {
                app(BindFailureListener::class)->listenForLdapBindFailure();
            });
        }
    }                                                                           

We must do it this way because Fortify doesn't allow us to swap out the AuthenticatedSessionController or the LoginRequest itself.

I've tested this and it works great. I'm working on a way to have this behaviour configurable and also be compatible with Laravel UI. Stay tuned! 馃憤

Okay we're all set. As promised, I've completed creating full documentation on using LdapRecord-Laravel with Jetstream

I have also just released LdapRecord-Laravel v1.7.2 with Jetstream support for displaying LDAP error messages during login attempts 馃帀

Thanks for bearing with me during this process 鉂わ笍 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aanderse picture aanderse  路  3Comments

abiffe picture abiffe  路  3Comments

kruiz122893 picture kruiz122893  路  5Comments

mgiritli picture mgiritli  路  5Comments

aanderse picture aanderse  路  7Comments