2014-09-05 49 views
0

我一直在嘗試構建一個概念的本地證明,以將我們當前的解決方案移至不同的URL結構。我使用ASP.NET有3個項目,目前擁有這些URL映射到他們:ASP.NET跨子域Cookie不會附加到請求

mysite.com 
mysite.com/api 
mysite.com/app 

要設置概念證明我在本地已經設置3個站點在IIS與以下網址:

mysite.com 
api.mysite.com 
app.mysite.com 

並增加以下條目到HOSTS文件:

127.0.0.1 mysite.com 
127.0.0.1 app.mysite.com 
127.0.0.1 api.mysite.com 

目前app.mysite.com會談api.mysite.com進行用戶登錄,它返回一個cookie b答覆。問題是該Cookie不存儲在mysite.com下。後續對api.mysite.com的請求沒有在請求頭中附加cookie,因此失敗。

我試驗過設置cookie的domain屬性,但沒有成功,也沒有包含域屬性。

一個cookie的一個例子返回在請求中:

Set-Cookie: MyCookie=somestuff; domain=.mysite.com; expires=Sat, 06-Sep-2014 00:02:04 GMT; path=/; HttpOnly 

然而,cookie被從未連接到任何請求api.mysite.com也不我可以看到它在瀏覽器,Firefox,IE等的瀏覽器的cookie .. 。

請注意,我已啓用web.config中的CORS以啓用跨域請求。

編輯: 在迴應歐恩的回答。我會再澄清一下我目前的設置。

關於<machineKey>我創建了一個machineKey,並在web.config文件中的兩個應用程序上使用了相同的值。在使用mysite.com/apimysite.com/app時,這已經在本地和在生產中工作了,直到我轉向子域時才遇到這個問題。

這裏是我的創建和連接該Cookie代碼:

 private void EncryptAndAttachCookieToHeaders(FormsAuthenticationTicket ticket) 
     { 

      string encryptedTicket = FormsAuthentication.Encrypt(ticket); 

      HttpCookie newCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
      newCookie.Domain = ".mysite.com"; 
      newCookie.Expires = DateTime.Now.AddMonths(3); 
      newCookie.HttpOnly = true; 
      newCookie.Secure = false; 

      System.Web.HttpContext.Current.Response.Cookies.Add(newCookie); 

     // For testing purposes 
     HttpCookie hc = new HttpCookie("cookie1", "value"); 
     hc.Domain = ".mysite.com"; 
     hc.Expires = DateTime.Now.AddMonths(3); 
     HttpContext.Current.Response.Cookies.Add(hc); 

     HttpCookie hd = new HttpCookie("cookie2", "value"); 
     hd.Domain = ".api.mysite.com"; 
     hd.Expires = DateTime.Now.AddMonths(3); 
     HttpContext.Current.Response.Cookies.Add(hd); 

所有這些Cookie(實一加兩個試驗)的觀察中提琴手響應時​​可見。然而,對api.mysite.com的後續請求並非在請求標頭中附加了任何cookie。瀏覽器似乎不想現在已經移動到子域結構中的cookie存儲。

回答

1

要使跨域登錄成功,首先需要編輯web.config中的<machineKey>元素。

默認情況下它是這樣的

<machineKey 
    validationKey="AutoGenerate,IsolateApps" 
    decryptionKey="AutoGenerate,IsolateApps" 
    validation="SHA1" 
    decryption="Auto" /> 

通過這些設置,在.NET框架使用自動生成的validationKey和decrytionKey

默認設置下驗證密鑰和解密密鑰將獲得由ASP生成。NET並將用於身份驗證票證和Cookie,如果您希望多個應用程序共享相同的身份驗證票證和Cookie,則只需將所有應用程序中的validationKey和decrytionKey設置爲相同的值

確保它們是在這兩個應用類似例如

<machineKey 
    validationKey="FBFF3D4EFD359FD58AA480E0A63A9C817463A30EF5AFF4E212AD3321C122AECFFEC427C26D24B67296F5EBBB6A3736BF37A5027718E5426B92C9AC606F9AD66F" 
    decryptionKey="048F8A9F3D6A7D2E88738B36BEEB85FF0B4E23EEF11976D1C0F6F03B91CCFC37" 
    validation="SHA1" 
    decryption="AES" /> 

您可以輕鬆地在該網站上創建一些按鍵相同http://aspnetresources.com/tools/machineKey

爲了使身份驗證cookie在所有其他子域可見,你將需要修改cookie的域屬性。

// Call SetAuthCookie method 
FormsAuthentication.SetAuthCookie("Test account", false); 

//modify the Domain attribute 
System.Web.HttpCookie TestCookie = 
     System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false); 

TestCookie.Domain = "mysite.com"; // (Also try ".mysite.com" i'm unsure about this one) the second level domain name 
Response.AppendCookie(TestCookie); 

這應該是你需要做跨域Cookie的工作

+0

感謝您的回答Owain。我編輯了我的問題以解決您提出的問題。 – 2014-09-05 15:36:52

0

我找到了答案應有盡有。這個問題實際上在於如何形成AJAX請求。我必須添加名爲withCredentials的AJAX屬性以允許瀏覽器發送跨域cookie。這種方法的缺點是,IE 9和老年人不支持它....

從後Setting a cookie on a subdomain from an ajax request

將允許憑據API

Access-Control-Allow-Credentials: true 

使用頭withCredentials爲請求

$.ajax({ 
    url: a_cross_domain_url, 
    xhrFields: { 
     withCredentials: true 
    } 
}); 

否則0無論Access-Control-Allow-Credentials標題如何,都不會發送Cookie。

的訪問控制允許來源

Access-Control-Allow-Origin: http://www.example.com 

通配符*行不通刪除通配符。如果設置了withCredentials,瀏覽器將放棄響應。