1

So ive gone through as many posts as I can, and I cant seem to sort this out!

My client wants us to allow logging into their ADFS via an MVC platform that I have built, so I am trying to allow them to sign into their Azure AD to sign into the platform.

When I am redirected to my signin page for Azure AD(MS Login), I type in my credentials and then it looks like it is doing a quick redirect loop and then automatically signs me out, I am going crazy!!!

Below is everything I have setup:

On Azure AD:

  • Created App service and put ApplicationId and TenantId in my Web.config

    <add key="ida:ClientId" value="ApplicationID from AzureAD" />

    <add key="ida:Tenant" value="TenantId from AzureAD" />

    <add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />

    <add key="ida:RedirectUri" value="https://sitename.azurewebsites.net/Home/Index" />

    <add key="ida:PostLogoutRedirectUri" value="https://sitename.azurewebsites.net" />

On Startup.Auth.cs

public partial class Startup
    {

        // Calling the keys values from Web.config file  
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
        private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

        // Concatenate aadInstance, tenant to form authority value       
        private string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

        // ConfigureAuth method  
        public void ConfigureAuth(IAppBuilder app)
        {
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            //app.UseCookieAuthentication(new CookieAuthenticationOptions());

            //Enable the application to use a cookie to store information for the signed in user

            //and to use a cookie to temporarily store information about a user logging in with a third party login provider

            //Configure the sign in cookie

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(

                            new OpenIdConnectAuthenticationOptions
                            {
                                ClientId = clientId,
                                Authority = authority,
                                PostLogoutRedirectUri = postLogoutRedirectUri,
                                Notifications = new OpenIdConnectAuthenticationNotifications
                                {
                                    AuthenticationFailed = (context) =>
                                    {
                                        context.HandleResponse();
                                        context.OwinContext.Response.Redirect("/Home/Index");
                                        return Task.FromResult(0);
                                    }
                                }
                            });


        } // end - ConfigureAuth method  

On my routeConfig : This was done so that my custom landing page can be loaded first, on this page is a button saying "Enter platform", which the client will click on and go to Azure AD signin(MS Login page)

public static class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.LowercaseUrls = true;
            routes.MapRoute("Default", "{controller}/{action}/{id}", new
            {
                controller = "Account",
                action = "Login",
                id = UrlParameter.Optional
            }).RouteHandler = new DashRouteHandler();
        }
    }

Account Controller

[Authorize]
        public void SignIn()
        {
            clsHomeScreen clsHomeScreen = new clsHomeScreen();
            if (!Request.IsAuthenticated)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }

            Response.Redirect("/");
        }

[AllowAnonymous]
        [OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
        public ActionResult Login(string returnUrl)
        {
            // We do not want to use any existing identity information
            EnsureLoggedOut();

            // Store the originating URL so we can attach it to a form field
            var viewModel = new AccountLoginModel { ReturnUrl = returnUrl };

            return View(viewModel);
        }

HomeController - This is where it SHOULD be redirected to after signing in, but its not:

[Authorize]
        public async Task<ActionResult> Index()
        {
            HomeScreenLists HS = new HomeScreenLists();
            IEnumerable<Challenges> ActiveChallenges;
            IEnumerable<Challenges> PrivateChallenges;
            string loggedInUserId = "";
            string loggedInEmail = "";
            var userClaims = User.Identity as System.Security.Claims.ClaimsIdentity;

            string email = userClaims?.FindFirst(System.IdentityModel.Claims.ClaimTypes.Name)?.Value;
            string firstname = userClaims?.FindFirst(System.IdentityModel.Claims.ClaimTypes.GivenName)?.Value;
            string lastname = userClaims?.FindFirst(System.IdentityModel.Claims.ClaimTypes.Surname)?.Value;
            string userId = "";

            //The Email will not contain an @(i.e. an email address) if not using Azure AD to sign in.
            if (!email.Contains("@"))
            {
                loggedInUserId = User.Identity.GetUserId();
                goto LoggedInUser_Found;
            }

            if (TempData["LoggedInEmail"] != null)
            {
                if (email != TempData["LoggedInEmail"].ToString())
                {
                    userId = clsHomeScreen.GetUserId(TempData["LoggedInEmail"].ToString());
                }
                else
                {
                    userId = clsHomeScreen.GetUserId(email);
                }
            }

            if (email != null)
            {
                userId = clsHomeScreen.GetUserId(email);
            }

            if (userId == null || userId == "")
            {
                clsUsers clsUsers = new clsUsers();

                if (TempData["LoggedInEmail"] != null)
                {
                    loggedInEmail = TempData["LoggedInEmail"].ToString();

                    var userDetails = clsUsers.GetUsers().Where(x => x.Email == loggedInEmail).FirstOrDefault();
                    loggedInUserId = userDetails.Id;
                }
                else
                {
                    if(userId == null)
                    {
                        await RegisterAAD();
                        userId = clsHomeScreen.GetUserId(email);
                        loggedInUserId = userId;
                    }
                    else
                    {
                        loggedInUserId = User.Identity.GetUserId();
                    }
                    
                }
            }
            else
            {
                loggedInUserId = userId;
            }

            LoggedInUser_Found:

            int iBU = (int)db.Users.FirstOrDefault(x => x.Id == loggedInUserId).fkiBusinessUnitId;

            if (iBU == 0)
            {
                HS.HasBU = false;
                TempData["HasBU"] = "No";
                TempData["UserId"] = loggedInUserId;
            }
            else
            {
                HS.HasBU = true;
                TempData["HasBU"] = "Yes";
                TempData["UserId"] = loggedInUserId;
            }

            bool isAdmin = false;

            if (User.IsInRole("Administrator"))
            {
                isAdmin = true;
            }

            ActiveChallenges = clsChallenges.GetActiveChallenges();
            PrivateChallenges = clsChallenges.GetPrivateChallenges(loggedInUserId, isAdmin);

            HS.HomeScreenList = clsHomeScreen.GetHomeScreenAdverts();

            HS.ActiveChallengesList = ActiveChallenges;
            HS.PrivateChallengesList = PrivateChallenges;

            HS.UserId = loggedInUserId;

            return View(HS);
        }

So if I remove the [Authorize] attribute on the Index ActionResult, then it does a continuous redirect loop.

What ive tried:

  • I have tried using the KentorCookiSaver, which didnt work.
  • Recreating the app service
  • Changed the redirectUrl in Azure AD App Registration
  • Someone even spoke about rewriting the cookies, which I tried, but dont know if I followed the steps correctly, the link is Here

Ive tried so many things that I cant even remember what ive tried. Could anyone possibly help with what I am doing wrong, please.

Thanks a million!

Community
  • 1
  • 1
AxleWack
  • 1,801
  • 1
  • 19
  • 51

1 Answers1

0

So with some help from someone who knows these things, my problem was solved.

Ultimately what it came down to was:

  • I needed to add the RedirectUri into my Web.config and into my Startup.Auth

Web.Config

<add key="ida:RedirectUri" value="https://sitename.azurewebsites.net/Home/Index"/>

Startup.Auth

 app.UseOpenIdConnectAuthentication(

                            new OpenIdConnectAuthenticationOptions
                            {
                                ClientId = clientId,
                                Authority = authority,
                                RedirectUri = redirectUri,
                                PostLogoutRedirectUri = postLogoutRedirectUri,
                                Notifications = new OpenIdConnectAuthenticationNotifications
                                {
                                    AuthenticationFailed = (context) =>
                                    {
                                        context.HandleResponse();
                                        context.OwinContext.Response.Redirect("/Home/Index");
                                        return Task.FromResult(0);
                                    }
                                }
                            });
  • My Signin process kept routing back to my Account/Login page when failing, when it should have routed to my Home/Index, as I was using my Account/Login as my landing page and authentication only happening there after, the problem that happened here was because I did an "EnsureLogOut" on the Account/Login, thus why it kept logging me out first before wanting to authenticate. So instead of the Redirect = "/" I changed as follows:

public void SignIn()

    `{`

        `clsHomeScreen clsHomeScreen = new clsHomeScreen();`

        `if (!Request.IsAuthenticated)`

        `{`

            `HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/Home/Index" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);`

        `}`


        `Response.Redirect("/Home/Index");`

    `}`

Perhaps this is something that might not help others, but maybe it helps them in the right direction.

AxleWack
  • 1,801
  • 1
  • 19
  • 51