我的 C# 代码运行得很好。我需要在下面编写 c# 逻辑 int apim 策略。 Azure APIM 不支持某些命名空间。我的要求是解码令牌并通过读取证书公钥来检查令牌有效性和签名。
下面的C#逻辑
using Microsoft.AspNetCore.Authentication;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace TokenValidation
{
internal class Program
{
static void Main(string[] args)
{
var token = "eyJBdXRoZW50aWNhdGlvblR5cGUiOiJCZWFyZXIiLCJOYW1lQ2xhaW1UeXBlIjoiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8bGFpbXMvbmFtZSIsIlJvbGVDbGFpbVR5cGUiOiJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93wiT3JpZ2luYWxJc3N1ZXIiOiJMT0NBTCBBVVRIT1JJVFkifV0sIlByb3BlcnRpZXMiOnsiRGljdGlvbmFyeSI6eyIuaXNzdWVkIjoiRnJpLCAyNiBKdWwgMjAyNCAxMDo1ODo1OSBHTVQiLCIuZXhwaXJlcyI6IkZyaSwgMjYgSnVsIDIwMjQgMTE6MTg6NTkgR01UIn19fQ<---->LsQakfrTMrKd-0iQAsEzs4snSGo7bqmSjjJiUXAomhAMFyJcHRI3yYFgMl_f9CCviV_T7d-VkMFN1g3V40qsqkjtneumkRJfg-T6JMg1RtehgaSBsHr5qncNeVqq6HbSNbW_A_v5NWD3dv4pK9AytetxNv4sm64BVebiag2YUMMWBhpeus-brF6j_-Ck6nIA0hCphGBj3DLNmt7iNlkkSg";
var Separator = "<---->";
X509Certificate2 _certificate;
if (string.IsNullOrEmpty(token))
{
throw new KeyNotFoundException("Token is empty");
}
var dataAndSign = token.Split(new[] { Separator }, StringSplitOptions.None);
if (dataAndSign.Length != 2)
{
throw new InvalidOperationException("Token has invalid format");
}
var originalData = dataAndSign[0];
var signature = dataAndSign[1];
var originalDataSanitized = originalData
.Replace('_', '/').Replace('-', '+');
switch (originalData.Length % 4)
{
case 2: originalDataSanitized += "=="; break;
case 3: originalDataSanitized += "="; break;
}
byte[] bytesToVerify = Convert.FromBase64String(originalDataSanitized);
var signatureSanitized = signature
.Replace('_', '/').Replace('-', '+');
switch (signature.Length % 4)
{
case 2: signatureSanitized += "=="; break;
case 3: signatureSanitized += "="; break;
}
byte[] signedBytes = Convert.FromBase64String(signatureSanitized);
var certResourcePath = "TokenValidation.Certificate.OAuthAuthorization.cer";
using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(certResourcePath))
using (var reader = new BinaryReader(resource))
{
_certificate = new X509Certificate2(reader.ReadBytes((int)resource.Length));
}
var rsa = _certificate.GetRSAPublicKey();
var rsaPublicKey = rsa.ToXmlString(false);
var isValid = rsa.VerifyData(bytesToVerify, signedBytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
}
}
`
以下是我的 APIM 政策。我已经写了这个直到解码令牌。就像上面的 C# 代码一样,我应该读取证书、获取公钥并验证令牌。
<policies>
<inbound>
<set-variable name="api.NamedValue.corrigoKey" value="{{corrigo-public-key}}" />
<set-variable name="api.isCorrigoTokenVerifed" value="@{
var corrigoToken = context.Request.Headers.GetValueOrDefault("Authorization","scheme param").Split(' ').Last();
var Separator = "<---->";
if (string.IsNullOrEmpty(corrigoToken))
{
return "false";
}
var dataAndSign = corrigoToken.Split(new[] { Separator }, StringSplitOptions.None);
if (dataAndSign.Length != 2)
{
return "false";
}
var originalData = dataAndSign[0];
var signature = dataAndSign[1];
var originalDataSanitized = originalData
.Replace('_', '/').Replace('-', '+');
switch (originalData.Length % 4)
{
case 2: originalDataSanitized += "=="; break;
case 3: originalDataSanitized += "="; break;
}
byte[] bytesToVerify = Convert.FromBase64String(originalDataSanitized);
var signatureSanitized = signature
.Replace('_', '/').Replace('-', '+');
switch (signature.Length % 4)
{
case 2: signatureSanitized += "=="; break;
case 3: signatureSanitized += "="; break;
}
byte[] signedBytes = Convert.FromBase64String(signatureSanitized);
var token = (String)context.Variables["api.NamedValue.corrigoKey"];
// Certifcate verfication logic is not supported as few namespaces not supported by Azure APIM.
return "true";
}" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
</policies>
您可以使用证书作为您的密钥
第1步:上传证书
上传证书:
下一步 - 使用如下策略
<policies>
<inbound>
<base />
<validate-jwt header-name="Authorization" require-scheme="Bearer" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
<issuer-signing-keys>
<key certificate-id="my-rsa-cert" /> <!-- signing key specified by certificate ID -->
</issuer-signing-keys>
<audiences>
<audience>https://api.yourdomain.com</audience> <!-- expected audience of the token -->
</audiences>
<issuers>
<issuer>http://contoso.com/</issuer> <!-- expected issuer of the token -->
</issuers>
</validate-jwt>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
请参阅 https://learn.microsoft.com/en-us/azure/api-management/validate-jwt-policy#examples