skip to Main Content

I am encountering an infinite redirect loop between login.microsoftonline.com and my application. My project is implementing authentication and authorization in an Asp.net 4.8 web forms project. I am able to add authentication using the default Owin startup file and then require authentication in the web config file. The below works correctly for requiring a user to sign in before being able to access pages/AuthRequired

StartupAuth.CS

public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
        private static string authority = ConfigurationManager.AppSettings["ida:Authority"];
        private static string clientSecret = ConfigurationManager.AppSettings["AppRegistrationSecret-Local"];
        public void ConfigureAuth(IAppBuilder app)
        {
            //for debugging
            //IdentityModelEventSource.ShowPII = true;

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
                    ClientSecret = clientSecret,
                    RedirectUri = postLogoutRedirectUri,
                    //This allows multitenant
                    //https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/03-authentication.md
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = false
                    },

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthenticationFailed = (context) =>
                        {
                            return Task.FromResult(0);
                        }
                    }
                }
                );

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }
    }

Web.Config

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <deny users="?" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

I need to add authorization so that only users with the admin role will be able to access Pages/AuthRequired. I have done that by updating the web config:

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <allow roles="Admin" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

Adding authorization to the authenticated page works correctly if the user has that role, but if a user who doesn’t have the role tries to access the page they are redirected back to login.microsoftonline.com and then back to the application in an infinite loop.

I can see that Owin UseOpenIdConnectAuthentication is returning a 302 response on unauthorized and that is causing the loop.

How can I change it so that instead of redirecting unauthorized (but authenticated) users to login.microsoftonline.com, that user should be directed to an app page that displays a 401 error?

2

Answers


  1. Please check if below work around helps:

    Its usually possible that if forms authentication is enabled, you will be redirected to the login page when status code is 401.

    As a workaround try Adding the below to global.asax in the application end request and you can create own unauthorized page if needed and redirect to that.

    if (this.Response.StatusCode == 302&& this.Response.StatusCode == 401 
            && this.Response.RedirectLocation.ToLower().Contains("login.aspx"))
          {
            this.Response.StatusCode = 401;
             //or Response.Redirect("Unauthorized.aspx");
          }
          
    

    You can also check this > Redirect unauthorised user to message page in ASP .Net. (microsoft.com)

    Other references

    1. Prevent redirect to login on status code 401 (Unauthorized)
      (microsoft.com)
    2. asp.net – In-place handling (no redirect) of 401 unauthorized? –
      Stack Overflow
    Login or Signup to reply.
  2. ASP.NET URL Authorization doesn’t appear to interoperate well with OIDC (i.e. Azure AD).

    First remove the URL Authorization from your Web.config:

    <configuration>
    ...
        <system.web>
            <authentication mode="None" />
        </system.web>
        <location path="Pages/AuthRequired">
            <system.web>
    --            <authorization>
    --                <allow roles="Admin" />
    --                <deny users="*" />
    --            </authorization>
            </system.web>
        </location>
        <system.webServer>
            <modules>
                <remove name="FormsAuthentication" />
            </modules>
        </system.webServer>
    ...
    </configuration>
    

    Optionally make authenticated required for all pages globally:

        <system.web>
          <deny users="?" />
        </system.web>
    

    You can override this behaviour with <Allow users="?" /> for specific pages i.e. logins/logouts/erorr pages/etc.

    Second add authorization logic to your AuthRequired.aspx page:

    public partial class AuthRequired {
      protected void Page_Load(object sender, EventArgs e)
      {
        Authorization.AuthorizeAuthRequiredPage();
        ...
      }
    }
    
    public static class Authorization
    {
      public static void AuthorizeAuthRequiredPage()
      {
        if (!Authorized(HttpContext.User))
        {
          Redirect("/Anauthorized.aspx");
        }
      }
    
      private static bool Authorized(User user) => { ... }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search