Is it possible to have both Azure AD and Individual Account authentication in one ASP.NET MVC application?

后端 未结 1 910
攒了一身酷
攒了一身酷 2020-12-04 22:59

I am kind of successful by doing this in the Startup.Auth.cs file

  // Configure the db context and user manager to use a single instance per request
                


        
相关标签:
1条回答
  • 2020-12-04 23:35

    Try this

    app.UseOpenIdConnectAuthentication(
               new OpenIdConnectAuthenticationOptions
               {
                   ClientId = ClientId,
                   Authority = Authority,                   
                   Notifications = new OpenIdConnectAuthenticationNotifications()
                   {
    
    
                       RedirectToIdentityProvider = (context) =>
                       {
    
                           if (context.Request.Path.Value == "/Account/ExternalLogin" || (context.Request.Path.Value == "/Account/LogOff" && context.Request.User.Identity.IsExternalUser()))
                           {
                               // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                               // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
                               // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                               string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                               context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
                               context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                           }
                           else
                           {
                               //This is to avoid being redirected to the microsoft login page when deep linking and not logged in 
                               context.State = Microsoft.Owin.Security.Notifications.NotificationResultState.Skipped;
                               context.HandleResponse();
                           }
                           return Task.FromResult(0);
                       },
                   }
               });
    

    EDIT:

    Forgot this extension method

        public static class IdentityExtensions
    {
        public static bool IsExternalUser(this IIdentity identity)
        {
            ClaimsIdentity ci = identity as ClaimsIdentity;
    
            if (ci != null && ci.IsAuthenticated == true)
            {
                var value = ci.FindFirstValue(ClaimTypes.Sid);
                if (value != null && value == "Office365")
                {
                    return true;
                }
            }
            return false;
        }
    }
    

    EDIT 2:

    You have to have some custom logic in the ExternalLoginCallback (AccountController) e.g. add the Sid claim. In this case there is also logic to check if the user allows external login.

     // GET: /Account/ExternalLoginCallback
        [AllowAnonymous]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl, string urlHash)
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
            if (loginInfo == null)
            {
                return RedirectToAction("Login");
            }
    
            var claims = new List<Claim>();
            claims.Add(new Claim(ClaimTypes.Sid, "Office365"));
    
            // Sign in the user with this external login provider if the user already has a login
            var user = await UserManager.FindAsync(loginInfo.Login);
            if (user == null)
            {
                user = await UserManager.FindByNameAsync(loginInfo.DefaultUserName);
    
                if (user != null)
                {
                    if(user.AllowExternalLogin == false)
                    {
                        ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName));
                        return View("Login");
                    }
                    var result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login);
    
                    if (result.Succeeded)
                    {
                        if (claims != null)
                        {
                            var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
                            userIdentity.AddClaims(claims);
                        }
                        await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                    }
                    return RedirectToLocal(returnUrl);
                }
                else
                {
                    ModelState.AddModelError("", String.Format("User {0} not found.", loginInfo.DefaultUserName));
                    return View("Login");
                }
            }
            else
            {
    
                if (user.AllowExternalLogin == false)
                {
                    ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName));
                    return View("Login");
                }
    
                if (claims != null)
                {
                    var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
                    userIdentity.AddClaims(claims);
                }
                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                return RedirectToLocal(returnUrl);
            }
        }
    
    0 讨论(0)
提交回复
热议问题