I was created one project with laravel 5.4 and custom authentication to one table of Dynamics NAV (2017) trough web services, these are the steps that I was make to do this:
- I was folow some steps As this article explains perfectly: CustomUserProvider.php
-
- Modify config/auth.php:
'providers' => [ 'users' => [ //'driver' => 'eloquent', 'driver' => 'customuserprovider', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
- but then Modify providers/AuthServiceProvider to use my own customuserprovider:
<?php namespace App\Providers; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); // added to modify auth provider that's the trick \Illuminate\Support\Facades\Auth::provider('customuserprovider', function($app, array $config) { return new CustomUserProvider($app['hash'], $config['model']); }); // } }
- Modify config/auth.php:
- Create a new file in providers/CustomUserProvider.php As yoy can see in the code that is very simple, I was replaced the functions retrieveByCredentials and retrieveById with my ownsThe functions checkUser and ReadUser, make the calls to DynamicsNAV websevices (Customer Table), I use Guzzle that is very easy to implement, and in the funcion checkUser only reads the user trough Odata, ( with filter expressions as says Microsoft) then validate the field “Password” , I have 3 new variables in .env file:
HTTP_URIBASE=http://www.myserver.com/MYDyanmicsNavService/ODataV4/Company('MyCompany') HTTP_USERNAME=user HTTP_PASSWORD=password
Is very important to have NTLM active on Microsoft Dynamics NAV service , if not it not works, becose Microsoft Dynamics NAV uses new OAuth that is more complex
this is the file that makes all the job CustomUserProvider.php:<?php namespace App\Providers; use Illuminate\Auth\EloquentUserProvider as UserProvider; use Illuminate\Contracts\Auth\Authenticatable as UserContract; use GuzzleHttp\Client as GuzzleHttpClient; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Response; class CustomUserProvider extends UserProvider { public function validateCredentials(UserContract $user, array $credentials) { $plain = $credentials['password']; //return $this->hasher->check($plain, $user->getAuthPassword()); return true; } public function retrieveByCredentials(array $credentials) { if (empty($credentials)) { return; } // Internal function to retrieve the user: $resultat =$this->checkUser($credentials); // the user not exists if (empty($resultat)){ return; } //password incorrect if ($resultat->{'value'}[0]->{'Contraseña'}!=$credentials['password']){ return; } //create new user to return $user = new \App\User(); $user->id=$resultat->{'value'}[0]->{'No'}; $user->name = $credentials['email']; $user->email = $credentials['email']; $user->password = bcrypt( $credentials['password']); //$user->remember_token = $request->_token; //$user->save(); return $user; } public function retrieveById($identifier) { $resultat =$this->ReadUser($identifier); $user = new \App\User(); $user->id=$resultat->{'value'}[0]->{'No'}; $user->name = $resultat->{'value'}[0]->{'Usuario'}; $user->email = $resultat->{'value'}[0]->{'Usuario'}; $user->password = bcrypt( $resultat->{'value'}[0]->{'Contraseña'}); return $user; } public function updateRememberToken(UserContract $user, $token) { $user->setRememberToken($token); $timestamps = $user->timestamps; $user->timestamps = false; //$user->save(); $user->timestamps = $timestamps; } public function checkUser(array $credentials) { //function to make the call to the web service with guzzle,DynamicsNAV table Customer, field=Usuario // try { $client = new GuzzleHttpClient(); $uri=env('HTTP_URIBASE', ''); $apiRequest = $client->request('GET', $uri.'/Customer?$filter=Usuario eq \''.$credentials['email'].'\'',[ 'auth' => [env('HTTP_USERNAME', 'usuari'),env('HTTP_PASSWORD', ''), 'ntlm' ], //If authentication required //'debug' => true //If needed to debug ]); $content = json_decode($apiRequest->getBody()->getContents()); return $content; // } catch (RequestException $re) { //For handling exception // } } public function ReadUser($identifier) { //function to read the user at the web service with guzzle,DynamicsNAV table Customer, field=No // try { $client = new GuzzleHttpClient(); $uri=env('HTTP_URIBASE', ''); // $uri=str_replace("%27","'" ,$uri); $apiRequest = $client->request('GET', $uri.'/Customer?$filter=No eq \''.$identifier.'\'',[ 'auth' => [env('HTTP_USERNAME', 'usuari'),env('HTTP_PASSWORD', ''), 'ntlm' ], //If authentication required //'debug' => true //If needed to debug ]); $content = json_decode($apiRequest->getBody()->getContents()); return $content; // } catch (RequestException $re) { //For handling exception // } } }
-