asp.net - 清除缓存后,set-cookie 不适用于 IE11/10

标签 asp.net authentication cookies asp.net-web-api forms-authentication

我目前遇到的问题是清除缓存/cookie 后 IE10 和 IE11 不会再次设置 cookie。请求和响应看起来几乎相同,但在清除缓存后,即使设置正确,cookie 也不会被传递。

以下是我的登录方法流程:

 1. VerifyLogin()    -> Fail: Go To Login page
                     -> Pass: Call rest of the AJAX Methods // Enter Login Credentials and submit
 2. Authentication() -> Fail: Prompt the user
                     -> Pass: set forms auth cookie and navigate back to original page, where it will call VerifyLogin() again

一旦 Authentication() 通过,他们就应该顺利通过 VerifyLogin() 并继续使用该产品。现在,所有调用都将传递表单例份验证 cookie。

在我看到它失败的实例中,Authentication() 调用通过并获得 200 OK(并且有一个 set-cookie 响应 header )但是,VerifyLogin() 然后失败,因为它没有传递 cookie。

我很难重现这个,但到目前为止我的重现步骤如下。这是从没有运行 IE 的实例开始的。我不是 100% 确定这与我的客户遇到的问题完全相同,但它似乎揭示了他们所看到的相同问题。
  • 启动IE
  • 浏览到站点的索引页面并被退回到登录(验证失败)
  • 使用凭据登录,Authentication() 返回 200 OK 并具有 set-cookie 响应 header 。然后它会引导您并调用通过的 VerifyLogin()。 cookie 在请求中发送,并且全部成功。随后的调用所有工作。
  • 清除我的缓存和 cookie
  • 浏览到该站点的索引页面并跳转到登录(验证失败)
  • 使用凭据登录,Authentication() 返回 200 OK 并具有 set-cookie 响应 header 。然后它会导航您并在此时调用 VerifyLogin() 失败。 cookie 不会在请求中传递,即使它之前已在 Authentication() 的响应中设置。如果我关闭并重新打开 IE,它将再次起作用。

  • 所以,就像第二次 set-cookie 响应只是没有设置 cookie。

    首先,这是我的 web.config 的相关部分以及我如何设置表单 cookie。

    网络配置:
     <authentication mode="Forms">
          <forms enableCrossAppRedirects="true" name="Gator.Express.Auth" timeout="2880" />
        </authentication>
    

    setAuthenticationCookie 方法:
     public void SetAuthenticationCookie(string userName, CookieData cookieData)
            {
                //In order to pickup the settings from config, we create a default cookie and use its values to create a 
                //new one.
                var cookie = FormsAuthentication.GetAuthCookie(userName, true);
                var ticket = FormsAuthentication.Decrypt(cookie.Value);
    
                if (ticket == null)
                    throw new Exception("Error setting authorisation cookie. Decryption of default cookie failed.");
    
                var jsonToken = JsonConvert.SerializeObject(cookieData);
    
                var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration,
                    ticket.IsPersistent, jsonToken, ticket.CookiePath);
                var encTicket = FormsAuthentication.Encrypt(newTicket);
    
                cookie.Value = encTicket;
    
                HttpContext.Current.Response.Cookies.Add(cookie);
            }
    

    现在下面是按顺序排列的请求和响应。

    工作身份验证请求
    POST http://localhost:55733/api/Authentication HTTP/1.1
    Accept: application/json, text/javascript, */*; q=0.01
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Referer: http://localhost:61496/Login.html
    Accept-Language: en-GB
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
    Connection: Keep-Alive
    Content-Length: 35
    DNT: 1
    Host: localhost:55733
    Pragma: no-cache
    
    Username=michaelGator&Password=XXXX
    

    # 有效的身份验证响应
    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    Set-Cookie: Gator.Express.Auth=01020FCCF4658183D208FE0F4CC8BA1385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
    Set-Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:28:39 GMT; path=/; HttpOnly
    X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
    Access-Control-Allow-Origin: http://localhost:61496
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    Access-Control-Allow-Credentials: true
    Date: Fri, 03 Jul 2015 08:28:39 GMT
    Content-Length: 14
    
    "michaelGator"
    

    # 工作验证登录请求
    GET http://localhost:55733/api/VerifyLogin HTTP/1.1
    Referer: http://localhost:61496/
    Accept: */*
    Accept-Language: en-GB
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
    Connection: Keep-Alive
    DNT: 1
    Host: localhost:55733
    Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF
    

    # 工作验证登录响应
    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
    Access-Control-Allow-Origin: http://localhost:61496
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    Access-Control-Allow-Credentials: true
    Date: Fri, 03 Jul 2015 08:28:39 GMT
    Content-Length: 0
    

    下面是一组无效的请求和响应。请注意,Authentication 方法返回 200 OK 和 set-cookie 命令,但在下一次验证登录调用中,cookie 消失了。

    # 身份验证请求 - 按应有的方式返回,但作为非工作请求集的一部分
    POST http://localhost:55733/api/Authentication HTTP/1.1
    Accept: application/json, text/javascript, */*; q=0.01
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Referer: http://localhost:61496/Login.html
    Accept-Language: en-GB
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
    Connection: Keep-Alive
    Content-Length: 35
    DNT: 1
    Host: localhost:55733
    Pragma: no-cache
    
    Username=michaelGator&Password=XXXX
    

    # 身份验证响应- 按原样返回,但作为非工作请求集的一部分
    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    Set-Cookie: Gator.Express.Auth=01022054EB9B8183D208FE20D4BEF01385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
    Set-Cookie: Gator.Express.Auth=01028447109C8183D208FE84C7E3F01385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:30:10 GMT; path=/; HttpOnly
    X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
    Access-Control-Allow-Origin: http://localhost:61496
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    Access-Control-Allow-Credentials: true
    Date: Fri, 03 Jul 2015 08:30:10 GMT
    Content-Length: 14
    
    "michaelGator"
    

    # 非工作验证登录请求 - 注意,没有 cookie 传递
    GET http://localhost:55733/api/VerifyLogin HTTP/1.1
    Referer: http://localhost:61496/
    Accept: */*
    Accept-Language: en-GB
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
    Connection: Keep-Alive
    DNT: 1
    Host: localhost:55733
    

    # 无效的验证登录响应 - 由于没有传递任何表单 Cookie 而失败
    HTTP/1.1 401 Unauthorized
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
    Access-Control-Allow-Origin: http://localhost:61496
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    Access-Control-Allow-Credentials: true
    Date: Fri, 03 Jul 2015 08:30:10 GMT
    Content-Length: 71
    
    {"$id":"1","Message":"Authorization has been denied for this request."}
    

    有人对此有任何想法吗?

    最佳答案

    您似乎获得了两个身份验证 cookie,这表明您的实现与 ASP.Net 试图为您自动化的东西发生冲突。

    有一个 FormsAuthentication.SetAuthCookie 创建和设置cookie,我认为这已经应用了,所以:

  • FormsAuthentication.SetAuthCookie获取 cookie(已在同一响应中设置)。
  • 您的 SetAuthenticationCookie火灾。
  • 这调用 FormsAuthentication.GetAuthCookie并处理(将 JSON 序列化数据嵌入到新的 cookie 中)原始文件。
  • 您调用HttpContext.Current.Response.Cookies.Add创建第二个cookie。
  • 两个 cookie 都在具有相同名称
  • 的 header 中传递

    您尚未清除原始 cookie,并且 .Net 不知道如何处理您处理过的 cookie。

    我认为你有两个选择:
  • 将您的 JSON 数据拆分为具有不同名称的完全独立的 cookie。
  • 从头开始滚动您自己的 cookie,不要使用任何 .Net 的 FormsAuthentication方法。

  • 我个人认为前者是最简单和最快的实现方式。

    尝试使用 cookie 名称可能也值得 - 我不确定所有浏览器都支持 cookie 名称中的句点,但它们都区分大小写。

    最后还有其他值得检查的东西 - 几乎是 never worth setting a cookie's path in .Net , 因为 IIS 将 URL 视为不区分大小写,但浏览器都将 cookie 名称视为区分大小写。

    关于asp.net - 清除缓存后,set-cookie 不适用于 IE11/10,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31204531/

    相关文章:

    asp.net - 在抛出 "A potentially dangerous Request.Path value was detected from the client"之前,ASP.NET 页面生命周期中是否存在任何位置

    c# - __doPostBack 在 Firefox 中不起作用

    asp.net - 我怎样才能把它变成一个div

    authentication - Jenkins - j_acegi_security_check

    cookies - 如何在 "laravel"中设置没有响应的cookie

    android - 带有 cookie 的 HttpPost 请求

    javascript - 使用 Javascript 在文本框中显示消息

    javascript - 类型错误 : Cannot read property 'replace' of undefined - VueJS

    session 中的 PHP 登录系统问题!

    PHP cURL 登录 facebook