php - 如何使用客户端证书而不是 secret (PHP) 让 OpenID Connect 工作?

标签 php azure-active-directory openid-connect

我是 OIDC 的新手,正在部署 SSO 应用程序。使用带有以下代码的客户端 key 时一切正常,但我公司的 Azure AD/Entra 配置要求在使用移动设备时使用客户端证书(而不是 key )。

我已使用 openssl 生成了 key 对并将公钥上传到 Azure 门户,确认指纹正确。但是我不知道如何将私钥输入到我的代码中。有人可以帮忙吗?

require_once 'vendor/autoload.php';

use Jumbojett\OpenIDConnectClient;
$oidc = new OpenIDConnectClient('*url*', '*clientid*', null);
$oidc->setTokenEndpointAuthMethodsSupported(['private_key_jwt']);
$oidc->authenticate();
print_r($oidc->requestUserInfo());

最佳答案

经过大量搜索并结合各种资源,我想我找到了答案。在这里发帖是为了其他可能有同样问题的人。

要点:

  1. 使用 $oidc->setTokenEndpointAuthMethodsSupported() 启用“private_key_jwt”作为受支持的身份验证方法
  2. 编写一个自定义函数,使用由私钥签名的客户端信息创建标准 JWT。使用 $oidc->setPrivateKeyJwtGenerator()
  3. 将其绑定(bind)到 $oidc
  4. Azure/OpenSSL 生成的公共(public)证书指纹是一个十六进制字符串(如 AB12C2D5FF...) - 需要将其转换为二进制,然后进行 Base64 编码,作为“x5t”参数添加到 JWT header :$headers['x5t'] =\base64_encode(\hex2bin('*public_key_thumbprint*'))

PHP OIDC 客户端代码:

require_once 'vendor/autoload.php';

use Jumbojett\OpenIDConnectClient;

$clientId = '*clientId*';
$oidc = new OpenIDConnectClient('*url*', $clientId, null);
$oidc->setTokenEndpointAuthMethodsSupported(['private_key_jwt']);
$oidc->setPrivateKeyJwtGenerator(function (string $token_endpoint) {
    global $clientId;
    $key = \file_get_contents('*private_key_file*');
    $headers = [
        'typ' => 'JWT',
        'alg' => 'RS256',
        'x5t' => \base64_encode(\hex2bin('*public_cert_thumbprint*')),
    ];
    $payload = [
        'iss' => $clientId,
        'sub' => $clientId,
        'aud' => $token_endpoint,
        'jti' => \base64_encode(\random_bytes(16)),
        'exp' => \time() + 300,
    ];
    openssl_sign(
        base64UrlEncode(json_encode($headers)) . "." . base64UrlEncode(json_encode($payload)),
        $signature,
        $key,
        "sha256WithRSAEncryption"
    );
    $jwt = base64UrlEncode(json_encode($headers)) . "." . base64UrlEncode(json_encode($payload)) . "." . base64UrlEncode($signature);

    return $jwt;
});
$oidc->authenticate();
print_r($oidc->requestUserInfo());

function base64UrlEncode(string $text): string
{
    return rtrim(strtr(base64_encode($text), '+/', '-_'), '=');
}
`

关于php - 如何使用客户端证书而不是 secret (PHP) 让 OpenID Connect 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77435605/

相关文章:

php - 仅返回字符串开头的大写字母的函数?

php - MySQL - 按不同标准对帖子/评论进行排序和分组

php - 请求的 Doctrine 未知列类型 "Date"

oauth - 我如何测试是否已获得管理员同意

oauth-2.0 - 带有 OIDC 和 Azure AD 的代码流 PKCE 在/token 端点上出现 cors 错误

php - 如何从数组中删除所有 html 标签?

oauth-2.0 - Microsoft 图 API 访问 token 生命周期

azure - 是否可以使用 PowerShell 中的服务主体将角色和范围分配给新创建的应用程序?

oauth-2.0 - 您是否为 OAuth 2.0 请求生成后端或前端状态参数?

oauth-2.0 - 是否应该将身份验证代码将访问 token 交换访问权转移到用于Web API/SPA OpenID Connect实现的API?