【问题标题】:Simplesamle external verification classSimplesample 外部验证类
【发布时间】:2022-06-29 19:09:39
【问题描述】:

我正在尝试在简单 saml 的 idp 安装中使用外部类。 idp 可以很好地登录用户/密码,但我需要外部帮助验证某些类型的用户。

这是我尝试修改和使用的类 https://github.com/simplesamlphp/simplesamlphp/blob/56a8949141a3aa2d783763aaaaccaa0ccf6164c2/modules/exampleauth/lib/Auth/Source/External.php

我不断收到这个 php 致命错误

PHP 致命错误:SimpleSAML\Module\mymodule\Auth\Source\MyAuth::authenticate() 的声明必须与 /var/simplesamlphp/modules/ 中的 SimpleSAML\Auth\Source::authenticate(&$state) 兼容mymodule/lib/Auth/Source/MyAuth.php 在第 355 行,引用者:https://xxxxxxxyyyyyzzzzz.com/

我用谷歌搜索过,似乎找不到与此相关的任何内容。有什么我可能出错的想法或我可以尝试解决的问题吗?

<?php

declare(strict_types=1);

namespace SimpleSAML\Module\mymodule\Auth\Source;

use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Module;
use SimpleSAML\Utils;
//use Symfony\Component\HttpFoundation\Request;
//use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;

/**
 * Example external authentication source.
 *
 * This class is an example authentication source which is designed to
 * hook into an external authentication system.
 *
 * To adapt this to your own web site, you should:
 * 1. Create your own module directory.
 * 2. Enable to module in the config by adding '<module-dir>' => true to the $config['module.enable'] array.
 * 3. Copy this file to its corresponding location in the new module.
 * 4. Replace all occurrences of "mymodule" in this file with the name of your module.
 * 5. Adapt the getUser()-function, the authenticate()-function and the logout()-function to your site.
 * 6. Add an entry in config/authsources.php referencing your module. E.g.:
 *        'myauth' => [
 *            '<mymodule>:External',
 *        ],
 *
 * @package SimpleSAMLphp
 */
class MyAuth extends Auth\Source
{
    /**
     * The key of the AuthId field in the state.
     */
    //public const AUTHID = 'SimpleSAML\Module\mymodule\Auth\Source\MyAuth.AuthId';
    const AUTHID = 'SimpleSAML\Module\mymodule\Auth\Source\MyAuth.AuthId';

    /**
     * Constructor for this authentication source.
     *
     * @param array $info  Information about this authentication source.
     * @param array $config  Configuration.
     */
    public function __construct(array $info, array $config)
    {
        // Call the parent constructor first, as required by the interface
        parent::__construct($info, $config);

        // Do any other configuration we need here
    }



    /**
     * Log in using an external authentication helper.
     *
     * @param array &$state  Information about the current authentication.
     */
    public function authenticate(array &$state)
    //public function authenticate(array &$state)
    {
        
        
        require_once('/yyy/xxx/some_server/public_html/web/setup.php');

       
        $_users = new \Users;
        $user = $_users->verifyUser($username,$password);
        

        $attributes = [
            'user_id' => [$user['user_id']],
            'mfg_dealer_number' => [$user['mfg_dealer_number']],
            'location_name' => [$location['name']],
            'first_name' => [$name[0]],
            'last_name' => [$name[1]],
            'email' => [$user['email']],
            'address1' => [$location['address']],
            'address2' => [$location['address2']],
            'city' => [$location['city']],
            'country' => [$location['country_abbrev']],
            'state' => [$location['state_abbrev']],
            'zip' => [$location['zip']],
            'phone' => [$location['phone']],
            'user_type' => [$user_type],
          
        ];        
        
        
        if ($attributes !== null) {
            /*
             * The user is already authenticated.
             *
             * Add the users attributes to the $state-array, and return control
             * to the authentication process.
             */
            $state['Attributes'] = $attributes;
            return;
        }

        /*
         * The user isn't authenticated. We therefore need to
         * send the user to the login page.
         */

        /*
         * First we add the identifier of this authentication source
         * to the state array, so that we know where to resume.
         */
        $state['mymodule:AuthID'] = $this->authId;

        /*
         * We need to save the $state-array, so that we can resume the
         * login process after authentication.
         *
         * Note the second parameter to the saveState-function. This is a
         * unique identifier for where the state was saved, and must be used
         * again when we retrieve the state.
         *
         * The reason for it is to prevent
         * attacks where the user takes a $state-array saved in one location
         * and restores it in another location, and thus bypasses steps in
         * the authentication process.
         */
        $stateId = Auth\State::saveState($state, 'mymodule:MyAuth');

        /*
         * Now we generate a URL the user should return to after authentication.
         * We assume that whatever authentication page we send the user to has an
         * option to return the user to a specific page afterwards.
         */
        $returnTo = Module::getModuleURL('mymodule/resume', [
            'State' => $stateId,
        ]);

        /*
         * Get the URL of the authentication page.
         *
         * Here we use the getModuleURL function again, since the authentication page
         * is also part of this module, but in a real example, this would likely be
         * the absolute URL of the login page for the site.
         */
        $authPage = Module::getModuleURL('mymodule/authpage');

        /*
         * The redirect to the authentication page.
         *
         * Note the 'ReturnTo' parameter. This must most likely be replaced with
         * the real name of the parameter for the login page.
         */
        $httpUtils = new Utils\HTTP();
        $httpUtils->redirectTrustedURL($authPage, [
            'ReturnTo' => $returnTo,
        ]);

        /*
         * The redirect function never returns, so we never get this far.
         */
        Assert::true(false);
    }


    /**
     * Resume authentication process.
     *
     * This function resumes the authentication process after the user has
     * entered his or her credentials.
     *
     * @param \Symfony\Component\HttpFoundation\Request $request
     *
     * @throws \SimpleSAML\Error\BadRequest
     * @throws \SimpleSAML\Error\Exception
     */
    public static function resume(Request $request)
    {
        /*
         * First we need to restore the $state-array. We should have the identifier for
         * it in the 'State' request parameter.
         */
        if (!$request->query->has('State')) {
            throw new Error\BadRequest('Missing "State" parameter.');
        }

        /*
         * Once again, note the second parameter to the loadState function. This must
         * match the string we used in the saveState-call above.
         */
        $state = Auth\State::loadState($request->query->get('State'), 'mymodule:MyAuth');

        /*
         * Now we have the $state-array, and can use it to locate the authentication
         * source.
         */
        $source = Auth\Source::getById($state['mymodule:AuthID']);
        if ($source === null) {
            /*
             * The only way this should fail is if we remove or rename the authentication source
             * while the user is at the login page.
             */
            throw new Error\Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
        }

        /*
         * Make sure that we haven't switched the source type while the
         * user was at the authentication page. This can only happen if we
         * change config/authsources.php while an user is logging in.
         */
        if (!($source instanceof self)) {
            throw new Error\Exception('Authentication source type changed.');
        }

        /*
         * OK, now we know that our current state is sane. Time to actually log the user in.
         *
         * First we check that the user is acutally logged in, and didn't simply skip the login page.
         */
           
        require_once('/yyy/xxx/some_server/public_html/web/setup.php');

       
        $_users = new \Users;
        $user = $_users->verifyUser($username,$password);
        

        $attributes = [
            'user_id' => [$user['user_id']],
            'mfg_dealer_number' => [$user['mfg_dealer_number']],
            'location_name' => [$location['name']],
            'first_name' => [$name[0]],
            'last_name' => [$name[1]],
            'email' => [$user['email']],
            'address1' => [$location['address']],
            'address2' => [$location['address2']],
            'city' => [$location['city']],
            'country' => [$location['country_abbrev']],
            'state' => [$location['state_abbrev']],
            'zip' => [$location['zip']],
            'phone' => [$location['phone']],
            'user_type' => [$user_type],
          
        ];        
         
         
        if ($attributes === null) {
            /*
             * The user isn't authenticated.
             *
             * Here we simply throw an exception, but we could also redirect the user back to the
             * login page.
             */
            throw new Error\Exception('User not authenticated after login page.');
        }

        /*
         * So, we have a valid user. Time to resume the authentication process where we
         * paused it in the authenticate()-function above.
         */

        $state['Attributes'] = $attributes;
        Auth\Source::completeAuth($state);

        /*
         * The completeAuth-function never returns, so we never get this far.
         */
        Assert::true(false);
    }


    /**
     * This function is called when the user start a logout operation, for example
     * by logging out of a SP that supports single logout.
     *
     * @param array &$state  The logout state array.
     */
    public function logout(array &$state)
    {
        //$session = new SymfonySession();
        //if (!$session->getId()) {
        //    $session->start();
        //}

        $session->clear();

        /*
         * If we need to do a redirect to a different page, we could do this
         * here, but in this example we don't need to do this.
         */
    }
}

【问题讨论】:

    标签: php idp


    【解决方案1】:

    您似乎混淆了两个 SimpleSAML 版本。

    这段代码:

        public function authenticate(array &$state)
    

    其中包含“数组”类型提示,而您在 SimpleSAMLphp 中扩展的类没有,如错误消息所示:

    must be compatible with SimpleSAML\Auth\Source::authenticate(&$state)
    

    所以删除array 关键字。如果您使用与您正在运行的 SimpleSAMLphp 版本匹配的代码/文档,则应该匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-22
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多