У меня есть код подписи RSA256, работающий в основном приложении aspnet на Mac, просто отлично.
В моих модульных тестах я получаю сообщение об ошибке.
'CspParameters' requires Windows Cryptographic API (CAPI) ONLY when running a unit test
Есть ли что-то aspnet'ish, которое мне нужно смоделировать или предоставить в модульном тесте, чтобы это работало?
public class SessionIdSecureDataFormat : ISessionIdSecureDataFormat
{
private readonly IEnumerable<SecurityKey> _issuerSigningKeys;
private readonly SecurityKey _privateKey;
private readonly string _issuer;
private readonly string _audience;
public SessionIdSecureDataFormat(IEnumerable<SecurityKey> issuerSigningKeys, SecurityKey privateKey,
string issuer, string audience)
{
_issuerSigningKeys = issuerSigningKeys;
_privateKey = privateKey;
_issuer = issuer;
_audience = audience;
}
public string Protect(string data)
{
if (data == null)
{
return null;
}
var securityTokenDescriptor = new SecurityTokenDescriptor
{
SigningCredentials = new SigningCredentials(_privateKey, "RS256"),
Issuer = _issuer,
Audience = _audience,
};
var handler = new JwtSecurityTokenHandler();
var jwt = handler.CreateJwtSecurityToken(securityTokenDescriptor);
jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, data));
return handler.WriteToken(jwt);
}
public string Protect(string data, string purpose)
{
return this.Protect(data);
}
public string Unprotect(string protectedText)
{
if (protectedText == null)
{
return null;
}
var handler = new JwtSecurityTokenHandler();
var validationContext = new TokenValidationParameters
{
RequireExpirationTime = false,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
IssuerSigningKeys = _issuerSigningKeys,
ValidIssuer = _issuer,
ValidAudience = _audience
};
handler.ValidateToken(protectedText, validationContext, out var jwt);
return jwt.Id;
}
public string Unprotect(string protectedText, string purpose)
{
//TODO - It's not clear if we are supposed to check if the purpose matches our declared purpose. No documentation.
return this.Unprotect(protectedText);
}
}
Настройка для модульного теста, где Protect
не удается.
public class SessionJwtDataProtectorTests
{
private readonly byte[] _encodedJwt;
private readonly byte[] _sessionIdOriginal;
private readonly SessionJwtDataProtector _sessionJwtDataProtector;
private readonly Mock<IServiceProvider> _provider = new Mock<IServiceProvider>();
public SessionJwtDataProtectorTests()
{
var sessionIdSecureDataFormat = CreateSessionIdSecureDataFormat();
_provider.Setup(p => p.GetService(typeof(ISessionJwtDataProtector)))
.Returns(new SessionJwtDataProtector(_provider.Object, sessionIdSecureDataFormat));
_sessionJwtDataProtector = new SessionJwtDataProtector(_provider.Object, sessionIdSecureDataFormat);
var sessionId = Guid.NewGuid().ToString();
_sessionIdOriginal = Encoding.UTF8.GetBytes(sessionId);
_encodedJwt = _sessionJwtDataProtector.Protect(_sessionIdOriginal);
}
private static SessionIdSecureDataFormat CreateSessionIdSecureDataFormat()
{
var issuerKeys = new List<RsaSecurityKey>();
foreach (var pemKey in StaticSessionPemKeys.ISSUER_KEYS)
{
RSA rsa = RSAHelper.PublicKeyFromPemString(pemKey.Pem);
issuerKeys.Add(new RsaSecurityKey(rsa) {KeyId = pemKey.KeyId});
}
RSA privateKeyProvider = RSAHelper.PrivateKeyFromPemString(StaticSessionPemKeys.PRIVATE_KEY.Pem);
var privateKey = new RsaSecurityKey(privateKeyProvider)
{KeyId = StaticSessionPemKeys.PRIVATE_KEY.KeyId};
return new SessionIdSecureDataFormat(issuerKeys, privateKey, "ABC", "ABC");
}
}