【发布时间】:2019-06-14 23:40:22
【问题描述】:
有一个基于 .NET Framework 的 Windows 桌面应用程序,它与基于 PHP 的后端网站进行通信。我在尝试验证 .NET 应用程序向 PHP 网站提供的令牌时遇到永久签名验证失败(openssl_verify 返回0)。
-
.NET Framework 应用程序使用 Microsoft Authentication Library (MSAL) 针对 Azure Active Directory (AAD) 对用户进行身份验证。该库将令牌作为字符串返回。应用程序将此令牌作为其请求的一部分发送到基于 PHP 的服务器。
var 结果 = await Application.AcquireTokenAsync(scopes).ConfigureAwait(false);
var token = result.AccessToken;
headers.Add("X-Auth-AAD-Token", token);
基于 PHP 的服务器网站接收 .NET 应用程序提供的令牌。然后,它会尝试验证令牌并在从 Azure Active Directory 请求用户数据时使用它。 PHP 网站使用 Networg/oauth2-azure 库,它是通用 thephpleage/oauth2-client 库的提供者,然后使用 firebase/php-jwt 库来处理 JWT 令牌。
PHP 应用程序实例化一个Azure 提供程序并调用
$provider->validateAccessToken($token);
其中$token 是从 .NET 应用程序接收到的字符串。该方法调用
$keys = $this->getJwtVerificationKeys();
(array)JWT::decode($accessToken, $keys, ['RS256'])
其中$keys 是从https://login.windows.net/common/discovery/keys 端点检索到的公钥数组。
JWT::decode 然后将令牌拆分为标头、有效负载和签名,解码它们,选择正确的公钥并验证签名:
public static function decode($jwt, $key, array $allowed_algs = array())
$tks = explode('.', $jwt);
list($headb64, $bodyb64, $cryptob64) = $tks;
$header = static::jsonDecode(static::urlsafeB64Decode($headb64))
$sig = static::urlsafeB64Decode($cryptob64);
$key = $key[$header->kid];
static::verify("$headb64.$bodyb64", $sig, $key, $header->alg);
jsonDecode 调用的地方
$obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
和urlsafeB64Decode 看起来像
public static function urlsafeB64Decode($input)
$remainder = strlen($input) % 4;
if ($remainder) {
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
verify 方法然后尝试通过调用 openssl_verify 来验证签名。
private static function verify($msg, $signature, $key, $alg)
list($function, $algorithm) = static::$supported_algs[$alg]; // list('openssl', 'SHA256')
openssl_verify($msg, $signature, $key, $algorithm);
openssl_verify函数返回0表示签名验证失败(不匹配)。
我做错了什么?如何解决?
编辑:除非令牌是为“我”颁发的,否则我不应该验证签名。由于我检查的令牌的范围是 Graph API,因此应该只有 Graph API 来验证它。在我将请求的令牌范围更改为 Web 应用程序后,签名会按预期进行验证。
【问题讨论】:
标签: php .net oauth-2.0 openssl jwt