2013-07-15 20 views
5

ho affrontato un problema per impostare più cookie nel filtro ISAPI. Voglio aggiungere il flag HttpOnly in tutti i cookie.Come impostare più cookie nel filtro ISAPI

Così, nel mio primo tentativo, ho diviso il valore biscotti e aggiungere il flag HttpOnly, poi li combino in un'unica stringa, invocare pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) alla fine, il browser ottiene solo il primo valore del cookie.

Codice del 1 ° tentativo:

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

Nel secondo tentativo, ho diviso il valore del cookie, e invocare pResponse->SetHeader(pfc, "Set-Cookie:", szNewValue) per ogni biscotto, ma il browser ottiene solo l'ultimo biscotto in questo caso.

Codice di 2 ° tentativo:

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

mi fate questo in IE10 + Win2008 R2. In entrambi i casi, le stringhe dei cookie dei risultati sono nel formato corretto. Qualcuno ha qualche idea su questo?

Questo problema esiste fondamentalmente perché quando si richiama GetHeader, si ricevono tutti i cookie in una stringa delimitata da una virgola. Quale sarebbe il modo migliore per utilizzare il metodo SetHeader per riportare tutti i cookie alla risposta?

risposta

0

Il tuo primo tentativo è migliore del secondo perché dovresti impostare l'intestazione solo una volta. Penso che il tuo algoritmo di analisi delle stringhe sia un po 'fuori. Vorrei provare a semplificare questo. Prima dividi l'intestazione in stringhe per ogni cookie. Quindi modifica il cookie per aggiungere l'attributo http only come necessario, quindi unisci i cookie in un'unica intestazione.

2

ero alla ricerca di una soluzione a questo problema e trovato un sacco di risposte errate.

Questo post è stato quello che mi ha fatto la soluzione.

La soluzione originale pubblicata non funzionava perché utilizzava SetHeader per ogni cookie. SetHeader sostituisce l'intestazione "Set-Cookie:" ogni volta che viene chiamato così è stato impostato solo l'ultimo cookie. Invece di usare SetHeader, quello che ho fatto è stato usare AddHeader per ogni cookie. Ma, prima di usare AddHeader per la prima volta, ho usato SetHeader con "" per "svuotare" l'intestazione "Set-Cookie:".

questo ha lavorato per me utilizzando IIS5.1 e IIS7.0

Questa soluzione funziona per ASP Session ID cookie troppo.

So che ASP classico è una vecchia tecnologia, ma è ancora in uso e abbiamo bisogno di soluzioni come questa.

Ecco il mio codice completo:

#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

Si dovrebbe usare '_countof (lszNewBuffer)' invece di 'sizeof (lszNewBuffer)' con 'strcpy_s' e' strcat_s' in quanto ha bisogno del numero di caratteri e non di byte. Qui funziona perché entrambi sono uguali poiché le stringhe sono ANSI. – McX

2

Ho avuto lo stesso problema e ho bisogno di contattare Microsoft per risolvere questo problema. Quando ricevi più cookie, riceverai una stringa completa con tutti i cookie separati da virgole. Il lavoro consiste nel separare ciascun cookie e quindi chiamare separatamente il metodo SetHeader.

La cosa importante è che ogni cookie deve avere un unico paio nome-valore (http://www.quirksmode.org/js/cookies.html) in modo che ogni cambiamento può essere adeguatamente mappata.

La soluzione in pseudocodice

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

// split cookies here 

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

In questo modo, non hanno bisogno di pulire tutti i cookie per aggiungerli di nuovo.

Problemi correlati