2012-09-22 23 views
2

我正在做一个项目,需要一个网站和一个移动应用程序,几乎具有相同的功能。 因此,为此,我正在使用Asp.net Web API构建API,这也将用于网站和移动应用程序。多个子域FormsAuthentication无法使用,使用Web API MVC 4

API的地址是:api.domain.com 网站地址是:testing.domain.com

问题:

现在在api.domain.com,我允许用户登录,FormsAuthentication在那里使用Cookies

当用户得到验证它得到200的Http萨特斯的Set-Cookie头,其中允许域也提到了一起。

这里是请求和响应:

**Request** 

Request URL:http://api.domain.com/account/login 
Request Method:POST 
Status Code:200 OK 
Request Headersview source 
Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
Content-Length:139 
Content-Type:application/x-www-form-urlencoded 
Host:api.domain.com 
Origin:http://testing.domain.com 
Referer:http://testing.domain.com/Login.aspx?ReturnUrl=%2fteacherpanel 
User-Agent:Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 
Form Dataview URL encoded 
__VIEWSTATE:/wEPDwUKMTY1NDU2MTA1MmRkmpJ4YQ4kteUpklwLOmcHppPgq/RHqfw7tilyk8pJp0Y= 
UserName:ishan 
Password:pass 





**Response** 

Access-Control-Allow-Headers:Content-Type 
Access-Control-Allow-Methods:PUT, GET, POST, DELETE, OPTIONS 
Access-Control-Allow-Origin:* 
Cache-Control:no-cache 
Content-Length:0 
Date:Sat, 22 Sep 2012 10:23:38 GMT 
Expires:-1 
Pragma:no-cache 
Server:Microsoft-IIS/7.5 
Set-Cookie:.Teacher=A3BD94D26CF733F6F223198ADE40D87C76D8ECC663D7CEDD6E3FF18B0ED23032F6089EF24141E0B65F3F29503A3AC1670C92B9CE4EF7D986974ABE61AB5F0C837245D1A30A8D8E8E058F9AFDD89281CBAB9A3EB98B4A320E689718AF9E76E4911506EBA7FD4244336D8409CFB6D77B179764726B550AB0FFF7A6508658615A57; domain=domain.com, .domain.com; path=/; HttpOnly 
X-AspNet-Version:4.0.30319 
X-Powered-By:ASP.NET 

现在根据回应,浏览器应该这个cookie发送到服务器的每个请求到该域domain.com或其任何子域

但是,这并没有发生,今天早上它怎么会为我工作,但我不知道我做了一个发布后发生了什么。

而且这里更refrence是我使用的设置cookie,并检查用户登录的代码。

这里以用户身份登录,该检查执行中的API,在api.domain.com。

[AllowAnonymous] 
     [HttpPost] 
     public HttpResponseMessage Login(LoginModel model, string returnUrl) 
     { 
      if (ModelState.IsValid) 
      { 
       Teacher t; 
       if (Teacher.Login(model.UserName,model.Password,out t)) 
       { 
        // Roles.AddUserToRole(t.ID.ToString(), "teacher"); 

        FormsAuthentication.SetAuthCookie(t.ID.ToString(), model.RememberMe); 






        FormsAuthenticationTicket ft = new FormsAuthenticationTicket(
        1,         // version 
        t.ID.ToString(), // get username from the form 
        DateTime.Now,      // issue time is now 
        DateTime.Now.AddMinutes(30),   // expires in 10 minutes 
        true,  // cookie is not persistent 
        "teacher"        // role assignment is stored 
         // in userData 
        ); 

        string enTicket = FormsAuthentication.Encrypt(ft); 


        HttpResponseMessage res = Request.CreateResponse(HttpStatusCode.OK); 


        System.Net.Http.Headers.CookieHeaderValue cokie = new System.Net.Http.Headers.CookieHeaderValue(FormsAuthentication.FormsCookieName, enTicket); 
        cokie.Domain = "domain.com .domain.com"; 
        IEnumerable<System.Net.Http.Headers.CookieHeaderValue> cookies = new System.Net.Http.Headers.CookieHeaderValue[] { cokie }; 

        res.Headers.AddCookies(cookies); 


        return res; 

       } 
       return Request.CreateResponse(HttpStatusCode.Unauthorized); 
      } 

      // If we got this far, something failed, redisplay form 
      return Request.CreateResponse(HttpStatusCode.Unauthorized); 
     } 

现在在testing.domain.com,只需根据其角色检查用户身份验证,在web.config中。

<location path="TeacherPanel"> 
    <system.web> 
     <authorization> 
     <allow roles="teacher" /> 
     <deny users="?" /> 
     </authorization> 
    </system.web> 
    </location> 

这些是我发现要检查通过这个问题研究的细节。随意提出任何事情,每一条线索都会有所帮助。在api.domain的web配置

<authentication mode="Forms"> 
     <forms name=".Teacher" loginUrl="Login.aspx" protection="All" path="/" timeout="30" domain=".domain.com" /> 
    </authentication> 

验证部分testing.domain.com的web配置

验证部分。

POST /account/login HTTP/1.1 
Host: api.domain.com 
Connection: keep-alive 
Content-Length: 123 
Origin: http://testing.domain.com 
User-Agent: Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 
Content-Type: application/x-www-form-urlencoded 
Accept: */* 
Referer: http://testing.domain.com/TeacherLogin.aspx?ReturnUrl=%2fteacherpanel 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

__VIEWSTATE:/wEPDwUKMTY1NDU2MTA1MmRkCjMwS9YdCRDD3Qsd4GYnLj+tGGg= 
UserName:username 
Password:pass 

响应由服务器发送:

COM

<authentication mode="Forms"> 
    <forms name=".Teacher" 
    cookieless="UseCookies" 
    requireSSL="false" 
    domain=".domain.com" 
    /> 
</authentication> 

添加机键和添加到期时间的cookie

进行身份验证POST请求通过浏览器后

HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Expires: -1 Server: Microsoft-IIS/7.5 Set-Cookie: .Teacher=9C8FD43FABDC1817D21272361CBF798BB64C364DECC62E2F5F666D1B2A248076C67737D89B03F515D4D81524345584B11E206B2DDEAD5AA846A15BC17B32D86DF1C95A2943766AB5955C99A8DD0D5984089131838E158A90241B60D40A2D928086486E2BA3DDE95814E7FA303845FBDE235D69F54B6891852A09A80F7465FF8C59957A4D; expires=Wed, 26 Sep 2012 10:02:46 GMT; max-age=432000; domain=.domain.com; path=/; secure; httponly X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Access-Control-Allow-Origin: * Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type Date: Tue, 25 Sep 2012 10:02:46 GMT Content-Length: 0 

下获取发送到testing.domain.com测试(因为浏览器不发送Cookie传回服务器,该服务器发生故障)要求:

GET/HTTP/1.1 
Host: testing.domain.com 
Connection: keep-alive 
X-Requested-With: XMLHttpRequest 
User-Agent: Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 
Accept: */* 
Referer: http://testing.domain.com/TeacherLogin.aspx?ReturnUrl=%2fteacherpanel 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

任何猜测为什么浏览器不发送Cookie传回?

+0

您还可以发布web.config的部分吗? API和测试都有web.config吗?如果是这样,你确定机器钥匙匹配吗? – explunit

+0

刚刚添加了部分,但不知道machinekey在哪里可以找到以及在哪里插入? –

+0

添加机器键以回答 – explunit

回答

0

两件事情可能发生在这里:

  1. 如果你没有在这两个API和测试web.config中的machineKey,那么你可能正在使用.NET Framework中的machine.config或继承的设置web.config中。这将为每个应用程序生成不同的密钥,因此一个发布的cookie不能被另一个解密。您应该为每个web.config添加相同的machinekey section。您可以使用众多在线生成器之一,例如this one

  2. 另一个问题是尝试将多个域放入单个Cookie中。更改此行:

    cokie.Domain =“domain.com .domain.com”;

要这样:

cokie.Domain = ".domain.com"; 

其实,看着你的部分,你甚至不需要这条线,因为两者都被设置为.domain.com发出的cookie

编辑:还请检查web.config的httpCookies section以控制是否使用设置的安全标志发送cookie。例如,在开发环境中,您会希望关闭安全标志:

<httpCookies httpOnlyCookies="true" requireSSL="false" /> 

也有forms tag requireSSL property,但我不认为适用于你的情况,因为你是手动发出的cookie。

+0

对不起,这不行! –

+0

刚做了机器关键技巧,但没有工作......问题是,一旦浏览器收到Cookie,它应该发送下一个请求,但在这里它只是不发送它们。 似乎有什么东西是缺少的是停止浏览器发送Cookie与下一个请求。 –

+0

原始问题有请求/响应,但是你可以在代码/配置更改后发布它现在的样子吗?原始响应之后的下一个请求(不发送cookie的那个)? – explunit