Forum Discussion

smilanko_261688's avatar
Jul 12, 2016

Clientless mode with 401 and 403

I am attempting to use basic authentication, HTTP 401, in clientless mode with F5. When prompted for username / password through the http client, only valid requests should go forward. Requests with an invalid username / password combo, should redirect to a 403.

This is how my iRule looks like:

when HTTP_REQUEST  {
 insert clientless mode
    set apmsessionid [HTTP::cookie value MRHSession]
    if { [HTTP::cookie exists "MRHSession"] } { set apmstatus [ACCESS::session exists -state_allow $apmsessionid]} else {set apmstatus 0}
    if {!($apmstatus)} {
         Insert Clientless-mode header to start APM in clientless mode
        if { [catch {HTTP::header insert "clientless-mode" 1} ] } {log local0. "[IP::client_addr]:[TCP::client_port] : TCL error on HTTP header insert clientless-mode : URL : [HTTP::host][HTTP::path] - Headers : [HTTP::request]"}
    }
}

when ACCESS_ACL_ALLOWED {
    HTTP::header remove username
    HTTP::header remove domain
    HTTP::header remove roles

    HTTP::header insert username [ACCESS::session data get session.custom.login]
    HTTP::header insert domain [ACCESS::session data get session.custom.domain]
    HTTP::header insert roles [ACCESS::session data get session.custom.roles]
}

when ACCESS_POLICY_COMPLETED {
    Authentication request for non bowser user-agent session denied
   if { ([ACCESS::policy result] equals "deny") } {
      ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"My Web Services Authentication\"" Connection close
      ACCESS::session remove
      return
    } else {
        set allRoles ""
         grab the session data containing the groups associated with the member
        set s [ACCESS::session data get "session.ad.last.attr.memberOf"]
        set matched [split [string map [list {| CN=} \0] $s] \0]
        foreach match $matched {
            if { $match != "" } { 
                puts [string range $match 0 [expr [string first , $match] - 1]]
                set queryarray [split $match ","]
                set firstvalue [lindex $queryarray 0]
                set cleaneddata [string toupper [join $firstvalue _]]
                if { $allRoles eq ""} {
                    append allRoles "ROLE_$cleaneddata"
                } else {
                    append allRoles ",ROLE_$cleaneddata"
                }
            }
        }
        puts $allRoles

         grab the session data containing the username associated with the member
        ACCESS::session data set session.custom.login [ACCESS::session data get "session.logon.last.logonname"]
         grab the session data containing the domaiin associated with the member
        ACCESS::session data set session.custom.domain [ACCESS::session data get "session.ad.last.actualdomain"]
         grab the session data containing the roles associated with the member
        ACCESS::session data set session.custom.roles $allRoles
    }
}

If I set the line:

ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"My Web Services Authentication\"" Connection close

equal to

ACCESS::respond 403

I get a blank page and no initial prompt for the login with an HTTP client.

Here is how my APM looks like:

What am I doing wrong?

2 Replies

  • what are you expecting exactly from a 403? that is a forbidden, not sure if that allows for prompting credentials.

     

    http://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses

     

  • i have tested a similar APM Policy ("HTTP 401 Response" with all default exits) to get at GIT Client with Basic Auth working. The "HTTP Auth Level" is set to Basic but APM always uses the Negotiate exit of "HTTP 401 Response". instead of sending a 401 to the client you can see a 302 to /vdesk/hangup.php3 in fiddler. We are using the debug mode on that DEV Box but the informations are to poor to find a solution.

     

    (12.1 HF1)