2013-07-15 18 views
5

Ich hatte ein Problem, mehrere Cookies im ISAPI-Filter festzulegen. Ich möchte die HttpOnly Flagge in allen Cookies hinzufügen.So legen Sie mehrere Cookies im ISAPI-Filter fest

Also, in meinem ersten Versuch, teile ich die Cookies Wert und fügen Sie die HttpOnly Flag, dann kombiniere ich sie in eine Zeichenfolge, aufrufen am Ende, der Browser erhalten nur erste Cookie-Wert.

Code of 1. Versuch:

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:",""); 
      } 

Im zweiten Versuch, spaltete ich die den Cookie-Wert, und rufen Sie pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) für jedes Cookie, aber der Browser nur das letzte Cookie in diesem Fall erhalten.

Code of 2. Versuch:

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); 
      } 

Ich tue dies in IE10 + Win2008 R2. In beiden Fällen haben die Ergebnis-Cookie-Strings das korrekte Format. Hat jemand eine Ahnung davon?

Dieses Problem besteht im Grunde, weil Sie beim Aufruf von GetHeader alle Cookies in einer durch Kommas getrennten Zeichenfolge erhalten. Was wäre die beste Methode, um die SetHeader Methode zu verwenden, um alle Cookies auf die Antwort zurückzusetzen?

Antwort

0

Ihr erster Versuch ist besser als der zweite, da Sie den Header nur einmal setzen sollten. Ich denke, dass Ihr String Parsing-Algorithmus ein wenig aus ist. Ich würde versuchen, dies zu vereinfachen. Teilen Sie zuerst den Header für jeden Cookie in Strings auf. Ändern Sie dann den Cookie, um das http-Only-Attribut nach Bedarf hinzuzufügen, und kombinieren Sie die Cookies dann wieder in einen einzigen Header.

2

Ich suchte nach einer Lösung für dieses Problem und fand viele falsche Antworten.

Dieser Beitrag war, was mich zur Lösung brachte.

Die ursprünglich veröffentlichte Lösung funktionierte nicht, da SetHeader für jeden Cookie verwendet wurde. SetHeader ersetzt den "Set-Cookie:" - Header bei jedem Aufruf, sodass nur das letzte Cookie gesetzt wurde. Anstatt SetHeader zu verwenden, habe ich AddHeader für jeden Cookie verwendet. Aber bevor ich AddHeader zum ersten Mal benutzte, benutzte ich SetHeader mit "", um den "Set-Cookie:" - Header zu leeren. Auch

Dieser arbeitete für mich IIS5.1 und IIS7.0

Diese Lösung funktioniert für ASP Session-ID-Cookie verwenden.

Ich weiß Classic ASP ist eine alte Technologie, aber es ist immer noch in Gebrauch und wir brauchen solche Lösungen.

Hier ist mein kompletter Code:

#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

Sie sollten '_countof (lszNewBuffer) verwenden' statt 'sizeof (lszNewBuffer)' mit 'strcpy_s' und' strcat_s' wie es viele Zeichen muss und nicht Bytes. Hier funktioniert es, weil Boths gleich sind wie Strings ANSI sind. – McX

2

Ich hatte das gleiche Problem und ich musste zur Kontaktaufnahme mit Microsoft dieses Problem zu lösen. Wenn Sie mehrere Cookies erhalten, erhalten Sie eine vollständige Zeichenfolge mit allen durch Kommas getrennten Cookies. Die Arbeit besteht darin, jeden Cookie zu trennen und dann die SetHeader-Methode für jeden separat aufzurufen.

Wichtig ist, dass jedes Cookie ein eindeutiges Name-Wert-Paar (http://www.quirksmode.org/js/cookies.html) haben muss, damit jede Änderung richtig zugeordnet werden kann.

Die Lösung in Pseudo-Code

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

// split cookies here 

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

Auf diese Weise brauchen Sie nicht alle Cookies reinigen sie wieder hinzuzufügen.

Verwandte Themen