我已按照此处的说明获取 Web API 的访问 token 。
https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx
我已经完成了这项工作,但在弄清楚如何在 PHP 中验证 token 时,文档很模糊。
You can use the access token that is returned in the response to authenticate to a protected resources, such as a web API. Typically, the token is presented to the web API in an HTTP request using the Bearer scheme, which is described in RFC 6750. This specification explains how to use bearer tokens in HTTP requests to access protected resources.
When the web API receives and validates the token, it gives the native client application access to the web API.
如何在应用程序中验证 JWT?我有一个 PHP 框架,它使用 PHP openssl_verify() 函数以及 token 、签名、 key 和算法,但是当我使用来自 Azure 的私钥和 SHA256 算法时,我收到错误:
openssl_verify(): supplied key param cannot be coerced into a public key
这让我相信我在 PHP 中用于验证的 key 不正确。目前,我正在使用为 Active Directory 应用程序生成的私钥,该私钥也恰好与我在点击 oauth2/token url 时为“client_secret”参数使用的值相同(任何其他值都会导致没有 token 生成,因此这可能是正确的)。
key 类似于(但实际上不是):
cLDQWERTYUI12asdqwezxctlkjpoiAn7yhjeutl8jsP=
我认为 openssl 需要有一个证书...如果是这样,我似乎无法在 Azure 门户中找到该证书的位置。
我在这里缺少什么?我应该使用 openssl_verify() 来验证 JWT 的 key 是什么?在 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
最佳答案
结束这个问题,因为我已经离开了原来的问题。用评论更新了我的问题,显示了我的进展。
针对新的具体问题创建了一个新问题: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 header 中的“kid”值,以找到要验证的正确公共(public)证书,并在 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 供您使用(并检查声明)。
关于php - 从 Azure Active Directory 验证 JWT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32143743/