【问题标题】:Verifying JWT from Azure Active Directory从 Azure Active Directory 验证 JWT
【发布时间】:2015-11-15 14:24:57
【问题描述】:

我已按照此处的说明获取 Web API 的访问令牌。

https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx

我有这个工作,但文档在弄清楚如何在 PHP 中验证令牌时含糊不清。

您可以使用响应中返回的访问令牌对受保护资源(例如 Web API)进行身份验证。通常,令牌使用承载方案在 HTTP 请求中呈现给 Web API,RFC 6750 中对此进行了描述。本规范说明了如何在 HTTP 请求中使用承载令牌来访问受保护的资源。

当 Web API 接收并验证令牌时,它会授予本机客户端应用程序对 Web API 的访问权限。

如何在应用程序中验证 JWT?我有一个 PHP 框架,它使用带有令牌、签名、密钥和算法的 PHP openssl_verify() 函数,但是当我使用 Azure 的私钥和 SHA256 算法时收到错误:

openssl_verify(): supplied key param cannot be coerced into a public key

这让我相信我在 PHP 中用来验证的密钥不正确。目前,我正在使用为 Active Directory 应用程序生成的私钥,这恰好与我在点击 oauth2/token url 时用于“client_secret”参数的值相同(任何其他值都会导致没有令牌生成,所以这可能是正确的)。

密钥类似于(但实际上不是):

cLDQWERTYUI12asdqwezxctlkjpoiAn7yhjeutl8jsP=

我认为 openssl 需要证书的地方...如果是这样,我似乎无法在 Azure 门户中找到该证书。

我在这里缺少什么?我应该使用 openssl_verify() 来验证 JWT 的密钥是什么?在 Azure 中的哪里可以找到它?

谢谢

--

更新:

我在这里找到了公钥:https://login.windows.net/common/discovery/keys

但是我仍然无法使用提供的 X5C 来验证签名。你如何在 PHP 中做到这一点?

--

更新 2:

我使用转换为使用“e”和“n”参数的公钥创建一个 .pem 文件。这收到了一个公钥。

现在我在用它解密时收到 OPEN SSL 错误:

error:0906D06C:PEM routines:PEM_read_bio:no start line

【问题讨论】:

    标签: php azure openssl cryptography jwt


    【解决方案1】:

    结束这个问题,因为我已经从原始问题移开。用 cmets 更新了我的问题,显示了我的进展情况。

    为新的特定问题创建了一个新问题:How do I verify a JSON Web Token using a Public RSA key?

    --

    以防万一它对其他人有所帮助:

    有关在 PHP 中从 Microsoft 获取公钥的解决方案的更多信息,我执行了以下操作:

    $string_microsoftPublicKeyURL = 'https://login.windows.net/common/discovery/keys';
    
    $array_publicKeysWithKIDasArrayKey = loadKeysFromAzure($string_microsoftPublicKeyURL);
    
    
    function loadKeysFromAzure($string_microsoftPublicKeyURL) {
        $array_keys = array();
    
        $jsonString_microsoftPublicKeys = file_get_contents($string_microsoftPublicKeyURL);
        $array_microsoftPublicKeys = json_decode($jsonString_microsoftPublicKeys, true);
    
        foreach($array_microsoftPublicKeys['keys'] as $array_publicKey) {
            $string_certText = "-----BEGIN CERTIFICATE-----\r\n".chunk_split($array_publicKey['x5c'][0],64)."-----END CERTIFICATE-----\r\n";
            $array_keys[$array_publicKey['kid']] = getPublicKeyFromX5C($string_certText);
        }
    
        return $array_keys;
    }
    
    
    function getPublicKeyFromX5C($string_certText) {
        $object_cert = openssl_x509_read($string_certText);
        $object_pubkey = openssl_pkey_get_public($object_cert);
        $array_publicKey = openssl_pkey_get_details($object_pubkey);
        return $array_publicKey['key'];
    }
    

    最好将它们缓存到磁盘上,这样您就不必每次都加载它们,但这只是一个简单的示例。

    然后,使用公钥数组,检查 JWT 标头中的“kid”值,以找到正确的公共证书进行验证,并在 openssl_verify() 的参数 3 中使用它。我使用 JWT 类为我处理这个问题。

    使用上面创建的这个公钥数组和 JWT 类应该允许您验证 Microsoft JWT。

    从 firebase 链接到 JWT 类:https://github.com/firebase/php-jwt

    使用 JWT 的参数 1、此公钥数组的参数 2 和仅包含“RS256”的数组的参数 3 调用 JWT::Decode。

    JWT::decode($string_JSONWebToken, $array_publicKeysWithKIDasArrayKey, array('RS256'));
    

    如果 JWT 无效或返回解密的 JWT 供您使用(并检查声明),这将引发异常。

    【讨论】:

    • 看来你已经在stackoverflow.com/questions/32185238/…解决了这个问题,如果你能在这里总结一下解决的关键点就更好了,其他有类似问题的社区也可以从这个帖子中受益.
    【解决方案2】:

    如果你想验证 jwt 然后去 jwt.io 这将允许您粘贴 JWT,然后它将验证标头、声明,如果您添加公钥或私钥(取决于服务器如何验证签名),它还将验证 JWT 的签名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 2015-01-11
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-08
      • 2016-12-15
      相关资源
      最近更新 更多