Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
951 stars 601 forks source link

Problem with migration from .NET Framework to .NET Core #1347

Closed const2409 closed 2 years ago

const2409 commented 2 years ago

When moving my web apllication from .NET Framework to .NET Core, I could not make SSO authentication work in a way it has been configured before. My authentication configuration in Startup.cs/ConfigureServices is now roughly the following: var builder = services.AddAuthentication(); builder.AddSaml2(options => { ConfigureSaml2Options(options); }); ConfigureSaml2Options contains necessary configurations for both service and identity providers that has not changed and must be correct. After going to Saml2/SignIn, communication between the application as SP and MS AAD as IdP is successful and SAML response is returned to Saml2/Acs. But then the problem is that the following exception is thrown from Saml2/Acs handler: _An unhandled exception has occurred while executing the request. System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultSignInScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action configureOptions). at Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, String scheme, ClaimsPrincipal principal, AuthenticationProperties properties) at Sustainsys.Saml2.AspNetCore2.CommandResultExtensions.Apply(CommandResult commandResult, HttpContext httpContext, IDataProtector dataProtector, ICookieManager cookieManager, String signInScheme, String signOutScheme, Boolean emitSameSiteNone) at Sustainsys.Saml2.AspNetCore2.Saml2Handler.HandleRequestAsync() at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|60(ExceptionHandlerMiddleware middleware, HttpContext context, Task task) I'm new to .NET Core but I thought that AddSaml2 would add the Saml2 authentication scheme automatically and use it by default, but then just in case I tried to add the scheme to the configuration code: options.SignInScheme = Saml2Defaults.Scheme; This did not help as SignInAsync still fails, just with a different error message: The authentication handler registered for scheme 'Saml2' is 'Saml2Handler' which cannot be used for SignInAsync. Did you forget to call AddAuthentication().AddCookie(\"Cookies\") and SignInAsync(\"Cookies\",...)? So if Saml2 scheme cannot be used for authentication, what else is missing in my SAML (or otherwise application) configuration? Note that the library documentation regrading .NET Core support is at best very minimal, also could not find a solution by looking at the source code and the sample related to it, therefore asking for help. Just FYI: Using Sustainsys.Saml2 and Sustainsys.Saml2.AspNetCore2 version 2.9.0.

AndersAbel commented 2 years ago

You need to AddCookies too and set Cookies as the default scheme. The Saml2 scheme only handles the sign in phase (challenge in Asp.Net Core terms). Then the result is persisted in a session and that is handled by the cookie scheme.

const2409 commented 2 years ago

Thank you! But one more question - how to get the access to the user identity attributes retrieved from the SAML assertion? Previously (with .NET Framework) I used the approach with an API method path defined to the SPOptions.ReturnUrl setting whose handler looked like this: if (!User.Identity.IsAuthenticated) { // redirect to IdP await HttpContext.ChallengeAsync(); return Unauthorized(); } // get user attributes from ClaimsPrincipal.Current?.Identities.First().Claims and do internal authorization based on them ... Now (with .NET Core) this approach does not work since HttpContext.ChallengeAsync does not redirect to IdP. Therefore I'm trying to use Saml2/SignIn directly, which works and redirects to the same URL handler in the end, but IsAuthenticated is false, though I expected it to be true since Saml2/Acs request payload contains the valid SAML assertion. Also ClaimsPrincipal.Current is null, and User.Identity is ClaimsIdentity but contains no Claims, Maybe I missing some setting again?

AndersAbel commented 2 years ago

Once you have the cookie scheme properly setup you can use HttpContext.User to get the principal.

hans9025 commented 6 months ago

@const2409 was you able to fix your issue, because I am also getting the same error

const2409 commented 6 months ago

Yes, this was long ago, but if I remember correctly, I just replaced the code in question with a simple redirection to Saml2/SighIn URL. Plus, of course, adding the cookies scheme as Anders suggested above.

пт, 8 мар. 2024 г. в 22:23, hans9025 @.***>:

@const2409 https://github.com/const2409 was you able to fix your issue, because I am also getting the same error

— Reply to this email directly, view it on GitHub https://github.com/Sustainsys/Saml2/issues/1347#issuecomment-1986366130, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXWKVQRQ5GIZUCGXDUQCOGDYXIM2HAVCNFSM5ULY3OJKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJYGYZTMNRRGMYA . You are receiving this because you were mentioned.Message ID: @.***>