一起使用 CakePHP 表单和基本身份验证
Using CakePHP Form and Basic Authentication together
我使用 CakePHP 3.8 和 Authentication 1.0 创建了一个简单的测试站点来试用它。我想同时使用 Form 和 Basic 身份验证,因为预期的应用程序将提供 REST 调用。
如果不包含 HttpBasic,站点将正常工作,即显示登录 window。但是,使用 HttpBasic,站点直接进入基本身份验证。
代码直接来自食谱。
我错过了什么?
public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response)
{
$service = new AuthenticationService();
$service->setConfig([
'unauthenticatedRedirect' => '/users/login',
'queryParam' => 'redirect'
]);
$fields = [
'username' => 'user',
'password' => 'password',
];
// Load Identifiers
$service->loadIdentifier('Authentication.Password', compact('fields'));
// Load the authenticators
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form', [
'fields' => $fields,
'loginUrl' => '/users/login',
]);
$service->loadAuthenticator('Authentication.HttpBasic');
return $service;
}
如评论中所述,同时使用表单身份验证器和 HTTP 基本身份验证器效果不会太好,这是因为身份验证服务不会停止执行所有已加载的身份验证器,除非其中之一他们 returns 表示身份验证成功的响应。
这意味着您将始终看到身份验证质询响应,而永远看不到您的登录表单。只有实际的身份验证部分才能在该星座中工作,即直接将您的登录凭据作为表单数据发送到登录端点。
如果您实际上不需要阻止您访问登录表单的基本身份验证质询响应,那么您可以使用不会导致返回质询响应的 custom/extended 身份验证器,这应该像覆盖 \Authentication\Authenticator\HttpBasicAuthenticator::unauthorizedChallenge()
:
一样简单
src/Authenticator/ChallengelessHttpBasicAuthenticator.php
namespace App\Authenticator;
use Authentication\Authenticator\HttpBasicAuthenticator;
use Psr\Http\Message\ServerRequestInterface;
class ChallengelessHttpBasicAuthenticator extends HttpBasicAuthenticator
{
public function unauthorizedChallenge(ServerRequestInterface $request)
{
// noop
}
}
$service->loadAuthenticator(\App\Authenticator\ChallengelessHttpBasicAuthenticator::class);
此外,您可能需要添加额外的检查以防您的应用程序使用身份验证组件的 setIdentity()
方法,这会导致身份在会话中持久保存,即使在使用无状态身份验证器时也是如此。如果你不想这样,那么你需要在设置身份之前测试成功的验证器是否是无状态的:
$provider = $this->Authentication->getAuthenticationService()->getAuthenticationProvider();
if (!($provider instanceof \Authentication\Authenticator\StatelessInterface))
{
$this->Authentication->setIdentity(/* ... */);
}
我使用 CakePHP 3.8 和 Authentication 1.0 创建了一个简单的测试站点来试用它。我想同时使用 Form 和 Basic 身份验证,因为预期的应用程序将提供 REST 调用。
如果不包含 HttpBasic,站点将正常工作,即显示登录 window。但是,使用 HttpBasic,站点直接进入基本身份验证。
代码直接来自食谱。
我错过了什么?
public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response)
{
$service = new AuthenticationService();
$service->setConfig([
'unauthenticatedRedirect' => '/users/login',
'queryParam' => 'redirect'
]);
$fields = [
'username' => 'user',
'password' => 'password',
];
// Load Identifiers
$service->loadIdentifier('Authentication.Password', compact('fields'));
// Load the authenticators
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form', [
'fields' => $fields,
'loginUrl' => '/users/login',
]);
$service->loadAuthenticator('Authentication.HttpBasic');
return $service;
}
如评论中所述,同时使用表单身份验证器和 HTTP 基本身份验证器效果不会太好,这是因为身份验证服务不会停止执行所有已加载的身份验证器,除非其中之一他们 returns 表示身份验证成功的响应。
这意味着您将始终看到身份验证质询响应,而永远看不到您的登录表单。只有实际的身份验证部分才能在该星座中工作,即直接将您的登录凭据作为表单数据发送到登录端点。
如果您实际上不需要阻止您访问登录表单的基本身份验证质询响应,那么您可以使用不会导致返回质询响应的 custom/extended 身份验证器,这应该像覆盖 \Authentication\Authenticator\HttpBasicAuthenticator::unauthorizedChallenge()
:
src/Authenticator/ChallengelessHttpBasicAuthenticator.php
namespace App\Authenticator;
use Authentication\Authenticator\HttpBasicAuthenticator;
use Psr\Http\Message\ServerRequestInterface;
class ChallengelessHttpBasicAuthenticator extends HttpBasicAuthenticator
{
public function unauthorizedChallenge(ServerRequestInterface $request)
{
// noop
}
}
$service->loadAuthenticator(\App\Authenticator\ChallengelessHttpBasicAuthenticator::class);
此外,您可能需要添加额外的检查以防您的应用程序使用身份验证组件的 setIdentity()
方法,这会导致身份在会话中持久保存,即使在使用无状态身份验证器时也是如此。如果你不想这样,那么你需要在设置身份之前测试成功的验证器是否是无状态的:
$provider = $this->Authentication->getAuthenticationService()->getAuthenticationProvider();
if (!($provider instanceof \Authentication\Authenticator\StatelessInterface))
{
$this->Authentication->setIdentity(/* ... */);
}