HTTPS Redirect Issue with InitiateSsoAsync

Our code is initially setup as a Local SP

And on the fly we add a Local IDP and add Partner SPs

When We InitiateSSOAsync it always posts the assertion using an HTTP url, even though the URL we provided is HTTPS?

The condifigured assertion url for SSO login is <a href=“https://test2.system.com/Account/AssertionConsumerService” ,“=”" title=“https://test2.system.com/Account/AssertionConsumerService” target=“_blank” style=“text-decoration: underline; color: rgb(49, 97, 185); font-family: Courier, "Courier New"; font-size: 13.3333px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;”>https://test2.system.com/Account/AssertionConsumerService

But the code redirect always to <a href=“https://test2.system.com/Account/AssertionConsumerService” ,“=”" title=“https://test2.system.com/Account/AssertionConsumerService” target=“_blank” style=“text-decoration: underline; color: rgb(49, 97, 185); font-family: Courier, "Courier New"; font-size: 13.3333px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;”>http://test2.system.com/Account/AssertionConsumerService

2022-03-18 12:28:06.447 -04:00 [DBG] The SAML message has been sent over HTTP-Post.
2022-03-18 12:28:06.447 -04:00 [DBG] The SAML response was successfully sent.

Any Idea how to force HTTPS Post for assertions?

THis was essentially the same code from old SAML version used in .net 4.7, just tweaked a bit to work with Core .Net


IDictionary<string, string> attributes = new Dictionary<string, string>();

var samlConfiguration = _samlConfigurations.Configurations.First();

samlConfiguration.LocalIdentityProviderConfiguration = new LocalIdentityProviderConfiguration
{
Name = “idp.system.com:saml2.0”,
LocalCertificates = new List
{
new Certificate
{
FileName = “cert.pfx”, Password = “password”
}
}
};

if (samlConfiguration.PartnerServiceProviderConfigurations == null)
samlConfiguration.PartnerServiceProviderConfigurations =
new List();
else
samlConfiguration.PartnerServiceProviderConfigurations.Clear();

samlConfiguration.PartnerServiceProviderConfigurations.Add(
new PartnerServiceProviderConfiguration
{
Name = $“test2.system.com:saml2.0”,
WantAuthnRequestSigned = false,
SignSamlResponse = true,
SignAssertion = false,
EncryptAssertion = false,
AssertionConsumerServiceUrl =
“<a href=“https://test2.system.com/Account/AssertionConsumerService” ,”=“”><a href=“https://test2.system.com/Account/AssertionConsumerService” ,“=”"><a href=“https://test2.system.com/Account/AssertionConsumerService",">https://test2.system.com/Account/AssertionConsumerService”,
PartnerCertificates = new List
{
new Certificate
{
FileName = “cert.cer”
}
}
});

_samlIdentityProvider.InitiateSsoAsync(“test2.system.com:saml2.0”,
test2@system.com”);


Further investigation:

Looking at network console, the POST seems to have gone to HTTPS url, but received a 400 bad request.

But I dont see any errors on both the sending or receiving end. How to debug this 400 error?

You should determine who is sending the 400 HTTP response. Presumably it’s the service provider unless there’s some intermediate network node.

The service provider’s log might have more information regarding why a 400 is being returned.

Also, the recommendation is to set the SAML configuration once at application start-up or to implement the ISamlConfigurationResolver interface if the configuration is dynamic. It’s not recommended setting the configuration on each SSO request. For more information, please refer to our Configuration Guide. This is unrelated to the error you’re seeing.

I dont think the request is even reaching the SP on the other side, I dont see any logs at all on the other side

The weird part is when trying to login using SSO from the new system to out old SAML login in .net 4.7 version it all works.

But when trying to login between 2 systems, it fails and when debugged locally to our qa system, I received this error

2022-03-21 08:09:15.788 -04:00 [ERR] Initiation of SSO to the partner service provider gen.razorplan.com:saml2.0 has failed.
ComponentSpace.Saml2.Exceptions.SamlBindingException: Failed to send the SAML message over HTTP-Post.
—> System.ObjectDisposedException: Cannot write to the response body, the response has completed.
Object name: ‘HttpResponseStream’.
at Microsoft.AspNetCore.Server.IIS.Core.HttpResponseStream.ValidateState(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.IIS.Core.HttpResponseStream.FlushAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.IIS.Core.WrappingStream.FlushAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Watch.BrowserRefresh.ResponseStreamWrapper.FlushAsync(CancellationToken cancellationToken)
at System.IO.Stream.FlushAsync()
at Microsoft.WebTools.BrowserLink.Net.ScriptInjectionFilterStream.FlushAsync(CancellationToken cancellationToken)
at System.IO.StreamWriter.FlushAsyncInternal(StreamWriter _this, Boolean flushStream, Boolean flushEncoder, Char[] charBuffer, Int32 charPos, Boolean haveWrittenPreamble, Encoding encoding, Encoder encoder, Byte[] byteBuffer, Stream stream, CancellationToken cancellationToken)
at ComponentSpace.Saml2.Bindings.Post.HttpPostBinding.SendMessageAsync(String url, String message, Boolean isResponse, String relayState)
— End of inner exception stack trace —
at ComponentSpace.Saml2.Bindings.Post.HttpPostBinding.SendMessageAsync(String url, String message, Boolean isResponse, String relayState)
at ComponentSpace.Saml2.SamlProvider.SendMessageAsync(String destinationUrl, String binding, XmlElement messageElement, Boolean isResponse, String relayState, AsymmetricAlgorithm key, String signatureAlgorithm)
at ComponentSpace.Saml2.SamlIdentityProvider.SendSamlResponseAsync(XmlElement samlResponseElement, String relayState, String assertionConsumerServiceUrl, String assertionConsumerServiceBinding)
at ComponentSpace.Saml2.SamlIdentityProvider.InitiateSsoAsync(String partnerName, String userID, IList attributes, String relayState, String authnContext)

The ObjectDisposedException is now fixed by using .Wait()

_samlIdentityProvider.InitiateSsoAsync(“test2.system.com:saml2.0”,
test2@system.com”).Wait();

The 400 Bad Request is still not fixed. We’ve confirmed that the Assertion is Posted by IDP but never received by SP.

Some config in IIS is blocking the Post with a 400 Bad Request.

Calling Wait() shouldn’t be necessary and isn’t recommended. It would still be worthwhile running the ExampleIdentityProvider and comparing its code with your application code to pinpoint the issue causing the exception.