2 回答

TA貢獻1784條經(jīng)驗 獲得超8個贊
據(jù)我所知,驗證 WOPI 證明密鑰的實施起來相當復雜,而從文檔中的解釋中提取編程邏輯則具有挑戰(zhàn)性。不幸的是,我不是 PHP 開發(fā)人員。不過,我想分享我的生產 C# 代碼,以防有幫助。
private async Task<bool> ValidateWopiProof(HttpContext context)
{
? ? // Make sure the request has the correct headers
? ? if (!context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF) ||
? ? ? ? !context.Request.Headers.ContainsKey(WopiRequestHeader.TIME_STAMP))
? ? ? ? return false;
? ? // TimestampOlderThan20Min
? ? var timeStamp = long.Parse(context.Request.Headers[WopiRequestHeader.TIME_STAMP].ToString());
? ? var timeStampDateTime = new DateTime(timeStamp, DateTimeKind.Utc);
? ? if ((DateTime.UtcNow - timeStampDateTime).TotalMinutes > 20)
? ? ? ? return false;
? ? // Set the requested proof values
? ? var requestProof = context.Request.Headers[WopiRequestHeader.PROOF];
? ? var requestProofOld = String.Empty;
? ? if (context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF_OLD))
? ? ? ? requestProofOld = context.Request.Headers[WopiRequestHeader.PROOF_OLD];
? ? // Get the WOPI proof info from Wopi discovery
? ? var wopiProofPublicKey = await _wopiDiscovery.GetWopiProof();
? ? // Encode the values into bytes
? ? var accessTokenBytes = Encoding.UTF8.GetBytes(context.Request.Query["access_token"].ToString());
? ? var hostUrl = GetAbsolouteUrl(context);
? ? var hostUrlBytes = Encoding.UTF8.GetBytes(hostUrl.ToUpperInvariant());
? ? var timeStampBytes = BitConverter.GetBytes(Convert.ToInt64(context.Request.Headers[WopiRequestHeader.TIME_STAMP])).Reverse().ToArray();
? ? // Build expected proof
? ? List<byte> expected = new List<byte>(
? ? ? ? 4 + accessTokenBytes.Length +
? ? ? ? 4 + hostUrlBytes.Length +
? ? ? ? 4 + timeStampBytes.Length);
? ? // Add the values to the expected variable
? ? expected.AddRange(BitConverter.GetBytes(accessTokenBytes.Length).Reverse().ToArray());
? ? expected.AddRange(accessTokenBytes);
? ? expected.AddRange(BitConverter.GetBytes(hostUrlBytes.Length).Reverse().ToArray());
? ? expected.AddRange(hostUrlBytes);
? ? expected.AddRange(BitConverter.GetBytes(timeStampBytes.Length).Reverse().ToArray());
? ? expected.AddRange(timeStampBytes);
? ? byte[] expectedBytes = expected.ToArray();
? ? return (VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.Value) ||
? ? ? ? VerifyProofKeys(expectedBytes, requestProofOld, wopiProofPublicKey.Value) ||
? ? ? ? VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.OldValue));
}
private string GetAbsolouteUrl(HttpContext context)
{
? ? var url = $"{_wopiUrlService.ApiAddress.TrimEnd('/')}{context.Request.Path}{context.Request.QueryString}";
? ? return url.Replace(":44300", "").Replace(":443", "");
}
private bool VerifyProofKeys(byte[] expectedProof, string proofFromRequest, string discoPublicKey)
{
? ? using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider())
? ? {
? ? ? ? try
? ? ? ? {
? ? ? ? ? ? rsaProvider.ImportCspBlob(Convert.FromBase64String(discoPublicKey));
? ? ? ? ? ? return rsaProvider.VerifyData(expectedProof, "SHA256", Convert.FromBase64String(proofFromRequest));
? ? ? ? }
? ? ? ? catch (FormatException)
? ? ? ? {
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? catch (CryptographicException)
? ? ? ? {
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
}
此實現(xiàn)遵循文檔規(guī)范。至于方法_wopiDiscovery.GetWopiProof()
,我只是從Wopi Discoveryproof-key
得到了部分。

TA貢獻1820條經(jīng)驗 獲得超9個贊
您可以在這個包中找到 PHP 中的 WOPI 證明驗證器: https: //github.com/Champs-Libres/wopi-lib/
該軟件包是在 PHP 應用程序中集成 WOPI 協(xié)議的幫助程序。
它包含您可以開箱即用的 WOPI 證明驗證器服務。
- 2 回答
- 0 關注
- 401 瀏覽
添加回答
舉報