Closed taigon1984 closed 2 years ago
Here is how I setup the cookie and saml2 auth on the API side,
services.AddAuthentication("Identity.Application") .AddCookie("Identity.Application", opts => { opts.Cookie.SecurePolicy = CookieSecurePolicy.Always; opts.Cookie.SameSite = SameSiteMode.None; opts.Cookie.HttpOnly = false; opts.Cookie.Path = "/"; opts.ExpireTimeSpan = userExpiry; opts.SlidingExpiration = true; opts.LoginPath = "/account/signin"; opts.LogoutPath = "/account/signout"; opts.Cookie.Name = ".AspNet.SharedCookie"; opts.ExpireTimeSpan = TimeSpan.FromMinutes(60); opts.Cookie.IsEssential = true;
opts.Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context =>
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (context.Principal == null)
{
context.RejectPrincipal();
return;
}
}
};
})
.AddSaml2(opts =>
{
var config = BaseConfiguration.GetConfiguration();
opts.SPOptions.ServiceCertificates.Add(GenericHelpers.FindCertificateFromStore(config.Saml2["SigningCertificateSubject"]));
opts.ClaimsIssuer = config.Saml2["Issuer"];
opts.SPOptions.EntityId = new EntityId(opts.ClaimsIssuer);
opts.SPOptions.AuthenticateRequestSigningBehavior = SigningBehavior.Always;
opts.SPOptions.ReturnUrl = new Uri(config.Saml2["SamlLoginCallback"]);
opts.SPOptions.OutboundSigningAlgorithm = config.Saml2["SignatureAlgorithm"];
opts.IdentityProviders.Add(new IdentityProvider(new EntityId(config.Saml2["EntityId"]), opts.SPOptions)
{
MetadataLocation = config.Saml2["IdPMetadata"],
RelayStateUsedAsReturnUrl = true,
Binding = Saml2BindingType.HttpPost,
LoadMetadata = true,
SingleLogoutServiceUrl = new Uri(config.Saml2["SignOutUrl"]),
SingleLogoutServiceBinding = Saml2BindingType.HttpPost
});
opts.Notifications.AcsCommandResultCreated = (commandResult, response) =>
{
//Just testing invocation
};
})
This is my authentication on the web project side
services.AddAuthentication("Identity.Application")
.AddCookie("Identity.Application", opts =>
{
opts.Cookie.Name = ".AspNet.SharedCookie";
opts.Cookie.Domain = ".lifemark.ca";
opts.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = (context) =>
{
var apiSettings = BaseConfiguration.GetConfiguration().APISettings;
var path = context.HttpContext.Request.Path.Value;
var returnPath = System.Web.HttpUtility.UrlEncode($"{context.HttpContext.Request.Scheme}://{context.HttpContext.Request.Host.Value}{(path.StartsWith("/Account") ? "/" : path)}");
var signInCompleteReturnPath = System.Web.HttpUtility.UrlEncode($"{context.HttpContext.Request.Scheme}://{context.HttpContext.Request.Host.Value}/Account/SignInComplete?returnPath={returnPath}");
foreach (var cookie in context.HttpContext.Request.Cookies)
context.HttpContext.Response.Cookies.Append(cookie.Key, cookie.Value, new CookieOptions() { Domain = ".lifemark.ca", Path = "/" });
context.HttpContext.Response.Redirect($"{apiSettings.Address}/v{apiSettings.Version}/account/signin?returnPath={signInCompleteReturnPath}");
return Task.CompletedTask;
},
OnValidatePrincipal = async context =>
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (context.Principal == null)
{
context.RejectPrincipal();
return;
}
var user = context.Principal;
if (!await AuthHandler.Authorize(ref user, ServiceProvider.GetService<IAuthorizationService>(), context.HttpContext)
&& !context.HttpContext.Request.Headers["Authorization"].Any())
context.Response.Redirect($"/Account/AccessDenied?ReturnUrl={(context.Request.Path.Value.StartsWith("/Acccount") ? "/" : context.Request.Path.Value)}");
},
OnSigningOut = async context =>
{
foreach (var cookie in context.HttpContext.Request.Cookies)
context.HttpContext.Response.Cookies.Append(cookie.Key, cookie.Value, new CookieOptions() { Domain = "appsapilocal.lifemark.ca", Path = "/" });
var apiSettings = BaseConfiguration.GetConfiguration().APISettings;
context.HttpContext.Response.Redirect($"{apiSettings.Address}/v{apiSettings.Version}/account/signout");
}
};
});
Disregard this, I just found my answers in other previous topics. Just investigating these and will re-open later if needed.
I am running dotnet core 5, using Sustainsys.Saml2 & Sustainsys.Saml2.AspNetCore2 libraries version 2.8.0, using Visual Studio 2022.
I do NOT experience this issue locally with a DEBUGGER attached and every attempt to replicate the error while a debugger is attached fails. Everything works as expected.
I have 2 applications, an API, and a front end web project. I am using cookie authentication and sharing the cookies between the applications. The SignIn for Saml2 is initiated on the API application, and for authentication on the portal side I am using cookie authentication, and everything is working fine.
I can sign in no problems for the FIRST TIME ONLY with no debugger attached, I can sign out no problem, but when I try to navigate back after signing out by just clicking the back button, I am redirected to login to ADFS again to sign in, but after signing in the SECOND time, I receive this error message right after being redirected back to portalsite.com/Saml2/Acs/. I then have to close the browser and re-open it to sign in again.
I can tell you that in FireFox, this error does not appear whatsoever, regardless if I'm debugging or not, so I have a feeling it's the Chrome SameSite issue, but I can't figure out how to resolve it even from the suggestions provided throughout numerous forums.
I've tried for days now to identify what the issue is and have tried different cookie settings, workarounds, including ones described for this issue, but they do not seem to work.
Please advise what other type of details would help resolve this....