authentication - 如何从身份验证器重定向到外部身份验证端点?

标签 authentication cakephp openid-connect

我正在编写一个网络应用程序,由于不同客户的需求,我希望它具有灵活的身份验证选项。我用的是官方cakephp/authentication库,但它没有 OpenID Connect Authenticator,所以我自己动手。

我遇到的问题是我无法从我的身份验证器返回带有重定向 header 的修改后的 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:无法将响应对象返回到中间件队列时如何重定向?

最佳答案

AFAICT 目前还没有真正推荐的做法,可能值得提出一个问题 over at 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() 中处理相应地,响应将被修改和返回的位置。

关于authentication - 如何从身份验证器重定向到外部身份验证端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54067100/

相关文章:

javascript - dojo Web 应用程序身份验证

r - 使用 RGoogleDocs 登录谷歌电子表格

php - 如何使用带有 POST 和 Cookie 的 cURL 登录

model-view-controller - 遵循 MVC 时递归函数放在哪里?

php - 将数据作为参数传递给测试用例 cakephp 中的操作

keycloak - 有没有办法在 OIDC 代码授权流程中传递状态?

c# - ASP.NET Core 2.1 cookie 身份验证似乎具有服务器亲和性

.net - 序列化/反序列化 GenericXmlSecurityToken 和安全性 - CRM Auth

php - SQLSTATE[HY000] [1045] 使用 CakePHP 拒绝用户 'username' @'localhost' 的访问

qt - Google OAuth 始终显示同意屏幕