DotNet Core 2 - Issue with HttpContext.AuthenticateAsync

Issue: The output of HttpContext.AuthenticateAsync is always false

Startup.cs

services.AddAuthentication().AddSaml(AppConstants.Saml2Scheme, AppConstants.Saml2Scheme, options => {
options.SignInScheme = “idsrv.external”;
options.PartnerName = ConfigSettings.PartnerName;
options.ConfigurationID = AppConstants.Default;
});

// Register the SAML configuration.
services.Configure<SamlConfigurations>(config => GetSamlConfiguration(config));

// Add SAML SSO services.
services.AddSaml();


Case 1:

When the value of “AssertionConsumerServiceUrl” matches the default value:
Controller: SAMLController
Action: AssertionConsumerService

“AssertionConsumerServiceUrl”: “<a href=“http://localhost:44339/Saml/AssertionConsumerService” ,”=“”><a href=“http://localhost:44339/Saml/AssertionConsumerService",">http://localhost:44339/Saml/AssertionConsumerService”,

Output: The action method inside controller doesn’t get hit (in debugger) and thus code doesn’t run.
Cookies:
  1. .AspNetCore.Antiforgery
  2. idsrv.external
  3. saml-session

Case 2:

When the value of “AssertionConsumerServiceUrl” is anything but the default value. E.g.

Controller: SAML1Contoller
Action: AssertionConsumerService1

“AssertionConsumerServiceUrl”: “<a href=“http://localhost:44339/Saml1/AssertionConsumerService1” ,”=“”><a href=“http://localhost:44339/Saml1/AssertionConsumerService1",">http://localhost:44339/Saml1/AssertionConsumerService1”,

Output: The debugger hits the code. However, the result of HttpContext.AuthenticateAsync is always false
Cookies: only 1 cookie
  1. saml-session


/// <summary>
/// Comes here after initiating SSO
/// </summary>
/// <returns></returns>
public async Task<ActionResult> AssertionConsumerService1()
{
var ssoResult = await _samlServiceProvider.ReceiveSsoAsync();
var returnUrl = ssoResult.RelayState;

// read external identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception(“External authentication error”);
} // Get token and sign-in }


Please advise.

Name:ComponentSpace.Saml2
Version: 2.0.2

The SAML authentication handler will intercept SAML protocol messages rather than letting them flow through to your application.
In case 1, the authentication handler receives and processes the SAML response. Your controller’s action method will not be invoked. The user should be logged in automatically by the handler.
In case 2, the authentication handler doesn’t process the SAML response as the assertion consumer service URL doesn’t match the default pattern. Therefore, your controller receives the SAML response.
If you haven’t already, please take a look at the MIddlewareExample project which demonstrates using the SAML authentication handler.

[quote]
ComponentSpace - 1/16/2018
The SAML authentication handler will intercept SAML protocol messages rather than letting them flow through to your application.
In case 1, the authentication handler receives and processes the SAML response. Your controller's action method will not be invoked. The user should be logged in automatically by the handler.
In case 2, the authentication handler doesn't process the SAML response as the assertion consumer service URL doesn't match the default pattern. Therefore, your controller receives the SAML response.
If you haven't already, please take a look at the MIddlewareExample project which demonstrates using the SAML authentication handler.
[/quote]

Thank you for your prompt response. Actually we are using the "ExampleServiceProvider" as it matches to our requirement.

In that example, Account controller is initiating the SSO and

await _samlServiceProvider.InitiateSsoAsync(partnerName);

there is a SAML controller and AssertionConsumerService action method which is executing performing some steps after receiving SSO token.

public async Task AssertionConsumerService()
{
// Receive and process the SAML assertion contained in the SAML response.
// The SAML response is received either as part of IdP-initiated or SP-initiated SSO.
var ssoResult = await _samlServiceProvider.ReceiveSsoAsync();

// Automatically provision the user.
// If the user doesn't exist locally then create the user.
// Automatic provisioning is an optional step.
var user = await _userManager.FindByNameAsync(ssoResult.UserID);
}

But in our case, it is not getting executed

The requirement is write some custom code after ReceiveSsoAsync.

Please refer to the ExampleServiceProvider’s Startup.cs.
You don’t want to call services.AddAuthentication().AddSaml as this is hooking up the SAML authentication handler which will intercept the SAML response.
That explains why your AssertionConsumerService isn’t being called.