【问题标题】:Adldap2-Laravel, where to put my logicAdldap2-Laravel,把我的逻辑放在哪里
【发布时间】:2018-06-14 09:24:48
【问题描述】:

我需要使用 Adldap2-Laravel。我的 laravel 应用基于 Laravel-boilerplate 5。

我看到应用程序使用的唯一 login() 方法是这个:vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php 我知道它是供应商,但出于测试目的,我编辑了 public function login(Request $request) 方法,如下所示:

public function login(Request $request){
    if (\Adldap::auth()->attempt(str_replace('@example.com', '', $request->email), $request->password)) { //THIS IS THE ONLY LINE THAT IA HAVE ADDED, THE REST OF THE CODE IS THE ORIGINAL ONE
       $this->validateLogin($request);
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }
    }
    else {
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }
}

这一切都很好,但我怎么能不接触这个供应商文件呢?我应该在哪里使用 Adlap 验证来实现 if-else。

【问题讨论】:

    标签: laravel-5 vendor adldap


    【解决方案1】:

    您可以使用默认的登录页面表单。

    所有步骤都在此处进行了说明: https://github.com/jotaelesalinas/laravel-simple-ldap-auth

    如果你错过了什么,我会解释一切直到第一步。

    1.安装 Adldap2-Laravel

    cd yourLaravalProjectFolder
    composer require adldap2/adldap2-laravel
    

    2。在config/app.php注册Adldap的服务提供商和门面

    'providers' => [
        ...
        Adldap\Laravel\AdldapServiceProvider::class,
        Adldap\Laravel\AdldapAuthServiceProvider::class,
    ],
    
    'aliases' => [
        ...
        'Adldap' => Adldap\Laravel\Facades\Adldap::class,
    ],
    

    发布 Adldap:

    php artisan vendor:publish --tag="adldap"
    

    3。更改config/auth.php中用户提供者的驱动

    'providers' => [
        'users' => [
            'driver' => 'adldap', // was 'eloquent'
            'model'  => App\User::class,
        ],
    ],
    

    4.在config/adldap.php中配置Adldap2连接
    尝试添加新连接并保持默认不变,但它不起作用。 Adldap2 一直尝试使用默认设置以管理员身份连接,所以我不得不直接修改默认设置:

    'connections' => [
        'default' => [
            'auto_connect' => false,
            'connection' => Adldap\Connections\Ldap::class,
            'schema' => Adldap\Schemas\OpenLDAP::class, // was Adldap\Schemas\ActiveDirectory::class
            'connection_settings' => [
                'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''),
                'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''),
                'domain_controllers' => explode(' ', env('ADLDAP_CONTROLLERS', 'corp-dc1.corp.acme.org corp-dc2.corp.acme.org')),
                'port' => env('ADLDAP_PORT', 389),
                'timeout' => env('ADLDAP_TIMEOUT', 5),
                'base_dn' => env('ADLDAP_BASEDN', 'dc=corp,dc=acme,dc=org'),
                'admin_account_suffix' => env('ADLDAP_ADMIN_ACCOUNT_SUFFIX', ''),
                'admin_username' => env('ADLDAP_ADMIN_USERNAME', ''),
                'admin_password' => env('ADLDAP_ADMIN_PASSWORD', ''),
                'follow_referrals' => true,
                'use_ssl' => false,
                'use_tls' => false,
            ],
        ],
    ],
    

    5.在config/adldap_auth.php 中更改要同步的用户名和属性:

    此配置指定为每个登录用户从 LDAP 服务器复制哪些字段到本地数据库。

    要同步的额外属性的一些示例可能是“角色”以控制对某些区域的访问,或“session_expiration_in_minutes”以在一段时间后强制注销。我相信您可以想到许多其他用途。

    测试 LDAP 服务器中可用的字段数量有限,因此我们将添加“电话”作为示例。

    'usernames' => [
        'ldap' => env('ADLDAP_USER_ATTRIBUTE', 'userprincipalname'), // was just 'userprincipalname'
        'eloquent' => 'username', // was 'email'
    ],
    
    'sync_attributes' => [
        // 'field_in_local_db' => 'attribute_in_ldap_server',
        'username' => 'uid', // was 'email' => 'userprincipalname',
        'name' => 'cn',
        'phone' => 'telephonenumber',
    ],
    

    6.在 .env

    中配置您的 LDAP 和数据库连接

    仅供参考,机密配置,即 API 令牌或数据库密码,应存储在此文件中,Laravel 默认包含在 .gitignore 中。

    ADLDAP_CONNECTION=default
    ADLDAP_CONTROLLERS=ldap.forumsys.com 
    ADLDAP_BASEDN=dc=example,dc=com
    ADLDAP_USER_ATTRIBUTE=uid
    ADLDAP_USER_FORMAT=uid=%s,dc=example,dc=com
    
    DB_CONNECTION=sqlite  # was 'mysql'
    DB_HOST=127.0.0.1     # remove this line
    DB_PORT=3306          # remove this line
    DB_DATABASE=homestead # remove this line
    DB_USERNAME=homestead # remove this line
    DB_PASSWORD=secret    # remove this line
    

    7.更改database/migrations/2014_10_12_000000_create_users_table.php

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('username')->unique(); // was 'email'
            $table->string('password');
            $table->string('name'); // to be read from LDAP
            $table->string('phone'); // extra field to read from LDAP
            $table->rememberToken();
            $table->timestamps();
        });
    }
    

    8.删除文件database/migrations/2014_10_12_100000_create_password_resets_table.php

    9.更改app/User.php

    protected $fillable = [
        // replace 'email' with 'username' and add 'phone'
        'name', 'username', 'password', 'phone',
    ];
    

    10 运行迁移以创建用户表和身份验证脚手架

    在迁移之前,请确保您的数据库已配置并正常工作。

    touch database/database.sqlite
    php artisan migrate
    php artisan make:auth
    

    最后一个命令安装了许多我们不需要的控制器和视图,所以让我们删除它们。

    11.删除这些文件和文件夹

     - app/Http/Controllers/Auth/ForgotPasswordController.php
     - app/Http/Controllers/Auth/RegisterController.php
     - app/Http/Controllers/Auth/ResetPasswordController.php
     - resources/views/auth/register.blade.php
     - resources/views/auth/passwords --> remove folder and all files inside
    

    12.从 resources/views/layouts/app.blade.php 中删除这一行

    <li><a href="{{ route('register') }}">Register</a></li>
    

    13.从 resources/views/welcome.blade.php 中删除这一行

    <a href="{{ url('/register') }}">Register</a>
    

    14.在资源/视图/auth/login.blade.php 中更改“用户名”的“电子邮件”

    <div class="form-group{{ $errors->has('username') ? ' has-error' : '' }}">
        <label for="username" class="col-md-4 control-label">Username</label>
        <div class="col-md-6">
            <input id="username" type="text" class="form-control" name="username" value="{{ old('username') }}" required autofocus>
            @if ($errors->has('username'))
                <span class="help-block">
                    <strong>{{ $errors->first('username') }}</strong>
                </span>
            @endif
        </div>
    </div>
    

    15.将这些方法添加到app/Http/Controllers/Auth/LoginController.php中的LoginController

    别忘了使用说明。

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    use Adldap\Laravel\Facades\Adldap;
    
    class LoginController extends Controller {
        ...
    
        public function username() {
            return config('adldap_auth.usernames.eloquent');
        }
    
        protected function validateLogin(Request $request) {
            $this->validate($request, [
                $this->username() => 'required|string|regex:/^\w+$/',
                'password' => 'required|string',
            ]);
        }
    
        protected function attemptLogin(Request $request) {
            $credentials = $request->only($this->username(), 'password');
            $username = $credentials[$this->username()];
            $password = $credentials['password'];
    
            $user_format = env('ADLDAP_USER_FORMAT', 'cn=%s,'.env('ADLDAP_BASEDN', ''));
            $userdn = sprintf($user_format, $username);
    
            // you might need this, as reported in
            // [#14](https://github.com/jotaelesalinas/laravel-simple-ldap-auth/issues/14):
            // Adldap::auth()->bind($userdn, $password);
    
            if(Adldap::auth()->attempt($userdn, $password, $bindAsUser = true)) {
                // the user exists in the LDAP server, with the provided password
    
                $user = \App\User::where($this->username(), $username) -> first();
                if (!$user) {
                    // the user doesn't exist in the local database, so we have to create one
    
                    $user = new \App\User();
                    $user->username = $username;
                    $user->password = '';
    
                    // you can skip this if there are no extra attributes to read from the LDAP server
                    // or you can move it below this if(!$user) block if you want to keep the user always
                    // in sync with the LDAP server 
                    $sync_attrs = $this->retrieveSyncAttributes($username);
                    foreach ($sync_attrs as $field => $value) {
                        $user->$field = $value !== null ? $value : '';
                    }
                }
    
                // by logging the user we create the session, so there is no need to login again (in the configured time).
                // pass false as second parameter if you want to force the session to expire when the user closes the browser.
                // have a look at the section 'session lifetime' in `config/session.php` for more options.
                $this->guard()->login($user, true);
                return true;
            }
    
            // the user doesn't exist in the LDAP server or the password is wrong
            // log error
            return false;
        }
    
        protected function retrieveSyncAttributes($username) {
            $ldapuser = Adldap::search()->where(env('ADLDAP_USER_ATTRIBUTE'), '=', $username)->first();
            if ( !$ldapuser ) {
                // log error
                return false;
            }
            // if you want to see the list of available attributes in your specific LDAP server:
            // var_dump($ldapuser->attributes); exit;
    
            // needed if any attribute is not directly accessible via a method call.
            // attributes in \Adldap\Models\User are protected, so we will need
            // to retrieve them using reflection.
            $ldapuser_attrs = null;
    
            $attrs = [];
    
            foreach (config('adldap_auth.sync_attributes') as $local_attr => $ldap_attr) {
                if ( $local_attr == 'username' ) {
                    continue;
                }
    
                $method = 'get' . $ldap_attr;
                if (method_exists($ldapuser, $method)) {
                    $attrs[$local_attr] = $ldapuser->$method();
                    continue;
                }
    
                if ($ldapuser_attrs === null) {
                    $ldapuser_attrs = self::accessProtected($ldapuser, 'attributes');
                }
    
                if (!isset($ldapuser_attrs[$ldap_attr])) {
                    // an exception could be thrown
                    $attrs[$local_attr] = null;
                    continue;
                }
    
                if (!is_array($ldapuser_attrs[$ldap_attr])) {
                    $attrs[$local_attr] = $ldapuser_attrs[$ldap_attr];
                }
    
                if (count($ldapuser_attrs[$ldap_attr]) == 0) {
                    // an exception could be thrown
                    $attrs[$local_attr] = null;
                    continue;
                }
    
                // now it returns the first item, but it could return
                // a comma-separated string or any other thing that suits you better
                $attrs[$local_attr] = $ldapuser_attrs[$ldap_attr][0];
                //$attrs[$local_attr] = implode(',', $ldapuser_attrs[$ldap_attr]);
            }
    
            return $attrs;
        }
    
        protected static function accessProtected ($obj, $prop) {
            $reflection = new \ReflectionClass($obj);
            $property = $reflection->getProperty($prop);
            $property->setAccessible(true);
            return $property->getValue($obj);
        }
    
    }
    

    运行网站

    我们完成了!

    不要忘记在本地测试.env文件中将Web服务器端口设置为8000:

    APP_URL=http://localhost:8000
    

    让我们运行网站并尝试登录。

    php artisan serve
    

    在您喜欢的浏览器中访问http://localhost:8000

    登录前尝试访问http://localhost:8000/home

    希望对你有所帮助。

    【讨论】:

    • 嗯,是的,答案真的是告诉我运行php artisan serve?我在问如何修改一些 Adldap 配置,但无论如何,它有很好的信息,谢谢。最后我没有从 AdLdap 中接触任何东西,这是一个配置问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2013-09-04
    • 2017-04-19
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多