Saul Chelewani
Jun 10 · 3 min read

API Authentication with LDAP and Laravel Passport

This article takes us through installation and configuration of LDAP and Laravel Passport on a Laravel project. This will enable API authentication with access and refresh tokens using existing Active Directory accounts.

Laravel comes with a fluent auth out of the box. For those wanting to use it as an API that manages its own API authentication, Passport does a fantastic job in that regard. Going further, some enterprise systems will require you to use their existing Active Directory accounts so everyone is saved from having to save gazillion passwords. And yes, Laravel LDAP does that well too.

Wait, it looks like there is no case where this article can come in after all. Maybe not just yet. What if you are required to develop an API for a mobile app but to be used by an enterprise? They require their Active Directory. They memorize one password. And you, on the other hand, require Laravel Passport to manage the app’s authentication with those tokens. Let’s crack this one up!

First, let’s set up the laravel application with

laravel new ldap-passport

Then install the two composer packages

cd ldap-passportcomposer require adldap2/adldap2-laravelcomposer require laravel/passport

You can find the config details of adaldap installation on their docs

Since traditionally you cannot use LDAP and Passport together out of the box, we will draw their lines in our auth config file and in LoginController so that LDAP handles the authentication with Active Directory, and pass on to Passport to issue tokens to the client.

To achieve this, first we change the api guard to passport and users provider to ldap as in the code snippet below.

Next we proceed to our login controller. We will attempt to login with our user provider defined above

Auth::attempt(['username' => request('username'), 'password' => request('password'), true)

Then we fetch the passport client to use with the request. We assume (of course we require) the consumers of the API to pass their client’s API key in the request header.

$client = PassportClient::findClientBySecret(request()->header("apiKey"));

And then we use the client to generate API tokens to return to the client

$passport = (new PassportAuthenticator($request))
    ->authenticate($client, request('username'), request('password'));

And finally we have out API tokens!

return response()->json([
    "access_token" => $passport->access_token,
    "expires_in" => $passport->expires_in,
    "refresh_token" => $passport->refresh_token,
], 200),

The complete login controller should like the one below

That sorts us out, right? Not just yet. At this stage, when subsequent requests are made, the API will try to authenticate with auth:api guard and that won’t work. So we will modify the Kernel to pass our custom middleware (which will refer to Passport Middleware anyway). Here is how…

'passport' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,

We add that to the routeMiddleware array of our Http Kernel. So instead of using auth:api in our protected routes, we will use passport.

Route::post('blog', 'BlogController@store')->middleware('passport');

The very last thing, as you might have noticed, we did some abstraction in the Login Controller. There is a little more happening in PassportClient and PassportAuthenticator classes. That was necessary to keep our code concise and focus on the main objective of the tutorial. You can see what’s happening behind the scenes in the snippets below: