I'm running a .NET framework 4.7.2 application using OWIN cookie authentication under IIS as a virtual application locally (e.g., https://example.test/cms/) but I end up in and endless redirect loop after I navigate to https://example.test/cms/ and logged in there. It validates the security token but the .AspNet.Cookies cookie does not seem to persist which causes an endless loop.
I configured the Redirect URI as https://example.test/cms/signin-oidc/ and I have a valid self-signed certificate for HTTPS. Am I missing something?
public static void ConfigureAuthentication(IAppBuilder app)
{
var clientId = SsoConfig.Instance.ClientId;
var authority = $"https://login.microsoftonline.com/{SsoConfig.Instance.TenantId}/v2.0";
var redirectUri = SsoConfig.Instance.RedirectUri;
var loggingCookieManager = new LoggingCookieManager();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieSecure = CookieSecureOption.Always,
ExpireTimeSpan = TimeSpan.FromHours(1),
CookiePath = "/cms",
CookieManager = loggingCookieManager,
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
CookieManager = loggingCookieManager,
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
ResponseType = OpenIdConnectResponseType.CodeIdToken,
Scope = "openid profile email offline_access",
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true
},
RequireHttpsMetadata = true,
SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
});
}
And my Cookie Manager is just a wrapper for debugging.
public class LoggingCookieManager : ICookieManager
{
private readonly ICookieManager _inner;
public LoggingCookieManager(ICookieManager inner = null)
{
_inner = inner ?? new CookieManager();
}
public string GetRequestCookie(IOwinContext context, string key)
{
var val = _inner.GetRequestCookie(context, key);
Debug.WriteLine($"GetRequestCookie: {key} = {val}");
return val;
}
public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
{
options.SameSite = Microsoft.Owin.SameSiteMode.None; // to make sure the cookie is sent in all contexts (cross-site)
Debug.WriteLine($"AppendResponseCookie: {key} = {value}, Path={options.Path}, SameSite={options.SameSite}, Secure={options.Secure}");
_inner.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
Debug.WriteLine($"DeleteCookie: {key}");
_inner.DeleteCookie(context, key, options);
}
}
I hoped the Cookie Manager wrapper gave me some more insights but it did not. It seemed to set the cookie correctly as .AspNet.Cookies=<cookie-value-here>; path=/cms; secure; HttpOnly; SameSite=None. But the next time it called GetRequestCookie at https://example.test/cms/ the cookie was null.
path=/cms, and invoke your app viahttps://example.test/myapp/? $\endgroup$/cms, but the URL path you are requesting starts with/myapp/. $\endgroup$