ASP.NET身份验证在两个ASP.NET MVC项目之间实现单点登录

10

我有两个 Web 应用程序,它们都共享与下面提到的相同的主级域名,因此可以共享 cookies。 这两个项目中的 Web.config 都具有相同的机器密钥和验证密钥。 由于我想使用身份验证而不是表单验证,在我的任何 Web.config 文件中都没有一个<authentication>节点。 我能够成功地从 SSO 创建 Auth cookie 并在 SSO 中查看已授权的页面,但当我尝试访问 MVC 项目中的已授权视图时仍然会重定向到 SSO 登录。

  1. sso.domain.com - MVC 项目
  2. mvc.domain.com - MVC 项目

我在我的 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;
    }
}

以下是我在SSO项目中AccountController.cs文件中的代码。当用户通过数据库验证时,我会调用下面的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个回答

6
所以,我找出了Single Sign On在两个MVC应用程序之间不起作用的原因,尽管它们共享相同的机器和验证密钥。我的SSO MVC应用程序和另一个MVC应用程序都使用不同版本的OWIN和ASP.NET Identity DLLs。我使用Nuget更新了一个项目中的DLLS,但没有在另一个项目中进行更新。
我希望这可以帮助遇到此问题的人。只是作为参考,要在多个应用程序之间共享ASP.NET Identity身份验证,请确保每个应用程序具备以下内容:
  1. web.config文件中具有相同的机器密钥和验证密钥
  2. 具有相同版本的OWIN和ASP.NET IDENTITY DLL
  3. 在Startup.cs中具有相同的COOKIE NAME和COOKIE DOMAIN
  4. 两个应用程序需要在同一个域中才能共享认证cookie

5

很可能你没有设置共享的机器密钥。鉴权cookie是加密的,除非两个站点共享相同的机器密钥,否则一个站点无法解密另一个站点加密的内容。请在两个项目的Web.config文件中添加以下内容:

<sytem.web>

    ...

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

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

谢谢Chris的快速回复,但是我已经在两个项目的web.config文件中配置了相同的机器密钥,就像我在上面的问题中提到的那样。 - Naupad Doshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接