Hello Arpit Tandon, this redirect loop with Azure AD + OWIN is typically caused by a callback/redirect mismatch, cookie settings, or an auth type mismatch. Here are my recommendations:
- Make the redirect exact
- Set
RedirectUri = https://<host>:<port>/signin-oidcandCallbackPath = "/signin-oidc". - Register that exact URI (scheme/host/port/path) in Entra ID; don’t reuse
PostLogoutRedirectUri.
- Set
- Order and auth types
- Call
app.SetDefaultSignInAsAuthenticationType("Cookies"). - Use
UseCookieAuthentication(...)beforeUseOpenIdConnectAuthentication(...). - In OIDC:
SignInAsAuthenticationType = "Cookies"(must match cookieAuthenticationType).
- Call
- Cookies/SameSite/nonce
-
CookieSecure = Always,CookieSameSite = None,CookieManager = new SystemWebChunkingCookieManager(). - Prevents nonce/correlation cookie loops and large headers.
-
- HTTPS only
- Run on HTTPS even locally; mixed HTTP/HTTPS drops secure cookies and retriggers auth.
- Update OWIN/Katana (optional helper)
- Update
Microsoft.Owin.*packages to latest (older versions had nonce/correlation bugs). - Optional legacy helper:
app.UseKentorOwinCookieSaver()before cookies. - References: https://github.com/Sustainsys/owin-cookie-saver
- Update
Minimal working config:
app.SetDefaultSignInAsAuthenticationType("Cookies");
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = "Cookies",
CookieSecure = CookieSecureOption.Always,
CookieSameSite = Microsoft.Owin.SameSiteMode.None,
CookieManager = new SystemWebChunkingCookieManager()
});
// optional (legacy): app.UseKentorOwinCookieSaver();
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
ClientId = ClientId,
Authority = Authority,
ClientSecret = OidcClientSecret,
RedirectUri = "https://localhost:44300/signin-oidc",
PostLogoutRedirectUri = "https://localhost:44300/",
CallbackPath = new PathString("/signin-oidc"),
ResponseType = OpenIdConnectResponseType.Code,
SignInAsAuthenticationType = "Cookies",
TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false } // set true in production
});
If a loop persists, confirm X-Forwarded-Proto=https behind proxies and use a shared machine key across instances. Hope this solves your problem.