How to override Sustainsys.Saml2 ACS URL to /api/Saml2/Acs instead of default /Saml2/Acs in .NET Core?

Niket Kumar Singh 835 Reputation points
2025-04-04T11:57:02.36+00:00

Hi all,

I'm integrating SAML-based SSO using Azure AD (Enterprise App) with a .NET 6 Web API using Sustainsys.Saml2 (via code-based configuration).

My Goal:

I want to use the Assertion Consumer Service (ACS) endpoint at: https://localhost:5001/api/Saml2/Acs (instead of the default /Saml2/Acs route hardcoded by Sustainsys).


🔧 My Setup:

Azure AD SSO (Enterprise App):

  • Identifier (Entity ID): https://xxxxxxxxxxxxxxxxx/a/webapi/api/externallogin/saml/identifier
  • Reply URL (ACS): https://localhost:5001/api/Saml2/Acs (only this is configured)

ASP.NET Core Controller:

[Route("api/Saml2")]
[ApiController]
public class Saml2Controller : ControllerBase
{
    [HttpGet("Microsoft_Login")]
    [AllowAnonymous]
    public IActionResult MicrosoftLogin() =>
        Challenge(new AuthenticationProperties(), "Saml2");

    [HttpPost("Acs")]
    [AllowAnonymous]
    public IActionResult Acs() =>
        Ok("SAML response processed.");
}

Startup.cs Configuration:

services.AddAuthentication()
    .AddSaml2(options =>
    {
        options.SPOptions.EntityId = new EntityId("https://xxxxxxxxxxxxxxx/a/webapi/api/externallogin/saml/identifier");
        options.SPOptions.PublicOrigin = new Uri("https://localhost:5001");
        options.SPOptions.ModulePath = "/api/Saml2";  // tried this
        options.IdentityProviders.Add(new IdentityProvider(
            new EntityId("https://sts.windows.net/<tenant-id>/"), options.SPOptions)
        {
            MetadataLocation = "https://login.microsoftonline.com/<tenant-id>/federationmetadata/2007-06/federationmetadata.xml",
            LoadMetadata = true
        });
    });

Even though I’ve:

Added the correct [Route("api/Saml2")] on the controller

Configured Azure AD reply URL as /api/Saml2/Acs

Tried setting SPOptions.ModulePath = "/api/Saml2"

Still, when initiating login and tracing the SAML AuthnRequest in network tools:

The AssertionConsumerServiceURL in the request sent to Azure is: https://localhost:5001/Saml2/Acs (❌)

❌ This causes the following error from Azure AD:

AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application.

Browser address bar correctly redirects to /api/Saml2/Acs, but the actual SAML response POST still goes to /Saml2/Acs

I’ve read GitHub Issue #1031 and confirmed:

  • AssertionConsumerServiceUrl cannot be overridden in Sustainsys v2.x
  • Only SPOptions.ModulePath can change the base path (/Saml2)
  • The hardcoded /Acs path cannot be changed in v2.x
  • Some users had to fork the repo to override AuthServicesUrls.cs
  1. Is there any supported way in Sustainsys.Saml2 v2.x to fully override the ACS URL (e.g., to /api/Saml2/Acs)?
  2. Is there a workaround (besides forking the repo) to force the correct AssertionConsumerServiceUrl in the SAML request?
  3. Would switching to Sustainsys v3 or a different lib (e.g., ITfoxtec) help with this scenario?

Any help or guidance from the community would be highly appreciated!

Developer technologies | .NET | F#
Developer technologies | .NET | F#
A strongly typed, multi-paradigm programming language developed by the F# Software Foundation, Microsoft, and open contributors.
{count} vote

Answer accepted by question author
  1. Danny Nguyen (WICLOUD CORPORATION) 5,405 Reputation points Microsoft External Staff Moderator
    2025-09-22T09:37:01.4633333+00:00

    Hi @Niket Kumar Singh !

    I took a look at this problem and here is what I've found.

    In short, if you're using Sustainsys.Saml2 v3, you can confidently use custom ACS endpoints by setting SPOptions.ModulePath. Make sure your IdP is configured with the exact URL and your app is listening on the correct path. I've tested this solution, and it worked fine.


    Problem:
    Previously, in v1 and v2 of Sustainsys.Saml2, the ACS path was hardcoded as /Saml2/Acs, making it difficult to change the endpoint to match custom requirements (such as /api/saml/acs). This was a limitation for many users integrating with Azure AD (Microsoft Entra) or other IdPs.


    Update:
    As confirmed in GitHub Issue #1434, v3 of Sustainsys.Saml2 introduces more flexibility, allowing you to change the ACS endpoint by setting the SPOptions.ModulePath property. This means you can now use custom paths like /api/saml/acs for your ACS endpoint.


    After configuring SPOptions.ModulePath to a custom value in my own test project, and updating the Reply URL in Microsoft Entra to match, the authentication flow worked (my version is 2.11.0) :

    • The SAML response POSTed to my custom ACS endpoint (/api/saml/acs)
    • The application processed the response and authenticated the user as expected
    • The network trace showed a successful POST and redirect (HTTP 303) at the endpoint

    If you need any help, please keep me updated on this.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.