php - 请求 oauth2 令牌时获取 invalid_grant

我正在尝试针对我们公司用于 SSO 的 MS 身份服务器检索令牌。我尝试了几种方法并继续得到 invalid_grant 错误响应。

这是我的脚本(敏感数据被隐藏):

<?php
//start the session to later store my verifier
session_start();

$client_id = 'my-client-id';
$client_secret = ''; //not using a secret because we are using PKCE
$access_token_url = "https://my-server-address/connect/token";
$redirect_uri = 'http://localhost/test.php';
$scope = 'openid and other scope items';

if (!isset($_SESSION['verifier']) && !isset($_GET['code'])) {
    $code_verifier = substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil(50 / strlen($x)))), 1, 50);

    $_SESSION['verifier'] = $code_verifier;
    $hash = hash('sha256', $code_verifier);
    $code_challenge = base64_encode(pack('H*', $hash));

    $dialog_url = "https://my-server-address/Account/Login?ReturnUrl=" . urlencode('/id-server-2fa/connect/authorize/callback?client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&code_challenge=' . $code_challenge . '&code_challenge_method=S256&response_type=code&scope=openid other scope items&response_mode=query&acr_values=' . urlencode('tenant:companyidused'));
}

if (isset($_GET['code'])) {

    $curl = curl_init();

    curl_setopt($curl, CURLOPT_URL, $access_token_url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($curl, CURLOPT_ENCODING, '');
    curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($curl, CURLOPT_POSTFIELDS, array(
        'code' => $_GET['code'],
        'code_verifier' => $_SESSION['verifier'],
        'client_id' => $client_id,
        'client_secret' => '',
        'grant_type' => 'authorization_code',
        'redirect_uri' => $redirect_uri
    ));

    $data = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);
    if ($err) {
        echo "cURL Error #:" . $err;
        die;
    } else {
        echo "Data" . $data . "<br/>";
    }

    $auth_string = json_decode($data, true); // token will be with in this json

    $apiToken = $auth_string['access_token'];
    $_SESSION['token'] = $apiToken;
    echo $auth_string['access_token'];
}

if (!isset($_SESSION['token'])) {
    echo "VERIFIER: " . $_SESSION['verifier'] . "<br/>";
    echo '<a href="' . $dialog_url . '">Click here to login</a>';
}

我也尝试过,根据这篇文章(https://auth0.com/docs/get-started/authentication-and-authorization-flow/call-your-api-using-the-authorization-code-flow-with-pkce#-response),对我的 redirect_url value 进行 urlcode 并使用 curl HTTPHEADER 发送 "content-type: application/x-www-form-urlencoded"

有没有人用这种方法成功过,如果是这样,你能看出我做错了什么吗?

谢谢!

回答1

好的,我发现了我自己的问题并让它工作。

$code_challenge = base64_encode(pack('H*', $hash)); //base64_encode

实际上应该是:

$code_challenge = base64url_encode(pack('H*', $hash)); //base64url_encode

然后,我必须添加这个函数来正确编码字符串:

function base64url_encode($plainText)
{
    $base64 = base64_encode($plainText);
    $base64 = trim($base64, "=");
    $base64url = strtr($base64, '+/', '-_');
    return ($base64url);
}

相似文章