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

use*_*865 9 c# asp.net asp.net-mvc single-sign-on asp.net-identity

我有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项目

我在我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

下面是我到目前为止在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;
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*att 5

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

<sytem.web>

    ...

    <machineKey validation="HMACSHA256" validationKey="[validationKey]"  decryptionKey="[decryptionKey]" compatibilityMode="Framework45" />
Run Code Online (Sandbox Code Playgroud)

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


use*_*865 5

所以,我找到了为什么单点登录在 2 个 MVC 应用程序之间不起作用的原因,尽管它们共享相同的机器和验证密钥。

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

我希望这可以帮助遇到这个问题的人。

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

  1. web.config 文件中的相同机器密钥和验证密钥
  2. 相同版本的 OWIN 和 ASP.NET IDENTITY DLL
  3. Startup.cs 中的相同 COOKIE NAME 和 COOKIE 域
  4. 两个应用程序都需要在同一个域中才能共享 auth cookie