我有一個單點登錄解決方案,它在我們的測試環境中工作得很好。它使用跨子域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
如何使用同一臺機器的關鍵?在我上面的示例web.config中,validationKey和decryptionKey是明確設置的,並且在兩臺服務器上都是相同的。我需要在另一個地方設置另一個關鍵位置還是這些關鍵位置? – mutex 2010-10-28 20:49:04
沒有那個人,只是我沒有仔細觀察。您是否嘗試刪除身份驗證過程的所有加密? – ntziolis 2010-10-28 21:04:59
是的,刪除了所有的加密和東西的工作!非常困惑,爲什麼當密鑰相同時它不能與加密一起工作。它是否將某種特定於服務器的信息添加到組合中? – mutex 2010-10-28 21:17:21