使用两个ASP.NET MVC项目之间的ASP.NET标识进行单点登录

时间:2017-02-14 15:20:57

标签: c# asp.net asp.net-mvc asp.net-identity single-sign-on

我有2个Web应用程序,它们共享相同的主级域,如下所述,所以我可以共享cookie。两个项目中的Web.conifg具有相同的机器密钥和验证密钥。因为,我想使用Identity和 NOT 表单认证,我的web.config文件中没有一个节点。我能够从SSO中成功创建Auth cookie,并且可以在SSO中查看授权页面,但是当我尝试访问MVC项目中的授权视图时,我仍然被重定向到SSO登录。

  1. sso.domain.com - MVC项目
  2. mvc.domain.com - MVC项目
  3. 我的SSO和MVC项目中有一个startup.cs文件,如下所示:

        public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    
        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                ExpireTimeSpan = TimeSpan.FromMinutes(3),                
                LoginPath = new PathString("/Login"),
                CookieName = "MyCookieName",
                CookieDomain = ".domain.com"               
            });
    
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
    
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
        }
    }
    

    以下是我在AccountController.cs下的SSO项目中的代码。我在下面调用IdentitySignin函数,根据创建cookie的数据库验证用户:

            private void IdentitySignin(string userId, string name, string providerKey = null, bool isPersistent = false)
        {
            var claims = new List<Claim>();
    
            // create *required* claims
            claims.Add(new Claim(ClaimTypes.NameIdentifier, userId));
            claims.Add(new Claim(ClaimTypes.Name, name));            
    
            var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
    
    
            //get the expiry minutes from config or use the default value of 30 minutes
            double expiryMinutes;
            expiryMinutes = double.TryParse(ConfigurationManager.AppSettings["AuthCookieExpiryMinutes"], out expiryMinutes) ? expiryMinutes : 30;
    
            // add to user here!
            AuthenticationManager.SignIn(new AuthenticationProperties()
            {
                AllowRefresh = true,
                IsPersistent = isPersistent,
                ExpiresUtc = DateTime.UtcNow.AddMinutes(expiryMinutes),
                IssuedUtc = DateTime.UtcNow                  
            }, identity);
        }
    
        private void IdentitySignout()
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
        }
    
        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.GetOwinContext().Authentication;
            }
        }
    
        private async Task<string> GetVerifiedUserIdAsync()
        {
            var result = await AuthenticationManager.AuthenticateAsync(
                DefaultAuthenticationTypes.ApplicationCookie);
    
            if (result != null && result.Identity != null
                && !String.IsNullOrEmpty(result.Identity.GetUserId()))
            {
                return result.Identity.GetUserId();
            }
            return null;
        }
    

2 个答案:

答案 0 :(得分:4)

最有可能的是,您尚未设置共享计算机密钥。 auth cookie是加密的,除非两个站点共享相同的机器密钥,否则无法解密另一个加密的内容。将以下内容添加到项目的Web.config:

<sytem.web>

    ...

    <machineKey validation="HMACSHA256" validationKey="[validationKey]"  decryptionKey="[decryptionKey]" compatibilityMode="Framework45" />

要生成密钥,请在IIS中单击左窗格中的服务器,然后单击“计算机密钥”控制面板项。选择验证方法(上面,我使用过HMACSHA256)。我不建议使用默认的SHA1,因为它非常容易破解。然后,在右侧“操作”面板上,单击“生成密钥”。将两个文本框值复制到此配置元素的相应属性,并确保它们对于需要共享身份​​验证cookie的所有项目都是相同的。

答案 1 :(得分:4)

所以,我想出了单点登录在两个MVC应用程序之间没有工作的原因,尽管它们共享相同的机器和验证密钥。

我的SSO MVC应用程序和其他MVC应用程序都使用不同版本的OWIN和ASP.NET Identity DLL。我使用Nuget在一个项目中更新DLLS,但没有在另一个项目中进行更新。

我希望这有助于遇到此问题的人。

正如仅供参考,要在多个应用程序之间共享ASP.NET身份验证,请确保在每个应用程序中有以下内容:

  1. web.config文件中的相同计算机密钥和验证密钥
  2. 相同版本的OWIN和ASP.NET IDENTITY DLL
  3. Startup.cs中的相同COOKIE NAME和COOKIE DOMAIN
  4. 两个应用都需要在同一个域上才能共享身份验证Cookie