Forum Discussion

Adam_S's avatar
Adam_S
Icon for Altostratus rankAltostratus
May 16, 2019

irule response redirect entire host to external website if a loaded resource returns 401

I have a specific usecase here where we have a Tableau Server that has the dreaded /#/ in the url. As a result my tactic is to run an irule on loaded resources to determine if the /getSessionInfo resource is throwing a 401. I know irules apply to each resource at a time so by running a redirect i will only be redirecting the /getSessionInfo resource and not the root domain. here is what I have now. I need a way to use this resource to redirect the host(root domain, host ,client whatever you call the person sitting down at the keyboard) to the domain i show in the HTTP_RESPONSE. please see comments in the code for what i know works and what does not.

 

the script below is currently not redirecting the host but only the resource, i need it to redirect the host.

 

when ACCESS_POLICY_AGENT_EVENT {
  if { [ACCESS::policy agent_id] eq "ga_user_verify" } {
    log local0. "CUSTOM - iRule_ga_user_verify"
    # Get userdata
    set username [ACCESS::session data get session.logon.last.username]
  }
}
 
when HTTP_REQUEST {
  log local0. "MARKER2: [HTTP::uri]"
  set uri [HTTP::uri]
}
 
when HTTP_RESPONSE {  
  if {$uri equals "/vizportal/api/web/v1/getSessionInfo"} {  #this works
    log local0. "MARKER3: $uri"
    if {[HTTP::status] equals "401"} { # this also works
      log local0. "MARKER3: [HTTP::status]"
 
	#this attempt to redirect the host to the following domain does not work
      HTTP::redirect "https://www.example.com/?user=$username"
     # HTTP::respond 307 Location "https://www.example.com"  #this also does not work.
    }
  }
}

 

  • You can try the code below. This iRule needs a virtual server with a stream profile enabled. The iRule will inject some javascript that will check if a redirect is needed. If needed it will do the redirect. You may have to adjust it a bit.

     

    when RULE_INIT {
        # insert custom javascript     
        set static::search_body {</body>}
        set static::replace_body {<script src="/401_redirect.js" defer></script></body>}
      
        # javascript that checks the redirect status every 5 seconds
        set static::script {
            function getStatus() {
                xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", "/401_status.html", true);                  
                xmlhttp.timeout = 200;
                xmlhttp.onreadystatechange = function(){
                    if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                        //console.log("received " + xmlhttp.responseText);
                        if(xmlhttp.responseText == "redirect is needed") {
                            window.location = "/401_redirect";
                        }
                    }
                }
                xmlhttp.send();
            }
            getStatus()
            window.setInterval(getStatus, 5000);
        }
    }
     
    when HTTP_REQUEST {
        # Disable the stream filter by default   
        STREAM::disable 
     
        # LTM does not uncompress response content, so if the server has compression enabled
        # and it cannot be disabled on the server, we can prevent the server from
        # sending a compressed response by removing the compression offerings from the client
        HTTP::header remove "Accept-Encoding"
        
        log local0. "MARKER2: [HTTP::uri]"
        set uri [HTTP::uri]
        
        if { [HTTP::uri] equals "/401_redirect.js" } {
            HTTP::respond 200 content $static::script
        }
        
        if { [HTTP::uri] equals "/401_status.html" } {
            set status [ACCESS::session data get session.custom.redirect.status]
            if { [info exists "status"] && $status == 1 } {
                HTTP::respond 200 content "redirect is needed"
            } 
            else {
                HTTP::respond 200 content "redirect is not needed"
            }
        }
        
        if { [HTTP::uri] equals "/401_redirect" } {
            # redirect will be done in a moment, so set this to 0
            ACCESS::session data set session.custom.redirect.status 0
            
            set username  [ACCESS::session data get session.logon.last.username]
            HTTP::redirect "https://www.example.com/?user=$username"
        }
    }
     
    when HTTP_RESPONSE {   
        # Check if we're rewriting the response
        if { ([HTTP::header value Content-Type] contains "text") } {
            STREAM::expression "@$static::search_body@$static::replace_body@"
                    STREAM::enable
        }
        
        if {$uri equals "/vizportal/api/web/v1/getSessionInfo"} {  #this works
            log local0. "MARKER3: $uri"
            if {[HTTP::status] equals "401"} { # this also works
                log local0. "MARKER3: [HTTP::status]"
                
                # redirect will be needed
                ACCESS::session data set session.custom.redirect.status 1
            }
        }
    }