Adldap2-Laravel,我的逻辑在哪里 [英] Adldap2-Laravel, where to put my logic

查看:105
本文介绍了Adldap2-Laravel,我的逻辑在哪里的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to use Adldap2-Laravel. My laravel app is based in Laravel-boilerplate 5.

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

The only login() method that I see that the app is using is this one: vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php I know it's a vendor, but for testing purposes I have edited the public function login(Request $request) method like this way:

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.

It all works fine, but how could I do it without touching this vendor file? Where should I look to implement that if-else with that Adlap verification.

推荐答案

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

You could use the default login page form.

此处说明了执行此操作的所有步骤: https://github.com/jotaelesalinas/laravel-simple-ldap-auth

All the steps to do that are explains there: https://github.com/jotaelesalinas/laravel-simple-ldap-auth

如果您错过了一些东西,我将在第一步之前向您进行解释.

I'll explain everything till the first step in case you missed something.

1.安装Adldap2-Laravel

cd yourLaravalProjectFolder
composer require adldap2/adldap2-laravel

2.在config/app.php

2. Register Adldap's service providers and façade in config/app.php

'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

3. Change the driver of the user provider in config/auth.php

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

4.在config/adldap.php
中配置Adldap2连接 尝试添加新的连接并保留默认设置不变,但这没有用. Adldap2一直尝试使用默认设置以管理员身份连接,因此我不得不直接修改默认设置:

4. Configure the Adldap2 connection in config/adldap.php
tried to add a new connection and leave default untouched, but it didn't work. Adldap2 kept trying to connect as administrator using the default setup, so I had to modify default directly:

'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中进行同步:

5. Change the usernames and attributes to synchronize in config/adldap_auth.php:

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

This configuration specifies which fields are copied from the LDAP server into the local database for each logged in user.

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

Some examples of extra attributes to synchronize could be "role" to control access to certain areas or "session_expiration_in_minutes" to force logout after some time. I am sure you can think of many other uses.

受测试的LDAP服务器中可用字段的数量是有限的,因此我们将添加"phone"作为示例.

The number of fields available in the testing LDAP server is limited, so we will add 'phone' as an example.

'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

6. Configure your LDAP and database connections in .env

FYI,秘密配置,即API令牌或数据库密码,应存储在此文件中,Laravel默认将其包含在.gitignore中.

FYI, configuration that is secret, i.e. API tokens or database passwords, should be stored in this file, which Laravel includes by default in .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

7. Change 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

8. Delete the file database/migrations/2014_10_12_100000_create_password_resets_table.php

9.更改app/User.php

9. Change app/User.php

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

10运行迁移以创建用户表和Auth脚手架

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

Before migrating, make sure that your database is configured and working properly.

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

最后一条命令将安装许多我们不需要的控制器和视图,因此我们将其删除.

This last command installs many controllers and views that we are not going to need, so let's remove them.

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.在resources/views/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

15. Add these methods to LoginController in app/Http/Controllers/Auth/LoginController.php

别忘了使用说明.

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:

Don't forget to set the web server port to 8000 in your local testing .env file:

APP_URL=http://localhost:8000

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

Let's run the website and try to log in.

php artisan serve

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

Visit http://localhost:8000 in your favourite browser.

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

希望它会对您有所帮助.

Hope it will help you.

这篇关于Adldap2-Laravel,我的逻辑在哪里的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆