5

I'm trying a simple implementation in my Asp net Core application of Saml2 to integrate with an Ad FS server. I can't figure why I am getting this error. I downloaded the samples from the gitHub and tried to adapt it in my application.

NotImplementedException: The method or operation is not implemented.
Sustainsys.Saml2.AspNetCore2.Saml2Handler.AuthenticateAsync()

Here's my implementation, my application is running on Asp Net Core

On StartUp

                services
                    .AddAuthentication(sharedOptions =>
                    {
                        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                        sharedOptions.DefaultChallengeScheme = Saml2Defaults.Scheme;
                    })
                    .AddSaml2(options =>
                    {
                        options.SPOptions.EntityId = new EntityId("http://myAdfsServer.myDomain.com/adfs/services/trust");
                        options.SPOptions.ReturnUrl = new Uri("https://localhost:5000");
                        options.IdentityProviders.Add(
                            new IdentityProvider(new EntityId("http://myAdfsServer.myDomain.com/adfs/services/trust"), options.SPOptions)
                            {
                               LoadMetadata = true,
                               MetadataLocation = "https://myAdfsServer.myDomain.com/FederationMetadata/2007-06/FederationMetadata.xml"
                                //MetadataLocation = "FederationMetadata.xml"
                            });

                        //options.SPOptions.ServiceCertificates.Add(new X509Certificate2(certificate.ToString()));
                    })
                    .AddCookie();

On my Controller trying something similar to Sustainsys SAML2 Sample for ASP.NET Core WebAPI without Identity


    [Authorize(AuthenticationSchemes = Saml2Defaults.Scheme)]
    public class AuthenticationController : Controller
    {
        public AuthenticationController()
        {

        }

        [AllowAnonymous]
        public async Task LoginAdfs()
        {
            string redirectUri = string.Concat("https://localhost:5000", "/verifyAdfs");
            try
            {
                new ChallengeResult(
                    Saml2Defaults.Scheme,
                    new AuthenticationProperties
                    {
                        RedirectUri = Url.Action(nameof(LoginCallback), new { redirectUri })
                    });
            }catch(Exception e)
            {

            }
        }

        [AllowAnonymous]
        public async Task<IActionResult> LoginCallback(string returnUrl)
        {
            var authenticateResult = await HttpContext.AuthenticateAsync(Saml2Defaults.Scheme);

            //_log.Information("Authenticate result: {@authenticateResult}", authenticateResult);

            // I get false here and no information on claims etc.
            if (!authenticateResult.Succeeded)
            {
                return Unauthorized();
            }

            var claimsIdentity = new ClaimsIdentity("Email");
            claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));

           // _log.Information("Logged in user with following claims: {@Claims}", authenticateResult.Principal.Claims);

            await HttpContext.SignInAsync("Email", new ClaimsPrincipal(claimsIdentity));

            return LocalRedirect(returnUrl);
        }
}


note: I've got a client that won't expose his MetaData in a URL, so I'll need to adapt it and set manually the metadata parameters

I'm stuck in this error, I does not even hit my method LoginAdfs.

Arturio
  • 418
  • 1
  • 7
  • 25

1 Answers1

2

The Saml2 handler cannot be used as an authencation scheme, it is a challenge scheme.

I guess that the LoginAdfs() method works fine, but that it's the LoginCallback that fails. The reason should be the call to HttpContext.AuthenticationAsync(Saml2Defaults.Scheme).

You should instead authenticate with the cookie scheme - because that's what keeps the session. Internally when the challenge is completed, the Saml2 handler will use the DefaultSignInScheme to preserve the result in a session (through a cookie, as that's the default sign in scheme).

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
  • I'm having a hard time getting it to work. Previously I implemented the WS-Protocol, and it was kind of simple. I didn't have to use this "LoginCallBack" method. It is not even hitting the Ad FS server. Any idea what could be wrong? Also, the samples provided in GitHub didn't help me. Besides the startup config, would there be another implementation I might be missing? – Arturio Nov 12 '19 at 21:09
  • 1
    Can you explain this with some sample code? I don't understand how I can authenticate with the cookie scheme... It seems that the Saml2Handler creates a custom cookie "Saml2.RelayState". – Pieter van der Heijden May 16 '20 at 06:03
  • @PietervanderHeijden Did you figure it out? I'm trying to achieve the same thing. – Justin Apr 12 '21 at 17:53
  • 1
    @Justin No, I couldn't get it to work... Therefore, I switched to ComponentSpace. This solution works very well, and has (a lot of) examples. – Pieter van der Heijden Apr 13 '21 at 15:31
  • 1
    @PietervanderHeijden Thanks for the tip, I switched from SustainSys to ComponentSpace and it's working beautifully now. I burned a week on SustainSys and never got the external cookie to be set in the challenge callback, whereas it took 4 hours to wire up ComponentSpace. Unfortunately it doesn't use the ASP.NET Core / Identity Server Authentication scheme external cookie approach, so isn't consistent with our OIDC and OAuth2 SSO flows. Instead, it just handles the validating and parsing of the request form's SAMLResponse internally. Oh well, it works, moving on... – Justin Apr 17 '21 at 12:31
  • @Justin I may not be following exactly what you mean but we do include a SAML authentication handler which ties in with the Microsoft authentication handler middleware approach. This is an alternative to calling our SAML API. The MiddlewareServiceProvider example project demonstrates its use. You're always welcome to email us for further details. – ComponentSpace Apr 17 '21 at 22:15