IHttpPostBinding.SendMessageAsync - unable to write response body before calling

I am trying to write a simple branded ‘please wait’ page to response body to avoid the white screen shown when calling IHttpPostBinding.SendMessageAsync but am getting errors calling HttpContext.Response.Body.WriteAsync before sending the SAML message. Ideally I would like to have the ‘please wait’ page rendered as early as possible and before SendMessageAsync to avoid seeing the white screen.

I was not on the project at the time but have been told that this used to work in .NET Framework and has only become a problem after upgrade to .NET Core 8. It does seem to work as expected when running a site locally in Kestrel server but the error occurs after publishing and running the site in IIS.

The code to write to response body:
byte[] bytes = Encoding.ASCII.GetBytes(body.ToString()); await _httpContextAccessor.HttpContext.Response.Body.WriteAsync(bytes);

The error:
ComponentSpace.Saml2.Exceptions.SamlBindingException: 'Failed to send the SAML message over HTTP-Post.'
InvalidOperationException: The response headers cannot be modified because the response has already started.

I assume you’re not calling IHttpPostBinding.SendMessageAsync directly as this isn’t recommended for most use cases.

The following code demonstrates specifying a “please wait” message to be displayed during the HTTP Post of the SAML message to the partner provider.

using ComponentSpace.Saml2.Bindings.Post;


builder.Services.Configure<HttpPostFormOptions>(options =>
{
    options.DisplayMessage = "<p>Please wait.</>";
});

builder.Services.AddSaml(builder.Configuration.GetSection("SAML"));

The DisplayMessage property specifies the HTML to be included with the HTML form returned to the browser.

This results in the following HTML.

<html>
  <body>
    <noscript>
      <p>
        Since your browser doesn't support JavaScript, you must press the Continue button to proceed.
      </p>
    </noscript>
    <p>Please wait.</>
    <form id="samlform" action="https://localhost:44360/SAML/AssertionConsumerService" method="post" target="_self">
      <div>
        <input type="hidden" name="SAMLResponse" value="..."/>
      </div>
      <noscript>
        <div>
          <input type="submit" value="Continue"/>
        </div>
      </noscript>
    </form>
</html>

Hi thank you for this information. I was able to achieve the affect I was looking for by using DisplayMessage and also FormTemplate to format the page with some CSS and images.

Can I ask what is meant by not calling IHttpPostBinding.SendMessageAsync directly? That is being called directly in our code but I’m not sure what the correct way of doing this would be. I couldn’t find anything in the SAML for ASP.NET Core Developer Guide document about using this or how it should be done.

The IHttpPostBinding interface is part of the low-level API and typically isn’t accessed directly. Most applications will perform SAML operations through the ISamlServiceProvider or ISamlIdentityProvider interface.

The ExampleServiceProvider and ExampleIdentityProvider projects included with the product demonstrate calling these interfaces.

For example, ISamlIdentityProvider.SendSsoAsync creates and sends a SAML response to a partner service provider. If the default HTTP Post binding is being used, SendSsoAsync will call the IHttpPostBinding interface.

The Developer Guide documents the ISamlServiceProvider and ISamlIdentityProvider interfaces.

The Examples Guide walks you through the ExampleServiceProvider and ExampleIdentityProvider projects.

If you’re calling IHttpPostBinding.SendMessageAsync, it means your application is responsible for constructing, securing and encoding the SAML message being sent. It also means you have to handle any state information required in support of the SAML protocol. It’s much easier to let the ISamlServiceProvider and ISamlIdentityProvider interfaces handle this.

Hi thank you for that, I am going to review the implementation and see if there are any improvements that can be made based on the Examples Guide and will let you know if I have any questions about that.

Sounds good.

Hi do you know where I can get copies of the sample projects ExampleServiceProvider and ExampleIdentityProvider? I’m very new to this project and having trouble figuring out how I would replicate this using ISamlServiceProvider and ISamlIdentityProvider.

These example projects are included with both the licensed product as well as the free evaluation.

You’ll find a download link for the trial version at: