Php 从Azure Active Directory验证JWT
我按照这里的说明获取web API的访问令牌 我有这项工作,但当涉及到如何在PHP中验证令牌时,文档是模糊的 您可以使用响应中返回的访问令牌对受保护的资源(如web API)进行身份验证。通常,令牌在HTTP请求中使用承载方案呈现给web API,如RFC 6750中所述。本规范解释了如何在HTTP请求中使用承载令牌来访问受保护的资源 当web API接收并验证令牌时,它会让本机客户端应用程序访问web API 如何在应用程序中验证JWT?我有一个PHP框架,它使用PHP openssl_verify()函数和令牌、符号、密钥和算法,但当我将Azure的私钥与SHA256算法一起使用时,收到错误消息:Php 从Azure Active Directory验证JWT,php,azure,openssl,cryptography,jwt,Php,Azure,Openssl,Cryptography,Jwt,我按照这里的说明获取web API的访问令牌 我有这项工作,但当涉及到如何在PHP中验证令牌时,文档是模糊的 您可以使用响应中返回的访问令牌对受保护的资源(如web API)进行身份验证。通常,令牌在HTTP请求中使用承载方案呈现给web API,如RFC 6750中所述。本规范解释了如何在HTTP请求中使用承载令牌来访问受保护的资源 当web API接收并验证令牌时,它会让本机客户端应用程序访问web API 如何在应用程序中验证JWT?我有一个PHP框架,它使用PHP openssl_ve
openssl_verify(): supplied key param cannot be coerced into a public key
这让我相信我在PHP中用来验证的密钥是不正确的。目前,我正在使用为Active Directory应用程序生成的私钥,它恰好也是我在点击oauth2/令牌url时为“client_secret”参数使用的相同值(任何其他值都不会导致生成令牌,因此这可能是正确的)
该键类似于(但实际上不是):
我认为openssl需要有一个证书。。。如果是这样,我似乎无法在Azure门户中找到此证书的位置
我错过了什么?我应该在openssl_verify()中使用什么密钥来验证JWT?我在Azure中的何处可以找到它
谢谢
--
更新:
我在这里找到了公钥:
但是,我仍然无法使用提供的X5C来验证签名。如何在PHP中实现这一点
--
更新2:
我使用一个转换后的文件为公钥创建了一个.pem文件,该文件使用了“e”和“n”参数。这收到了一个公钥
现在,在使用它进行解密时,我会遇到OPEN SSL错误:
error:0906D06C:PEM routines:PEM_read_bio:no start line
结束这个问题,我从最初的问题开始。更新了我的问题,并添加了说明我进展情况的评论 为新的特定问题创建了新问题: -- 以防万一对其他人有帮助: 有关使用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 JWTs
从firebase链接到JWT类:
使用JWT的参数1、此公钥数组的参数2和仅为“RS256”的数组的参数3调用JWT::Decode
JWT::decode($string_JSONWebToken, $array_publicKeysWithKIDasArrayKey, array('RS256'));
如果JWT无效或返回解密的JWT供您使用(并检查声明),这将引发异常。如果要验证JWT,请转到JWT.io
这将允许您粘贴JWT,然后它将验证标题、声明,如果您添加公钥或私钥(取决于服务器验证签名的方式),它还将验证JWT的签名。看起来您已经在解决了问题,如果您可以在此处总结解决方案的要点,则会更好,然后,其他有类似问题的社区将从该线程中受益。
JWT::decode($string_JSONWebToken, $array_publicKeysWithKIDasArrayKey, array('RS256'));