authentication - 如何从身份验证器重定向到外部身份验证端点?
问题描述
我正在编写一个网络应用程序,由于不同客户的需求,我希望它具有灵活的身份验证选项。我正在使用官方的cakephp/authentication库,但它没有 OpenID Connect Authenticator,所以我自己滚动。
我遇到的问题是我无法Cake\Http\Response
从身份验证器返回带有重定向标头的修改对象。 AuthenticatorInterface
需要authenticate()
方法返回一个Result
对象。我希望不必修改 Authenticator 类,因为如果我只是要重写它的流程,它有点违背使用库的目的。
class OidcAuthenticator extends AbstractAuthenticator
{
public function authenticate(ServerRequestInterface $request, ResponseInterface $response)
{
// non-pertinent code removed for brevity
return $this->_requestAuthorization($request, $response);
}
private function _requestAuthorization(ServerRequestInterface $request, ResponseInterface $response)
{
$auth_endpoint = $this->getConfig('authorization_endpoint');
$response_type = 'code';
$state = $this->_setState($request, Security::randomString());
$auth_params = [
'response_type' => $response_type,
'redirect_uri' => 'http://localhost:8080/',
'client_id' => $this->getConfig('client_id'),
'nonce' => $nonce,
'state' => $state,
'scope' => 'openid'
];
$auth_endpoint .= (strpos($auth_endpoint, '?') === false ? '?' : '&') .
http_build_query($auth_params, null, '&');
/* What I want to return */
$response = $response->withHeader('Location', $auth_endpoint);
/* What I have to return */
return new Result(null, Result::FAILURE_MISSING_CREDENTIALS);
}
}
我可以让这个工作
$request->getAttribute('session')->close();
header('Location: ' . $auth_endpoint, true, 302);
exit();
但这似乎违反了 CakePHP 的约定。理想情况下,我可以将新的响应对象嵌入到 Result 中,并且 Authentication 中间件会捕获并发出它,而不是UnauthenticatedException
. 这是一个最佳实践问题,但希望它对 SO 来说足够具体。
TL;DR:当您无法将响应对象返回到中间件队列时如何重定向?
解决方案
AFAICT 目前还没有真正推荐的做法,可能值得在 GitHub 上打开一个问题进行澄清。
您可以使用AuthenticationRequiredException
(或UnauthorizedException
在早期版本中),它与无状态身份验证有点纠缠不清,但没有什么可以阻止您使用它。与无状态身份验证器不同,您必须将其放入authenticate()
方法调用流程中,如下所示:
private function _requestAuthorization(
ServerRequestInterface $request,
ResponseInterface $response
) {
// ...
$headers = [
'Location' => $auth_endpoint
];
$body = null;
$statusCode = 302;
// in CakePHP 4.x / Authentication 2.x
throw new \Authentication\Authenticator\AuthenticationRequiredException (
$headers,
$body,
$statusCode
);
// in CakePHP 3.x / Authentication 1.x
throw new \Authentication\Authenticator\UnauthorizedException(
$headers,
$body,
$statusCode
);
}
然后将AuthenticationMiddleware::__invoke()
相应地处理,其中将修改并返回响应。
推荐阅读
- ruby - 无法从 Ruby 连接到 gmail SMTP 服务器
- html - 如何使侧边栏菜单与正文的左边距对齐?
- c - 不明白这个陌生的语法:arr1[ arr2[i] - 'a' ]++
- asp.net-core - ASP.Net Core Web App Reauthentication with Microsoft.Identity.Web
- python - PyMySQL 在数据库中的每次咨询都变得越来越慢
- c - 通过模拟它在 C 中调用的非静态函数来测试静态函数
- c# - EF Core 错误地为 Array 执行多次插入
- php - 验证信用卡号
- rust - FuturesUnordered 的终身问题
- keepalived - keepalived:不可预知的转发方式