我正在编写一个网络应用程序,由于不同客户的需求,我希望拥有灵活的身份验证选项。我用的是官方的cakephp/身份验证库,但它没有 OpenID Connect 身份验证器,所以我正在滚动自己的。
我遇到的问题是我无法返回修改后的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 约定。理想情况下,我可以将新的响应对象嵌入到结果中,身份验证中间件将捕获它并发出它,而不是UnauthenticatedException
。这是一个最佳实践问题,但希望它对于 SO 来说足够具体。
TL;DR:当无法将响应对象返回到中间件队列时如何重定向?