2010-10-28 100 views
2

我有一個單點登錄解決方案,它在我們的測試環境中工作得很好。它使用跨子域cookie在2個Web應用程序之間共享身份驗證票據。僅在其中一個應用程序上進行登錄,而在第二個站點上,用戶通過由第一個站點創建的Cookie進行身份驗證。ASP.NET跨子域單點登錄Cookies

問題是,當我將其轉移到生產環境中時,單一登錄不再起作用。我正在尋找關於爲什麼這可能是任何想法。詳細信息如下:

1)這兩個應用程序使用ASP.NET MVC2

2)在我們的測試環境這兩個網站都坐在一臺服務器上實現,以用於服務於在IIS不同的網站和主機頭2個Web應用程序。在生產中,這些站點位於不同的地理位置上分開的服務器上。不過,他們使用相同的子域。

3)兩個站點都有SSL設置並通過https訪問;這是在測試和生產中使用相同的自簽名通配符證書完成的。

4)用戶登錄到site1,然後應用程序使用AJAX和JSONP自動從site2中檢索數據。

5)如果網站是site1.example.com和site2.example.com,以下是web.config中的1和Site2之間共享的重要組成部分:

... 
<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" /> 
... 

注:有一件事我不知道上面的內容是,認證票證是否被加密\散列方式只能在同一臺服務器上解密?這將解釋我的問題;但如果是這種情況,我如何確保site1和site2的服務器都可以解密我的身份驗證Cookie?兩個站點\服務器上的KEY1和KEY2都是完全相同的。

6)在站點1的用戶在角色使用也插入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)的作用是在站點2恢復使用以下:

 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); 
     } 
    } 

編輯:

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 

回答

4

是的。加密是服務器特定的。或者更精確地依賴於機器密鑰是相同的。

  1. 嘗試和使用相同的機器密鑰在兩個網頁配置
  2. 如果該dosent幫助。 刪除加密和嘗試,如果作品則

如果不刪除安全/加密工作後,完全有不兼容的加密沒什麼待辦事項。讓我們知道。

UPDATE 這是從我們的web.config中提取的。當然,刪除網站的細節。儘量明確指定的一切,尤其是路徑

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

如何使用同一臺機器的關鍵?在我上面的示例web.config中,validationKey和decryptionKey是明確設置的,並且在兩臺服務器上都是相同的。我需要在另一個地方設置另一個關鍵位置還是這些關鍵位置? – mutex 2010-10-28 20:49:04

+0

沒有那個人,只是我沒有仔細觀察。您是否嘗試刪除身份驗證過程的所有加密? – ntziolis 2010-10-28 21:04:59

+0

是的,刪除了所有的加密和東西的工作!非常困惑,爲什麼當密鑰相同時它不能與加密一起工作。它是否將某種特定於服務器的信息添加到組合中? – mutex 2010-10-28 21:17:21