英文:
What is missing from my test so I can unit test this code?
问题
I am trying to write unit tests to cover my ExternalAuthenticationService
class; I'm trying to test my RedirectToLogin
method and ensure that the RelayStateQuery
is populated like it should be:
public IActionResult RedirectToLogin(LoginInfo loginInfo)
{
var binding = new Saml2RedirectBinding();
var dict = new Dictionary<string, string>()
{
{ "SomeKey", info.SomeStringIWantToRoundTrip }
};
binding.SetRelayStateQuery(dict);
return binding.Bind(new Saml2AuthnRequest(config)).ToActionResult();
}
So I've tried to setup my test like this:
public class ExternalAuthenticationServiceTests
{
private IExternalAuthenticationService service;
public ExternalAuthenticationServiceTests()
{
var testCertificate = GenerateCertificate("Test Certificate");
var config = new Saml2Configuration
{
CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None,
Issuer = "http://wonderwoman.com",
RevocationMode = X509RevocationMode.NoCheck,
SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
SigningCertificate = testCertificate
};
service = new ExternalAuthenticationService(config);
}
[Fact]
public void RedirectToLogin_sets_tenantName_in_RelayStateQuery()
{
LoginInfo loginInfo = new() {
SomeStringIWantToRoundTrip = "user location or whatever"
};
var result = service.RedirectToLogin(loginInfo);
}
private X509Certificate2 GenerateCertificate(string subjectName)
{
// Generate a new RSA key pair
using var rsa = RSA.Create(2048);
// Create a certificate request
CertificateRequest request = new($"CN={subjectName}", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
// Set certificate validity dates
DateTimeOffset now = DateTimeOffset.UtcNow;
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, false));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(request.PublicKey, false));
// Create a self-signed certificate
X509Certificate2 certificate = request.CreateSelfSigned(now, now.AddYears(1));
// Return the generated certificate
return certificate;
}
}
}
…but this doesn't work, even before assertions are added. The RedirectToLogin
method throws an exception:
Message:
System.NullReferenceException : Object reference not set to an instance of an object.Stack Trace:
Saml2RedirectBinding.BindInternal(Saml2Request saml2RequestResponse, String messageName) Saml2Binding`1.Bind(Saml2Request saml2Request) ExternalAuthenticationService.RedirectToLogin(LoginInfo loginInfo) line 39
I'm assuming the Saml2Configuration
class needs something I'm not providing in the properties, but I can't tell what. What am I missing?
英文:
I am trying to write unit tests to cover my ExternalAuthenticationService
class; I'm trying to test my RedirectToLogin
method and ensure that the RelayStateQuery
is populated like it should be:
public IActionResult RedirectToLogin(LoginInfo loginInfo)
{
var binding = new Saml2RedirectBinding();
var dict = new Dictionary<string, string>
{
{ "SomeKey", info.SomeStringIWantToRoundTrip }
};
binding.SetRelayStateQuery(dict);
return binding.Bind(new Saml2AuthnRequest(config)).ToActionResult();
}
So I've tried to setup my test like this:
public class ExternalAuthenticationServiceTests
{
private IExternalAuthenticationService service;
public ExternalAuthenticationServiceTests()
{
var testCertificate = GenerateCertificate("Test Certificate");
var config = new Saml2Configuration
{
CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None,
Issuer = "http://wonderwoman.com",
RevocationMode = X509RevocationMode.NoCheck,
SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
SigningCertificate = testCertificate
};
service = new ExternalAuthenticationService(config);
}
[Fact]
public void RedirectToLogin_sets_tenantName_in_RelayStateQuery()
{
LoginInfo loginInfo = new() {
SomeStringIWantToRoundTrip = "user location or whatever"
};
var result = service.RedirectToLogin(loginInfo);
}
private X509Certificate2 GenerateCertificate(string subjectName)
{
// Generate a new RSA key pair
using var rsa = RSA.Create(2048);
// Create a certificate request
CertificateRequest request = new($"CN={subjectName}", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
// Set certificate validity dates
DateTimeOffset now = DateTimeOffset.UtcNow;
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, false));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(request.PublicKey, false));
// Create a self-signed certificate
X509Certificate2 certificate = request.CreateSelfSigned(now, now.AddYears(1));
// Return the generated certificate
return certificate;
}
}
}
…but this doesn't work, even before assertions are added. The RedirectToLogin
method throws an exception:
> Message:
> System.NullReferenceException : Object reference not set to an instance of an object.
>
> Stack Trace:
>
> Saml2RedirectBinding.BindInternal(Saml2Request saml2RequestResponse, String messageName)
> Saml2Binding`1.Bind(Saml2Request saml2Request)
> ExternalAuthenticationService.RedirectToLogin(LoginInfo loginInfo) line 39
I'm assuming the Saml2Configuration
class needs something I'm not providing in the properties, but I can't tell what. What am I missing?
答案1
得分: 1
I was missing a SingleSignOnDestination
:
var config = new Saml2Configuration
{
CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None,
Issuer = "http://wonderwoman.com",
RevocationMode = X509RevocationMode.NoCheck,
SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
SigningCertificate = testCertificate,
SingleSignOnDestination = new Uri("http://test.com"), // required - duh
};
英文:
I was missing a SingleSignOnDestination
:
var config = new Saml2Configuration
{
CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None,
Issuer = "http://wonderwoman.com",
RevocationMode = X509RevocationMode.NoCheck,
SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
SigningCertificate = testCertificate,
SingleSignOnDestination = new Uri("http://test.com"), // required - duh
};
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论