为什么回调标识符没有被调用?

问题描述 投票:0回答:1

我正在尝试在 CakePHP4 中实现 Kerberos 身份验证与本地用户数据库的匹配。所以我安装了 CakePHP 4 和身份验证插件 2.0。由于 Kerberos 身份验证由我们的 IIS Web 服务器管理,因此我唯一要做的就是检查我的 web 应用程序是否知道经过身份验证的用户。

回调认证应该让我实现这样的东西,对吧? 所以我把这个函数放在Application.php中:

<?php
    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $service = new AuthenticationService();
    
        // Define where users should be redirected to when they are not authenticated
        $service->setConfig([
            'unauthenticatedRedirect' => '/users/login',
            'queryParam' => 'redirect',
        ]);
    
        // Load the authenticators. Session should be first.
        $service->loadAuthenticator('Authentication.Session');
    
        $service->loadIdentifier('Authentication.Callback', [
            'callback' => function($data) {
                // do identifier logic
                if (empty($_SERVER['REMOTE_USER'])) {
                    return new Result(
                        null,
                        Result::FAILURE_OTHER,
                        ['message' => 'Unknown user.']
                    );
                } else {
                    // On vérifie que l'utilisateur est autorisé à utiliser cette application
                    $users = TableRegistry::getTableLocator()->get('Users');
                    $remoteUserNoDomain = str_replace("DOMAIN\\", "", $_SERVER['REMOTE_USER']);
    
                    $result = $users->find()
                        ->where(['username' => $remoteUserNoDomain]);
                    
                    if ($result) {
                        return new Result($result, Result::SUCCESS);
                    }
            
                    return new Result(
                        null,
                        Result::FAILURE_OTHER,
                        ['message' => 'Removed user.']
                    );
                }
                
                return null;
            }
        ]);
    
        return $service;
    }

但是到目前为止,它似乎不起作用,就像它根本不会调用回调函数一样。我尝试添加一些调试代码,然后退出...没有任何效果。

php authentication cakephp kerberos cakephp-4.x
1个回答
0
投票

我假设您还完成了身份验证工作所需的所有其他配置,即加载插件、添加身份验证中间件等!?

https://book.cakephp.org/authentication/2/en/index.html

也就是说,标识符本身不做任何工作,它们是由身份验证器触发的,以防它们确实需要它们。您只加载了

Session
身份验证器,其默认配置中不使用标识符,但即使您将其配置为使用标识符(通过将其
identify
选项设置为
true
),它也只会使用当会话中已经存在身份时,该标识符将用于验证该身份。

https://github.com/cakephp/authentication/blob/2.3.0/src/Authenticator/SessionAuthenticator.php#L52

我不熟悉 Kerberos 身份验证,但如果它预先填充

$_SERVER['REMOTE_USER']
(顺便说一句,永远不要直接访问 CakePHP 中的超级全局变量,它只会在以后造成麻烦),那么您需要的是自定义身份验证器。然后,您可以重新使用 ORM 访问部分的密码标识符,因为它允许在不检查密码的情况下找到某些内容(很奇怪,鉴于其名称)。

基于您的代码片段的快速而肮脏的示例:

// src/Authenticator/KerberosAuthenticator.php

namespace App\Authenticator;

use Authentication\Authenticator\AbstractAuthenticator;
use Authentication\Authenticator\Result;
use Authentication\Authenticator\ResultInterface;
use Psr\Http\Message\ServerRequestInterface;

class KerberosAuthenticator extends AbstractAuthenticator
{
    public function authenticate(ServerRequestInterface $request): ResultInterface
    {
        $server = $request->getServerParams();

        if (empty($server['REMOTE_USER'])) {
            return new Result(null, Result::FAILURE_CREDENTIALS_MISSING);
        }

        $remoteUserNoDomain = str_replace("DOMAIN\\", "", $server['REMOTE_USER']);
        $user = $this->_identifier->identify(['username' => $remoteUserNoDomain]);

        if (empty($user)) {
            return new Result(
                null, 
                Result::FAILURE_IDENTITY_NOT_FOUND, 
                $this->_identifier->getErrors()
            );
        }

        return new Result($user, Result::SUCCESS);
    }
}

您的服务验证器/标识符设置将如下所示:

$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Kerberos');

$service->loadIdentifier('Authentication.Password');

不确定您是否真的想使用这样的会话身份验证器,即您是否只想在每个会话中识别远程用户一次。

© www.soinside.com 2019 - 2024. All rights reserved.