2013-07-15 72 views
5

我在使用ISAPI篩選器設置多個Cookie時遇到問題。我想將HttpOnly標誌添加到所有Cookie中。如何在ISAPI篩選器中設置多個Cookie

因此,在我第一次嘗試時,我分割了cookie值並添加了HttpOnly標誌,然後我將它們合併爲一個字符串,最後調用pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue),瀏覽器只獲取第一個cookie值。

碼1的嘗試:

cbValue = sizeof(szValue)/sizeof(szValue[0]); 
     if (pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue)) 
     { 
      char szNewValue[MAX_URI_SIZE] = ""; 
      char* token = NULL; 
      char* context = NULL; 
      char delim[] = ","; 

      // szValue format like 
      // "Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly" 
      // After first split 
      // token = "Language=en; expires=Sat" 
      // context = " 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly" 
      token = strtok_s(szValue, delim, &context); 
      while (token != NULL) 
      { 
       strcat_s(szNewValue, token); 
       if (NULL != context) 
       { 
        if (' ' != context[0] && !strstr(token, "HttpOnly")) 
        { 
         strcat_s(szNewValue, "; HttpOnly"); 
        } 

        // context[0] = ' ' means it split the one whole cookie, not an entire cookie, we need append "," 
        // context[0] != '\0' means other cookies after, we need append delimiter "," 
        if (' ' == context[0] || '\0' != context[0]) 
        { 
         strcat_s(szNewValue, ","); 
        } 
       } 
       // NULL, function just re-uses the context after the first read. 
       token = strtok_s(NULL, delim, &context); 
      } 
      if (!pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue)) 
      { 
       // Fail securely - send no cookie! 
       pResponse->SetHeader(pfc,"Set-Cookie:",""); 
      } 

在第二次嘗試,我分裂cookie值,並調用pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue)每一個cookie的,但瀏覽器只得到在這種情況下的最後一塊餅乾。

守則第2次嘗試的:

cbValue = sizeof(szValue)/sizeof(szValue[0]); 
     if (pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue)) 
     { 
      char szNewValue[MAX_URI_SIZE] = ""; 
      char* token = NULL; 
      char* context = NULL; 
      char delim[] = ","; 

      // szValue format like 
      // "Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly" 
      // After first split 
      // token = "Language=en; expires=Sat" 
      // context = " 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly,Language=en; expires=Sat, 15-Jul-2113 02:46:27 GMT; path=/; HttpOnly" 
      token = strtok_s(szValue, delim, &context); 
      while (token != NULL) 
      { 
       strcat_s(szNewValue, token); 
       if (NULL != context) 
       { 
        if (' ' != context[0] && !strstr(token, "HttpOnly")) 
        { 
         strcat_s(szNewValue, "; HttpOnly"); 
        } 

        // context[0] = ' ' means it split the one whole cookie, not an entire cookie, we need append "," 
        // context[0] != '\0' means other cookies after, we need append delimiter "," 
        if (' ' == context[0])// || '\0' != context[0]) 
        { 
         strcat_s(szNewValue, ","); 
        } 
        if (' ' != context[0]) 
        { 
         pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue); 
         strcpy(szNewValue, ""); 
        } 
       } 
       // NULL, function just re-uses the context after the first read. 
       token = strtok_s(NULL, delim, &context); 
      } 

我這樣做是IE10 +的Win2008 R2。在這兩種情況下,結果cookie字符串的格式都是正確的。有沒有人對此有任何線索?

,因爲當你調用GetHeader,您會收到一個逗號分隔字符串的所有cookies,這些問題主要存在。使用SetHeader方法將所有Cookie設置迴響應的最佳方式是什麼?

回答

0

你的第一次嘗試是更好的那麼第二個,因爲您應該只設置一次頭。我認爲你的字符串解析算法有點關閉。我會盡量簡化這一些。首先將每個cookie的頭部分割爲字符串。然後修改cookie以根據需要添加http only屬性,然後將cookie合併回單個標頭。

2

我正在尋找一個解決這個問題,並發現了很多不正確的反應。

這篇文章讓我接觸到了解決方案。

因爲它使用了SetHeader可以爲每個Cookie的原貼的解決方案沒有奏效。 SetHeader在每次調用時會替換「Set-Cookie:」標題,以便只設置最後的Cookie。我沒有使用SetHeader,而是爲每個cookie使用AddHeader。但是,在第一次使用AddHeader之前,我使用SetHeader和「」來清空「Set-Cookie:」標題。

這個工作我使用IIS5.1和IIS7.0

該解決方案適用於ASP會話ID cookie也對。

我知道傳統的ASP是一個古老的技術,但它仍然是在使用中,我們需要這樣的解決方案。

這裏是我的完整代碼:

#include <windows.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <httpfilt.h> 

BOOL WINAPI __stdcall GetFilterVersion(HTTP_FILTER_VERSION *pVer) 
{ 
    pVer->dwFlags = SF_NOTIFY_SEND_RESPONSE | SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT; 

    pVer->dwFilterVersion = HTTP_FILTER_REVISION; 

    strcpy_s(pVer->lpszFilterDesc, sizeof(pVer->lpszFilterDesc), "httpOnly Filter, Version 1.0. JCGalvezV."); 

    return TRUE; 
} 

DWORD WINAPI __stdcall HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD NotificationType, VOID *pvData) 
{ 
    DWORD cbBuffer; 
    char lszBuffer[2000], lszNewBuffer[2000]; 
    HTTP_FILTER_PREPROC_HEADERS *pFPH = (HTTP_FILTER_PREPROC_HEADERS *)pvData; 

    switch (NotificationType) 
    { 
    case SF_NOTIFY_SEND_RESPONSE : 
     cbBuffer = sizeof(lszBuffer); 
     if (pFPH->GetHeader(pfc, "Set-Cookie:", lszBuffer, &cbBuffer)) 
     { 
     char* token = NULL; 
     char* context = NULL; 
     char delim[] = ","; 

     // Delete previous cookies 

     pFPH->SetHeader(pfc, "Set-Cookie:", ""); 

     token = strtok_s(lszBuffer, delim, &context); 
     while (token != NULL) 
     { 
      strcpy_s(lszNewBuffer, sizeof(lszNewBuffer), token); 
      if (!strstr(token, "httpOnly")) 
      strcat_s(lszNewBuffer, sizeof(lszNewBuffer), "; httpOnly"); 

      // AddHeader instead of SetHeader. 

      pFPH->AddHeader(pfc, "Set-Cookie:", lszNewBuffer); 

      // next token 
      token = strtok_s(NULL, delim, &context); 
     } 

     } 
     break; 
    default : 
     break;     
    } 

    return SF_STATUS_REQ_NEXT_NOTIFICATION; 
} 
+0

你應該使用'_countof(lszNewBuffer)'而不是'sizeof(lszNewBuffer)''strcpy_s'和'strcat_s',因爲它需要字符數而不是字節。這裏它的工作原理是因爲兩個字符串都是ANSI都是相等的。 – McX

2

我有同樣的問題,我需要聯繫微軟來解決這個問題。當您收到多個Cookie時,您將收到一個完整的字符串,其中所有的cookie都以逗號分隔。 該工作包括分離每個cookie,然後分別爲每個cookie調用SetHeader方法。

重要的是,每個Cookie必須有一個唯一的名稱 - 值對(http://www.quirksmode.org/js/cookies.html),因此每個變化可以正確映射。

在僞

pResponse->GetHeader(pfc, "Set-Cookie:", szValue, &cbValue) 

// split cookies here 

foreach separated cookie 
    pResponse->SetHeader(pfc, "Set-Cookie:", oneCookie) 

這樣的解決方案,你不需要清洗所有Cookie重新添加。