简体   繁体   English

ASP.NET跨子域单一登录Cookie

[英]ASP.NET Cross-Sub-Domain Single Sign-On Cookies

I have a Single Sign-on solution which is working great in our test environment. 我有一个单点登录解决方案,在我们的测试环境中效果很好。 It uses Cross-Sub-Domain cookies to share the authentication ticket between 2 web applications. 它使用跨子域cookie在2个Web应用程序之间共享身份验证票证。 Sign-on is done only on one of the applications and on the second site the user is authenticated by the cookie created by the first site. 登录仅在其中一个应用程序上完成,在第二个站点上,用户将通过第一个站点创建的cookie进行身份验证。

The problem is that when I roll it into the production environment the single sign-on no longer works. 问题是,当我将其导入生产环境时,单点登录不再起作用。 I'm looking for any ideas on why this might be. 我正在寻找有关为什么会这样的想法。 More details below: 以下是更多详细信息:

1) Both apps are implemented using ASP.NET MVC2 1)这两个应用程序都是使用ASP.NET MVC2实现的

2) In our test environment both websites are sitting on a single server, with different websites in IIS and host headers used to serve the 2 web applications. 2)在我们的测试环境中,两个网站都位于单个服务器上,IIS中有不同的网站,并且主机标头用于服务2个Web应用程序。 In production the sites are on different servers which are geographically separated. 在生产中,站点位于地理位置不同的不同服务器上。 They use the same sub-domains though. 他们使用相同的子域。

3) Both sites have SSL setup and accessed via https; 3)两个站点都具有SSL设置并可以通过https访问; this is done in both test and production using the same self-signed wild-card certificate. 这是在测试和生产中使用相同的自签名通配符证书完成的。

4) Users login to site1 and then the application automatically retrieves data from site2 using AJAX and JSONP. 4)用户登录到site1,然后应用程序使用AJAX和JSONP从site2自动检索数据。

5) if the sites are site1.example.com and site2.example.com, the following are the important parts of the web.config shared between site1 and site2: 5)如果站点是site1.example.com和site2.example.com,则以下是site1和site2之间共享的web.config的重要部分:

...
<authentication mode="Forms">
  <forms name=".myapp" domain=".example.com" slidingExpiration="true" loginUrl="~/Account/LogOn" timeout="30"/>
</authentication>
...
<machineKey validationKey="KEY1..." decryptionKey="KEY2..."
  validation="SHA1" decryption="AES" />
...

NOTE: One thing I do wonder about the stuff above is, does the authentication ticket get encrypted\\hashed in such a way that it can only be decrypted on the same server? 注意:关于以上内容,我确实想知道的一件事是,身份验证票证是否以只能在同一服务器上解密的方式进行了加密/散列? That would explain my issue; 那可以解释我的问题; but if this is the case how can I ensure that the server for both site1 and site2 can decrypt my authentication cookie? 但是如果是这种情况,我如何确保site1和site2的服务器都可以解密我的身份验证Cookie? KEY1 and KEY2 are both definitely the same on both sites\\servers. KEY1和KEY2在两个站点\\服务器上都绝对相同。

6) On Site1 the Roles the user is in are also inserted into the cookie using the following: 6)在Site1上,用户所在的角色也可以通过以下方式插入到Cookie中:

public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
    {
        if (!ValidateLogOn(userName, password))
        {
            ViewData["rememberMe"] = rememberMe;
            return View(new SiteViewModel(this));
        }

        FormsAuth.SignIn(userName, rememberMe);

        // Add roles to cookie
        string[] roles = Roles.GetRolesForUser(userName);
        HttpCookie cookie = FormsAuthentication.GetAuthCookie(User.Identity.Name, rememberMe);
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
        // Store roles inside the Forms cookie.  
        FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(ticket.Version, userName,
            ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, String.Join("|", roles), ticket.CookiePath);
        cookie.Value = FormsAuthentication.Encrypt(newticket);
        cookie.HttpOnly = false;
        Response.Cookies.Remove(cookie.Name);
        Response.AppendCookie(cookie);

        if (!String.IsNullOrEmpty(returnUrl))
        {
            return Redirect(returnUrl);
        }
        return RedirectToAction("Index", "Home");
    }

7) The roles are restored on Site2 using the following: 7)使用以下方法在Site2上还原角色:

        protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        if (Context.Request.IsAuthenticated)
        {
            FormsIdentity ident = (FormsIdentity)Context.User.Identity;
            string[] arrRoles = ident.Ticket.UserData.Split(new[] { '|' });
            Context.User = new System.Security.Principal.GenericPrincipal(ident, arrRoles);
        }
    }

EDIT: 编辑:

8) This is a printout of the assemblies referenced by the applications on both servers: 8)这是两个服务器上的应用程序引用的程序集的打印输出:

        mscorlib: 2.0.0.0
    System: 2.0.0.0
        System.Configuration: 2.0.0.0
            System.Xml: 2.0.0.0
    System.ComponentModel.DataAnnotations: 3.5.0.0
        System.Core: 3.5.0.0
    System.Data: 2.0.0.0
        System.EnterpriseServices: 2.0.0.0
            System.Transactions: 2.0.0.0
    System.Data.Entity: 3.5.0.0
        System.Runtime.Serialization: 3.0.0.0
            SMDiagnostics: 3.0.0.0
    System.Web: 2.0.0.0
        System.Drawing: 2.0.0.0
        System.Web.RegularExpressions: 2.0.0.0
        System.Web.Services: 2.0.0.0
    System.Web.Abstractions: 3.5.0.0
    System.Web.Extensions: 3.5.0.0
        System.Data.Linq: 3.5.0.0
            System.Xml.Linq: 3.5.0.0
        System.ServiceModel: 3.0.0.0
            System.IdentityModel: 3.0.0.0
        System.ServiceModel.Web: 3.5.0.0
    System.Web.Mvc: 1.0.0.0
        System.Web.Routing: 3.5.0.0
    xVal: 1.0.0.0

Yes. 是。 The encryption is server specific. 加密是特定于服务器的。 Or being more precise relies on the machine key being the same. 或者更精确地依靠相同的机器钥匙

  1. Try and use the same machine key in both web configs . 尝试在两个Web配置中使用相同的机器密钥
  2. If that dosent help. 如果有帮助的话。 Remove encryption and try if works then 删除加密 ,然后尝试工作

If it does not work after removing security/encryption entirely it has nothing todo with incompatible encryption. 如果在完全删除安全性/加密后仍无法使用,则与不兼容的加密无关。 Let us know. 让我们知道

UPDATE This is extracted from our web.config. 更新这是从我们的web.config中提取的。 After removing site specifics of course. 当然删除网站细节之后。 Try to specify everything explicitly, especially the path : 尝试明确指定所有内容,尤其是路径

<forms name=".ASPNET" protection="All" loginUrl="~/Account/LogOn" timeout="2880"
        path="/" domain=".example.com"/>

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

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