从 Azure Active Directory 验证 JWT
Verifying JWT from Azure Active Directory
我已按照此处的说明获取网络访问令牌 API。
https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx
我有这个工作,但在弄清楚如何验证 PHP 中的令牌时,文档含糊不清。
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() 函数,但是当我将来自 Azure 的私钥与 SHA256 一起使用时,我收到错误消息算法:
openssl_verify(): supplied key param cannot be coerced into a public key
这让我相信我在 PHP 中用来验证的密钥是不正确的。目前,我正在使用我为 Active Directory 应用程序生成的私钥,它恰好与我在点击 oauth2/token [=69 时为“client_secret”参数使用的值相同=](任何其他值都不会生成令牌,因此这可能是正确的)。
密钥类似于(但实际上不是):
cLDQWERTYUI12asdqwezxctlkjpoiAn7yhjeutl8jsP=
我认为 openssl 需要证书的地方...如果是的话,我似乎无法在 Azure 门户中找到该证书的位置。
我在这里错过了什么?我应该使用 openssl_verify() 来验证 JWT 的密钥是什么?我在 Azure 中的什么地方可以找到它?
谢谢
--
更新:
我在这里找到了 public 键:https://login.windows.net/common/discovery/keys
但是我还是无法使用提供的X5C来验证签名。在 PHP 中如何做到这一点?
--
更新 2:
我使用转换后的 'e' 和 'n' 参数为 public 键创建了一个 .pem 文件。这收到了一个 public 密钥。
现在用它解密时出现 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 获取 public 密钥的解决方案的更多信息,我执行了以下操作:
$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'];
}
不过,最好将它们缓存到磁盘,这样您就不会每次都加载它们,但这只是一个如何执行此操作的简单示例。
然后,使用 public 键数组,检查 JWT header 的 'kid' 值以找到正确的 public 证书来验证并使用它在 openssl_verify() 中的参数 3 中。我使用 JWT class 来为我处理这个问题。
使用上面创建的 public 键数组和 JWT class 应该可以让您验证 Microsoft JWT。
Link 从 firebase 到 JWT class:https://github.com/firebase/php-jwt
使用 JWT 的参数 1、此 public 键数组的参数 2 和 'RS256'.
数组的参数 3 调用 JWT::Decode
JWT::decode($string_JSONWebToken, $array_publicKeysWithKIDasArrayKey, array('RS256'));
如果 JWT 无效或 return 一个解密的 JWT 供您使用(并检查声明),这将引发异常。
如果你想验证 jwt 然后去 jwt.io
这将允许您粘贴 JWT,然后它会验证 header、声明,如果您添加 Public 密钥或私钥(取决于服务器验证签名的方式),它还会验证JWT 的签名。
我已按照此处的说明获取网络访问令牌 API。
https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx
我有这个工作,但在弄清楚如何验证 PHP 中的令牌时,文档含糊不清。
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() 函数,但是当我将来自 Azure 的私钥与 SHA256 一起使用时,我收到错误消息算法:
openssl_verify(): supplied key param cannot be coerced into a public key
这让我相信我在 PHP 中用来验证的密钥是不正确的。目前,我正在使用我为 Active Directory 应用程序生成的私钥,它恰好与我在点击 oauth2/token [=69 时为“client_secret”参数使用的值相同=](任何其他值都不会生成令牌,因此这可能是正确的)。
密钥类似于(但实际上不是):
cLDQWERTYUI12asdqwezxctlkjpoiAn7yhjeutl8jsP=
我认为 openssl 需要证书的地方...如果是的话,我似乎无法在 Azure 门户中找到该证书的位置。
我在这里错过了什么?我应该使用 openssl_verify() 来验证 JWT 的密钥是什么?我在 Azure 中的什么地方可以找到它?
谢谢
--
更新:
我在这里找到了 public 键:https://login.windows.net/common/discovery/keys
但是我还是无法使用提供的X5C来验证签名。在 PHP 中如何做到这一点?
--
更新 2:
我使用转换后的 'e' 和 'n' 参数为 public 键创建了一个 .pem 文件。这收到了一个 public 密钥。
现在用它解密时出现 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 获取 public 密钥的解决方案的更多信息,我执行了以下操作:
$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'];
}
不过,最好将它们缓存到磁盘,这样您就不会每次都加载它们,但这只是一个如何执行此操作的简单示例。
然后,使用 public 键数组,检查 JWT header 的 'kid' 值以找到正确的 public 证书来验证并使用它在 openssl_verify() 中的参数 3 中。我使用 JWT class 来为我处理这个问题。
使用上面创建的 public 键数组和 JWT class 应该可以让您验证 Microsoft JWT。
Link 从 firebase 到 JWT class:https://github.com/firebase/php-jwt
使用 JWT 的参数 1、此 public 键数组的参数 2 和 'RS256'.
数组的参数 3 调用 JWT::DecodeJWT::decode($string_JSONWebToken, $array_publicKeysWithKIDasArrayKey, array('RS256'));
如果 JWT 无效或 return 一个解密的 JWT 供您使用(并检查声明),这将引发异常。
如果你想验证 jwt 然后去 jwt.io 这将允许您粘贴 JWT,然后它会验证 header、声明,如果您添加 Public 密钥或私钥(取决于服务器验证签名的方式),它还会验证JWT 的签名。