Skip to content

Commit 920eff3

Browse files
authored
AB#4678: Convert blog post to article
1 parent 59f27f1 commit 920eff3

3 files changed

Lines changed: 148 additions & 0 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
title: Infinite sign-in loop between ASP.NET application and Microsoft Entra ID
3+
description: Helps you resolve an infinite sign-in loop issue between an ASP.NET application and with Microsoft Entra ID when performing sign in.
4+
ms.date: 04/14/2025
5+
ms.author: bachoang
6+
ms.service: entra-id
7+
ms.custom: sap:Developing or Registering apps with Microsoft identity platform
8+
---
9+
10+
# Infinite sign-in loop between ASP.NET application and Microsoft Entra ID
11+
12+
This article provides solutions to an issue where an ASP.NET application experiences an infinite redirect loop during signing in with Microsoft Entra ID.
13+
14+
## Symptoms
15+
16+
An ASP.NET application running an old version of OWIN middleware fails to recognize an authenticated request from Microsoft Entra ID.  It keeps sending the request back to Microsoft Entra ID for signing in, leading to the infinite loop issue. The following error message might be displayed in the browser:
17+
18+
> We couldn't sign you in. Please try again.
19+
20+
## Cause
21+
22+
This issue occurs due to a cookie mismanagement issue (a [known Katana bug](https://github.com/aspnet/AspNetKatana/wiki/System.Web-response-cookie-integration-issues)) in the old version of OWIN.
23+
24+
### How to recognize the Katana bug
25+
26+
Capture a Fiddler trace and examine one of the later redirect frames back to the web application. Note in the following screenshot, the request in frame 58 contains multiple OpenIdConnect.nonce cookies (red-circled). In a working scenario, you should only have one OpenIdConnect.nonce cookie set at the beginning before authentication. After the request is successfully authenticated, this nonce cookie is destroyed and ASP.NET sets its own session cookie. Because of this bug, you see there is a build up of these nonce cookies.
27+
28+
:::image type="content" source="media/asp-dot-net-application-infinite-sign-in-loop/openidconnet-nonce-cookies.png" alt-text="Screenshot that shows multiple OpenIdConnect nonce cookies." lightbox="media/asp-dot-net-application-infinite-sign-in-loop/openidconnet-nonce-cookies.png":::
29+
30+
## Solution 1: Upgrade to ASP.NET Core
31+
32+
The issue has been resolved in ASP.NET Core and a newer version of Katana OWIN for ASP.NET. To resolve this issue, upgrade your application to use ASP.NET Core.
33+
34+
If you must continue to use ASP.NET, perform the following things:
35+
36+
- Update your application's Microsoft.Owin.Host.SystemWeb package to be at least version 3.1.0.0.
37+
- Modify your code to use one of the new cookie manager classes, for example:
38+
39+
```csharp
40+
app.UseCookieAuthentication(new CookieAuthenticationOptions
41+
{
42+
AuthenticationType = "Cookies",
43+
CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager()
44+
});
45+
```
46+
47+
Or
48+
49+
```csharp
50+
app.UseCookieAuthentication(new CookieAuthenticationOptions()
51+
{
52+
CookieManager = new SystemWebCookieManager()
53+
});
54+
```
55+
56+
## Solution 2: Correct the redirect URL
57+
58+
In some cases where the application is hosted under a virtual directory or an application instead of the root of the web site, the [solution 1](#solution-1-upgrade-to-aspnet-core) might not work. For more information, see [Infinite re-direct loop after AAD Authentication when redirect is specified](https://stackoverflow.com/questions/44397715/infinite-re-direct-loop-after-aad-authentication-when-redirect-is-specified) and [Microsoft Account OAuth2 sign-on fails when redirect URL is not under the website root](https://github.com/aspnet/AspNetKatana/issues/203).
59+
60+
For example, suppose you have the following environment:
61+
62+
- The root of a web site: `https://mysite` – This site runs under *Application Pool 1*.
63+
- An application *test2* under the root: `https://mysite/test2` – This application runs under *Application Pool 2*.
64+
- Your ASP.NET application runs under the *tes2* application with the following code:
65+
66+
```csharp
67+
public void Configuration(IAppBuilder app)
68+
{
69+
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
70+
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
71+
app.UseCookieAuthentication(new CookieAuthenticationOptions());
72+
app.UseOpenIdConnectAuthentication(
73+
new OpenIdConnectAuthenticationOptions
74+
{
75+
// Sets the ClientId, authority, RedirectUri as obtained from web.config
76+
ClientId = clientId,
77+
Authority = authority,
78+
RedirectUri = "https://mysite/test2",
79+
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
80+
PostLogoutRedirectUri = redirectUri,
81+
Scope = OpenIdConnectScope.OpenIdProfile,
82+
// ResponseType is set to request the id\_token - which contains basic information about the signed-in user
83+
ResponseType = OpenIdConnectResponseType.IdToken,
84+
// ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
85+
// To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
86+
// To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
87+
88+
// OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
89+
90+
Notifications = new OpenIdConnectAuthenticationNotifications
91+
{
92+
AuthenticationFailed = OnAuthenticationFailed
93+
}
94+
95+
}
96+
);
97+
}
98+
```
99+
100+
And you are using the following code for triggering the sign in flow:
101+
102+
```csharp
103+
public void SignIn()
104+
{
105+
if (!Request.IsAuthenticated)
106+
{
107+
HttpContext.GetOwinContext().Authentication.Challenge(
108+
new AuthenticationProperties { RedirectUri = "/" },
109+
OpenIdConnectAuthenticationDefaults.AuthenticationType);
110+
}
111+
}
112+
```
113+
114+
This scenario can result in an authentication infinite loop with a build-up of multiple OpenIdConnect.nonce cookies. The difference is that ASP.NET doesn't appear to set its authenticated session cookies. To resolve the issue in such scenario, set the redirect URLs in the OpenID Connect initialization code and the `Challenge` method (note the trailing slash in the redirect URL):
115+
116+
```csharp
117+
app.UseOpenIdConnectAuthentication(
118+
new OpenIdConnectAuthenticationOptions
119+
{
120+
// Sets the ClientId, authority, RedirectUri as obtained from web.config
121+
ClientId = clientId,
122+
Authority = authority,
123+
RedirectUri = "https://mysite/test2/",
124+
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
125+
PostLogoutRedirectUri = redirectUri,
126+
Scope = OpenIdConnectScope.OpenIdProfile,
127+
...
128+
```
129+
130+
```csharp
131+
public void SignIn()
132+
{
133+
if (!Request.IsAuthenticated)
134+
{
135+
HttpContext.GetOwinContext().Authentication.Challenge(
136+
new AuthenticationProperties { RedirectUri = "/test2/" },
137+
OpenIdConnectAuthenticationDefaults.AuthenticationType);
138+
}
139+
}
140+
```
141+
142+
## References
143+
144+
[Infinite redirects with ASP.NET OWIN and OpenID Connect](https://varnerin.info/infinite-redirects-with-aspnet-owin-and-openid-connect/)
145+
146+
[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)]
1.94 MB
Loading

support/entra/entra-id/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
href: app-integration/enable-msal4j-logging-spring-boot-webapp.md
6464
- name: Repeated login prompts in iOS MSAL implementation
6565
href: app-integration/repeat-login-prompts-in-msal-ios-app.md
66+
- name: Infinite sign-in loop issue with ASP.NET applications
67+
href: app-integration/repeat-login-prompts-in-msal-ios-app.md
6668

6769

6870
- name: Troubleshoot adding apps

0 commit comments

Comments
 (0)