简体   繁体   中英

asp.net mvc azure AAD authentication infinite loop

I have an asp.net mvc application with azure AAD sign in. When I press f5 to debug the application goes to azure to authenticate in AAD, then it goes back to the application to the controller, and its redirected back again to azure.

I know this because If I put a breakpoint on the Sign In controller it gets hit infinitely

This is my route config

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            //routes.IgnoreRoute("");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Dashboards", action = "Dashboard_1", id = UrlParameter.Optional }
            );
        }

This is my dashboard controller which has authorize

[Authorize]
    public class DashboardsController : Controller
    {
        public ActionResult Dashboard_1()
        {
            return View();
        }

This is my Sign In and sign account controller actions

public class AccountController : Controller
    {
        public void SignIn()
        {
            if (!Request.IsAuthenticated)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(
                                new AuthenticationProperties { RedirectUri = "/" },
                                OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }
        }

        public void SignOut()
        {
            // Remove all cache entries for this user and send an OpenID Connect sign-out request.
            string usrObjectId = ClaimsPrincipal.Current.FindFirst(SettingsHelper.ClaimTypeObjectIdentifier).Value;
            AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority, new EfAdalTokenCache(usrObjectId));
            authContext.TokenCache.Clear();

            HttpContext.GetOwinContext().Authentication.SignOut(
                OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
        }

        public ActionResult ConsentApp()
        {
            string strResource = Request.QueryString["resource"];
            string strRedirectController = Request.QueryString["redirect"];

            string authorizationRequest = String.Format(
                "{0}oauth2/authorize?response_type=code&client_id={1}&resource={2}&redirect_uri={3}",
                    Uri.EscapeDataString(SettingsHelper.AzureADAuthority),
                    Uri.EscapeDataString(SettingsHelper.ClientId),
                    Uri.EscapeDataString(strResource),
                    Uri.EscapeDataString(String.Format("{0}/{1}", this.Request.Url.GetLeftPart(UriPartial.Authority), strRedirectController))
                    );

            return new RedirectResult(authorizationRequest);
        }

        public ActionResult AdminConsentApp()
        {
            string strResource = Request.QueryString["resource"];
            string strRedirectController = Request.QueryString["redirect"];

            string authorizationRequest = String.Format(
                "{0}oauth2/authorize?response_type=code&client_id={1}&resource={2}&redirect_uri={3}&prompt={4}",
                    Uri.EscapeDataString(SettingsHelper.AzureADAuthority),
                    Uri.EscapeDataString(SettingsHelper.ClientId),
                    Uri.EscapeDataString(strResource),
                    Uri.EscapeDataString(String.Format("{0}/{1}", this.Request.Url.GetLeftPart(UriPartial.Authority), strRedirectController)),
                    Uri.EscapeDataString("admin_consent")
                    );

            return new RedirectResult(authorizationRequest);
        }

        public void RefreshSession()
        {
            string strRedirectController = Request.QueryString["redirect"];

            HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = String.Format("/{0}", strRedirectController) }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }
    }

and this is my startup.auth.cs

 public void ConfigureAuth(IAppBuilder app)
        {
            // configure the authentication type & settings
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            // configure the OWIN OpenId Connect options
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = SettingsHelper.ClientId,
                Authority = SettingsHelper.AzureADAuthority,
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    // when an auth code is received...
                    AuthorizationCodeReceived = (context) => {
                        // get the OpenID Connect code passed from Azure AD on successful auth
                        string code = context.Code;

                        // create the app credentials & get reference to the user
                        ClientCredential creds = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);
                        string userObjectId = context.AuthenticationTicket.Identity.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;

                        // use the ADAL to obtain access token & refresh token...
                        //  save those in a persistent store...
                        EfAdalTokenCache sampleCache = new EfAdalTokenCache(userObjectId);
                        AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority, sampleCache);

                        // obtain access token for the AzureAD graph
                        Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                        AuthenticationResult authResult = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, creds, SettingsHelper.AzureAdGraphResourceId);

                        // successful auth
                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = (context) => {
                        context.HandleResponse();
                        return Task.FromResult(0);
                    }
                },
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = false
                }
            });
        }

We ran into the same issue and solved it by slipping in the Kentor cookie saver. See https://github.com/KentorIT/owin-cookie-saver for details.

To resolve this issue: you can upgrade your application to use ASP.NET Core. If you must continue stay on ASP.NET, perform the following: Update your application's Microsoft.Owin.Host.SystemWeb package be at least version and Modify your code to use one of the new cookie manager classes, for example something like the following:

    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
        AuthenticationType = "Cookies", 
        CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager() 
    });

Reference Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM