Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
958 stars 602 forks source link

Custom AuthenticationScheme #980

Closed christopher-lawrence closed 2 years ago

christopher-lawrence commented 6 years ago

I'm attempting to simply add a custom AuthenticationScheme name when setting up SAML2 within IdentityServer4. When the endpoint is hit upon being redirected from a successful auth from Okta, I get the error below.

Startup and controller below.

IdentityService.exe Error: 0 : 2018-06-15 16:28:34.622 -04:00 [Error] An unhandled exception has occurred: The method or operation is not implemented.
System.NotImplementedException: The method or operation is not implemented.
   at Sustainsys.Saml2.AspNetCore2.Saml2Handler.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.<AuthenticateAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.<AuthenticateAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.<OnAuthorizationAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Hosting.BaseUrlMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at PrecisionLender.Andi.IdentityService.Infrastructure.ErrorHandlingMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()

Startup.cs

            services.AddAuthentication()
                .AddOpenIdConnect("aad-sso", "Azure Active Directory OpenID Connect SSO",
                    options => SetAadSsoOptions(options))
                .AddSaml2("saml-sso", "SAML2.0 SSO", options => ConfigureSaml(options));

.....

        private void ConfigureSaml(Saml2Options options)
        {
            options.SPOptions = new SPOptions
            {
                AuthenticateRequestSigningBehavior = SigningBehavior.Never,
                EntityId = new EntityId("http://localhost/identity/Saml2"),
                ReturnUrl = new Uri("http://localhost/identity/account/LoginSaml?idp=saml"),
            };
            options.IdentityProviders.Add(new IdentityProvider(new EntityId("[OKTA_ENTITYID]"), options.SPOptions)
            {
                LoadMetadata = true,
                MetadataLocation = "https://[DOMAIN].okta.com/app/exk2jffzcXyxpXTr2355/sso/saml/metadata",
                AllowUnsolicitedAuthnResponse = true,
/** Just tried adding these 2 lines after I found the IdSrvr4 example, but no luck */
                Binding = Saml2BindingType.HttpRedirect,
                SingleSignOnServiceUrl = new Uri("https://[DOMAIN].okta.com/app/precisionlenderorg364213_andisaml_1/exk2jffzcXyxpXTr2355/sso/saml"),
            });
            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
            options.SignOutScheme = IdentityServerConstants.SignoutScheme;     

Controller

        [Route("LoginSaml")]
        [Authorize(AuthenticationSchemes = "saml-sso")]
        public IActionResult LoginSamlAsync(string idp)
        {
            return Ok(idp); 
        }
jamescrowley321 commented 6 years ago

I had the same problem when I tried to set the SignInScheme and SignOutScheme to the IdentityServer4 constants. The way I worked around with was to keep the SignInScheme and SignOutScheme different from the IdentityServer4 values, allow the default SAML2 AspNetCore middleware set the user principal, and then manually add the required OpenID claims. I did modify the Sustainsys.SAML2.AspNetCore2.Saml2Handler to accept an injected authentication service that will return claims to be added to the user principal.

AndersAbel commented 6 years ago

Looks like something needs to be adjusted here. @jamescrowley321 can you please provide some more info of what you did and why?