繁体   English   中英

在MVC5中使用Azure AD和个人帐户混合cookie外部登录

[英]Mixing cookie external login using Azure AD and individual account in MVC5

我遇到了应用程序 cookie 和外部 cookie 的问题,它们使用 MVC5 与 Azure AD 集成登录到我的 web 应用程序。 目前,我的本地帐户可以正常工作,但外部帐户(Google 和 Azure AD)无法将外部 cookie 转换为本地 cookie。 我的代码获取 userId 返回不正确的用户 ID。

IIdentity ident = HttpContext.Current.GetOwinContext().Request.User.Identity;
ident.GetUserId()

下面是我的startup.cs

public partial class Startup
    {
        // The Client ID is used by the application to uniquely identify itself to Azure AD.
        string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];

        // RedirectUri is the URL where the user will be redirected to after they sign in.
        string redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];

        string postLogoutRedirectUri = System.Configuration.ConfigurationManager.AppSettings["PostLogoutRedirectUri"];

        // Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant)
        static string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];

        // Authority is the URL for authority, composed by Microsoft identity platform endpoint and the tenant name (e.g. https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0)
        string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);

        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(AppIdentityDbContext.Create);
            app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
            app.CreatePerOwinContext<AppSignInManager>(AppSignInManager.Create);
            app.CreatePerOwinContext<AppRoleManager>(AppRoleManager.Create);


            // 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,
                AuthenticationMode = AuthenticationMode.Active,
                LoginPath = new PathString("/"),
                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<AppUserManager, AppUser>(
                        validateInterval: TimeSpan.FromHours(1),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                },
                ExpireTimeSpan = TimeSpan.FromHours(1),
                //Samesite secure
                CookieSameSite = SameSiteMode.Lax,
                CookieHttpOnly = true,
                CookieSecure = CookieSecureOption.Always,
                CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            //Open Id Connect
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
            });
            app.UseOpenIdConnectAuthentication(CreateOpenIdOptions());

            // GOOGLE
            app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            {
                ClientId = ConfigurationManager.AppSettings["GoogleClientID"].ToString(),
                ClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"].ToString()
            });
        }

        private OpenIdConnectAuthenticationOptions CreateOpenIdOptions()
        {
            var options = new OpenIdConnectAuthenticationOptions
            {
                Authority = authority,
                ClientId = clientId,
                RedirectUri = redirectUri,
                AuthenticationMode = AuthenticationMode.Passive,
                // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
                PostLogoutRedirectUri = postLogoutRedirectUri,
                Scope = OpenIdConnectScope.OpenIdProfile, // a basic set of permissions for user sign in & profile access
                                                          // ResponseType is set to request the id_token - which contains basic information about the signed-in user
                ResponseType = OpenIdConnectResponseType.IdToken,
                TokenValidationParameters = new TokenValidationParameters
                {
                    // In a real application you would use ValidateIssuer = true for additional checks and security.
                    ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = OnAuthenticationFailed,
                },
                // Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/samesite/owin-samesite
                CookieManager = new SameSiteCookieManager(
                                 new SystemWebCookieManager()),
            };

            return options;
        }

        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
        {
            // Handle any unexpected errors during sign in
            context.OwinContext.Response.Redirect("/Error?message=" + context.Exception.Message);
            context.HandleResponse(); // Suppress the exception
            return Task.FromResult(0);
        }
    }

下面是登录前调用的注销方法

var authenticationTypes = new string[] {
                DefaultAuthenticationTypes.ApplicationCookie,
                DefaultAuthenticationTypes.ExternalCookie,
            };

            AuthManager.SignOut(authenticationTypes);

我也已经尝试过应用许多与此相关的固定帖子,但它不起作用。 我们如何将外部 cookie map 解析为本地 cookie?

最后,我在下面找到了解决方法:首先,如果您不想使用 Open id connect,请使用下面的链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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