Forum Discussion

Joss_100621's avatar
Joss_100621
Icon for Nimbostratus rankNimbostratus
Jul 17, 2010

modify original headers on HTTP:retry

Hi,

 

 

I have two HTTP server pools - webserver and authserver.

 

HTTP requests without a specific cookie ("authcookie") are redirected to authserver pool where they are authenticated.

 

If the request has passed the authentication the authserver will send auth cookie in the 200 response and set a specific header

 

LTM should intercept the 200 response, supress it so it is not sent back to the client and originate a new request to webserver pool copying the auth cookie to the original request from the client.

 

Below is a simplified form I have so far with a couple of questions inline:

 

 

when HTTP_REQUEST {

 

 

if { HTTP::cookie exists "userauth" }

 

{

 

pool webserver

 

LB::select

 

}

 

 

else {

 

set orig_request_headers [HTTP::request]

 

pool authserver

 

LB::select

 

}

 

}

 

 

when HTTP_RESPONSE {

 

if { [HTTP::status] starts_with "200" and HTTP::header exists "userauth"}

 

{

 

set auth_cookie [HTTP::cookie "authcookie"]

 

 

pool vacc

 

LB::select

 

How to add auth_cookie to orig_request_headers?

 

How to supress original 200 coming from authserver and replace it with the 200 with content coming from webserver?

 

HTTP::retry $orig_request_headers

 

}

 

}

 

1 Reply

  • Hi Joss,

    HTTP::retry will trigger a new HTTP_REQUEST event where you can modify the HTTP headers using standard HTTP:: commands. Also, it would make sense to track the auth token values in the LTM session table to ensure a malicious client can't insert any auth cookie value and bypass the authentication scheme. Here's an untested example which does this. If it doesn't work as expected, check the debug output in /var/log/ltm when you test. Once you get it working, you can comment out the debug logging.

    
    when HTTP_REQUEST {
    
        log local0. "[IP::client_addr]:[TCP::client_port]: [HTTP::method] request to [IP::local_addr]:[TCP::local_port] \
            [HTTP::host][HTTP::uri], auth_cookie=[HTTP::cookie "userauth"]"
    
         Track whether to insert the auth pool's auth cookie in responses to the client
           Don't do this by default, unless we've received a successful auth response
        set insert_cookie 0
    
         Track whether to perform auth against the auth pool
           Do this by default, unless we've received a successful auth response
        set do_auth 1
    
         Check if auth was already successful
        if { [HTTP::cookie "userauth"] ne "" }
        {
             Request has a userauth cookie, so check it against the LTM session table
            log local0. "[IP::client_addr]:[TCP::client_port]: Auth cookie present: [HTTP::cookie "userauth"]"
    
    if {[session lookup uie [HTTP::cookie "userauth"]] eq ""}
    {
         Auth token doesn't exist in session table to send request to auth pool
                log local0. "[IP::client_addr]:[TCP::client_port]: Auth cookie not in LTM session table, reauthing."
            }
    else {
         Auth was successful, so use the webserver pool
        log local0. "[IP::client_addr]:[TCP::client_port]: Auth cookie present, using webserver pool"
        set do_auth 0
            }
        }
         Check if auth was already successful and this is an HTTP::retry request
        elseif {[info exists auth_token] and $auth_token ne ""}{
    
            log local0. "[IP::client_addr]:[TCP::client_port]: userauth cookie not present, but auth was just successful"
    set do_auth 0
    
             Insert the authcookie in the request
            HTTP::cookie insert name authcookie value $auth_token
    
     Track that we also need to insert the cookie in the response so the client will present it in 
       subsequent requests
    set insert_cookie 1
        }
        if { $do_auth==1 }
        {
             Need to authenticate request, so use the auth pool
            log local0. "[IP::client_addr]:[TCP::client_port]: Performing auth using authserver pool"
            pool authserver
    
     Save original request headers to retry request against webserver pool if auth succeeds
            set orig_request_headers [HTTP::request]
        }
        else {
             Auth was successful, so use the webserver pool
            log local0. "[IP::client_addr]:[TCP::client_port]: Using webserver pool"
    pool webserver
        }
    }
    
    when HTTP_RESPONSE {
    
        log local0. "[IP::client_addr]:[TCP::client_port]: pool: [LB::server], status: [HTTP::status]"
    
         Check if auth was successful
        if { $do_auth==1 and [HTTP::header exists "userauth"] and [HTTP::status] == 200}
        {
             Save the auth token value from the auth server
            set auth_token [HTTP::cookie "authcookie"]
    
     Add the auth cookie value to the LTM session table with any value using a timeout of 1800 seconds 
      so we can verify the client has a valid auth token on subsequent requests
            session add uie $auth_token 1 1800
    
             Retry the request so we can send it to the server pool
            HTTP::retry $orig_request_headers
        }
        else {
             Unset the auth_token variable to ensure a prior value isn't used for this connection
       Use catch to handle the case where auth_token hasn't been set
            catch {unset auth_token}
    
             Check if we need to insert the auth pool's auth cookie in responses to the client
            if { $insert_cookie==1 }{
                HTTP::cookie insert name authcookie value $auth_token path "/"
            }
        }
    }
    

    Aaron