2017-03-10 4 views
1

Ich versuche LDAP-Authentifizierung für Symfony Firewall arbeiten zu bekommen, habe aber Probleme. Das Hauptproblem scheint von der Symfony LdapUserProvider zu stammen - es nimmt nicht den vom Benutzer angegebenen Benutzernamen und das Passwort an, wenn es versucht, ldap_bind().Symfony LDAP auth bind mit Benutzername und Passwort

Also, ich habe dies als meinen Firewall config:

$app->register(new SilexProvider\SecurityServiceProvider(), [ 
    'security.firewalls' => [ 
     'secured' => [ 
      'pattern' => '^.*$', 
      'http' => true, 
      'users' => new \Symfony\Component\Security\Core\User\LdapUserProvider(
       \Symfony\Component\Ldap\Ldap::create('ext_ldap', [ 
        'connection_string' => 'ldap://MY_LDAP_DOMAIN', 
       ]), 
       'dc=MY_DC_1,dc=MY_DC_2', 
       'uid={username},cn=users,cn=accounts,dc=MY_DC_1,dc=MY_DC_2' 
      ), 
     ], 
    ], 
]); 

Aber mein {username} Teil wird vom Benutzer angegebenen Benutzername nicht ersetzt, wenn die ldap_bind Methode aufgerufen wird. So ist die dn Zeichenfolge, die an ldap_bind übergeben wird, buchstäblich uid={username},cn=users,cn=accounts,dc=MY_DC_1,dc=MY_DC_2 - der Benutzername wird nicht ersetzt.

Wenn ich durch den Code schaue, obwohl dies erwartet wird, wie LdapUserProvider->loadUserByUsername() ruft bind vor jeder String-Ersetzungen zu tun. Das andere Problem besteht darin, dass das vom Benutzer bereitgestellte Kennwort erst viel später bekannt ist, so dass der Anruf bind nicht erneut das vom Benutzer angegebene Kennwort enthält.

Wie kann ich dies einrichten, so dass es meine dn und Passwort entsprechend ersetzt? Wenn ich diese zwei Grundlinien verwenden (wo $data ist ein Array eines gültigen):

$ldap = ldap_connect('MY_LDAP_DOMAIN'); 
$bind = ldap_bind($ldap, 'uid=' . $data['username'] . ',cn=users,cn=accounts,dc=MY_DC_1,dc=MY_DC_2', $data['password']); 

Dann bindet sie perfekt. Wie kann ich diese zwei Zeilen in eine Situation übersetzen, die Symfony Firewall versteht?

Antwort

3

Sie haben wichtigsten Themen in den vorhandenen Code:

  1. der Symfony LdapUserProvider Komponente standardmäßig verwendet Active Directory (Windows) Schema: sAMAccountName={username} statt Open LDAP der uid={username}
  2. Sie verwenden integrierte in http Sicherheits-Firewall, die standardmäßig DaoAuthenticationProvider Authentifizierung Provider verwendet. Im Falle einer LDAP-Authentifizierung müssen Sie stattdessen verwenden.

    $app['ldap.users'] = function() use ($app) { 
        return new LdapUserProvider(
         // your LDAP adapter 
         $app['ldap'], 
         // base DN 
         'dc=example,dc=com', 
         // you don't need search DN 
         null, 
         // you don't need search password 
         null, 
         // list of default roles, can be empty array 
         ['ROLE_USER'], 
         // user identifier key for LDAP 
         // this identitfer must be set explicitly 
         'uid' 
        ); 
    }; 
    

    Hinweis 3. und 4. Parameter können null sein, weil sie nie verwendet werden:

Die erste Ausgabe kann, indem Benutzerkennung Schlüssel zu LdapUserProvider gelöst werden LdapBindAuthenticationProvider zuerst aufgerufen werden , sodass die LDAP-Verbindung bereits gebunden ist.

Die zweite Ausgabe erfordert ein wenig Codierung. Symfony verfügt über einen integrierten Authentifizierungsanbieter http_basic_ldap, der perfekt zu Ihren Anforderungen passt. Leider hat Silex keins, also musst du es selbst machen. Verwenden Sie die Silex-Dokumentation als Referenz: Defining a custom Authentication Provider

Hier ist mein Beispiel für form_login_ldap Implementierung für Silex. Registrierung alle LDAP-bezogene Dienste:

$app // register other services 
    ->register(new LdapServiceProvider()) 
    ->register(new LdapUsersServiceProvider()) 
    ->register(new LdapSecurityServiceProvider()) 
    ->register(new \Silex\Provider\SecurityServiceProvider(), [ 
     'security.firewalls' => [ 
      'login' => [ 
       'pattern' => '^/login$', 
      ], 
      'secured' => [ 
       'pattern' => '^.*$', 
       'form_login_ldap' => [ 
        'login_path' => 'login', 
        'check_path' => 'login_check', 
        'default_target_path' => 'backoffice', 
       ], 
       'users' => $this['ldap.users'], 
      ], 
     ], 
    ]) 
; 

Service Provider für die LDAP-Adapter

use Pimple\Container; 
use Pimple\ServiceProviderInterface; 
use Symfony\Component\Ldap\Ldap; 

class LdapServiceProvider implements ServiceProviderInterface 
{ 
    public function register(Container $app) 
    { 
     $app['ldap'] = function() { 
      return Ldap::create('ext_ldap', [ 
       'connection_string' => 'ldap.example.com', 
      ]); 
     }; 
    } 
} 

Service Provider für LDAP-Benutzer

use Pimple\Container; 
use Pimple\ServiceProviderInterface; 
use Symfony\Component\Security\Core\User\LdapUserProvider; 

class LdapUsersServiceProvider implements ServiceProviderInterface 
{ 
    public function register(Container $app) 
    { 
     $app['ldap.users'] = function() use ($app) { 
      return new LdapUserProvider(
       $app['ldap'], 
       'dc=example,dc=com', 
       null, 
       null, 
       ['ROLE_USER'], 
       'uid' 
      ); 
     }; 
    } 
} 

Service Provider für Sicherheitsauthentifizierung Listener Fabrik für LDAP-Form (der interessanteste Teil für Sie)

use Pimple\Container; 
use Pimple\ServiceProviderInterface; 
use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticationProvider; 

class LdapSecurityServiceProvider implements ServiceProviderInterface 
{ 
    public function register(Container $app) 
    { 
     $app['security.authentication_listener.factory.form_login_ldap'] = $app->protect(function ($name, $options) use ($app) { 
      // define the authentication provider object 
      $app['security.authentication_provider.'.$name.'.form_login_ldap'] = function() use ($app, $name) { 
       return new LdapBindAuthenticationProvider(
        $app['security.user_provider.'.$name], 
        $app['security.user_checker'], 
        $name, 
        $app['ldap'], 
        'uid={username},dc=example,dc=com', 
        $app['security.hide_user_not_found'] 
       ); 
      }; 

      // define the authentication listener object 
      $app['security.authentication_listener.'.$name.'.form_login_ldap'] = $app['security.authentication_listener.form._proto']($name, $options); 

      // define the entry point object 
      $app[$entryPoint = 'security.entry_point.'.$name.'.form_login_ldap'] = $app['security.entry_point.form._proto']($name, array()); 

      return array(
       // the authentication provider id 
       'security.authentication_provider.'.$name.'.form_login_ldap', 
       // the authentication listener id 
       'security.authentication_listener.'.$name.'.form_login_ldap', 
       // the entry point id 
       $entryPoint, 
       // the position of the listener in the stack 
       'form' 
      ); 
     }); 
    } 
} 
Verwandte Themen