Forum Discussion

bfrancom_123272's avatar
bfrancom_123272
Icon for Nimbostratus rankNimbostratus
Sep 25, 2015

APM Issue Injecting New Authorization Header

I have a policy that uses an Active Directory Authentication, then an Active Directory Query for client authorization. The server side is "dumb." It uses basic auth for authentication. So I inject a new authorization header using variable assign. This allows us to authenticate many users on the client side, while keeping the server side "dumb."

session.logon.last.username = set username "new-username"

session.logon.last.password = set password "new-password"

I have a problem where I need to switch over to LDAP instead of Active Directory. The problem is that even though the

session.logon.last.username
and
session.logon.last.password
get updated, it doesn't pass the new credentials to the back end...it still uses the original credentials.

Why would it work in the case of AD, but not LDAP? Authentication is done at that point, and it just needs to pass the new header to the backend. The logs show the new credentials are present, yet the old ones are still passed.

Here is my LDAP policy:

*Tested on both BIG-IP 11.5.2 Build 1.0.169 Hotfix HF1, and BIG-IP 11.6.0 Build 4.0.420 Hotfix HF4, with the same result.

  • That does not make a lot of sense and might be a bug. But you should be able to use different variables to set username/password and check and see if it works.

     

  • That does not make a lot of sense and might be a bug. But you should be able to use different variables to set username/password and check and see if it works.

     

  • This still seems to be a problem in v.12.1.1. I've also tried insering an iRule just before the "Allow" that says,

    when ACCESS_POLICY_AGENT_EVENT {
        HTTP::header replace username "foo"
    }
    

    Still doesn't seem to override the basic auth from origin.

  • Hi,

     

    this is not a problem with APM, but a configuration issue.

     

    This thread issue was a variable assign issue. yours is ACCESS_POLICY_AGENT_EVENT is not the right event to insert headers.

     

    create a new thread and explain what you want to do, with irule and a screenshot of your VPE to help us understand what's wrong.

     

  • Thanks for the response. I'm the OP author, attempting to do the same thing: Overwrite the authorization header in any way after an

    LDAP Auth
    event. Neither the
    variable assign
    /
    sso mapping
    , nor the
    ACCESS_POLICY_AGENT_EVENT
    seem to be able to do this in my limited experience/perspective. Today I'm going to turn up the logging and try to see what I'm missing. Bear in mind the same config works fine if I change it to
    AD Auth
    as outlined in the OP.

  • Sorry, I did not see the same username...

     

    the AD or LDAP auth does not change the variable assign behavior.

     

    Can you upload screenshots of

     

    • the Basic SSO assign to this access profile
    • variable assign of both access policies
    • SSO Credential mapping of both Access policies
  • No problem. Thanks for helping! The way the initial login is captured is via an iRule. I'm currently running tests with a rest client (postman & ARC)

    when ACCESS_SESSION_STARTED {
        if { [HTTP::password] ne "" } {
        ACCESS::session data set "session.logon.last.username" [string trim [HTTP::username]]
        ACCESS::session data set -secure "session.logon.last.password" [string trim [HTTP::password]]
        }
    }
    

    The variable assign and sso of both policies are the same:

    I can see in the APM log report that the session varibles are updating during the variable assign and SSO mapping, but not being handed to the backend:

  • Hi,

    I think the problem with your configuration is that password was not stored with secure flag.

    If you want to only support Basic authentication for clientside, use the following irule with a Policy that contains Logon page and LDAP Auth:

    when RULE_INIT {
       set static::Basic_Realm_Text "Authentication Required"
       set static::sso(username) "foo"
       set static::sso(password) "bar"
    }
    when HTTP_REQUEST {
        if { ! [ info exists SP_PROFILE_RESTRICT_SINGLE_IP ] } {
            set SP_PROFILE_RESTRICT_SINGLE_IP        [PROFILE::access restrict_to_single_client_ip]
        } 
        if { ( [set sessionid [HTTP::cookie value "MRHSession"]] ne "" ) and ( [ACCESS::session exists -state_allow $sessionid] ) } then {
             Allow the successfully pre authenticated request to pass
            return
        } else {
            if { [ string match -nocase {basic *} [HTTP::header Authorization] ] == 1 } {
                set clientless(insert_mode) 1
                set clientless(src_ip)      [IP::remote_addr]
                set clientless(username)    [ string tolower [HTTP::username] ]
                set clientless(password)    [HTTP::password]
                if { $SP_PROFILE_RESTRICT_SINGLE_IP == 0 } {
                    binary scan [md5 "$clientless(password)"] H* clientless(hash)
                } else {
                    binary scan [md5 "$clientless(password)$clientless(src_ip)"] H* clientless(hash)
                }
                set user_key "$clientless(username).$clientless(hash)"
                set clientless(cookie_list)             [ ACCESS::user getsid $user_key ]
                if { [ llength $clientless(cookie_list) ] != 0 } {
                   set clientless(cookie) [ ACCESS::user getkey [ lindex $clientless(cookie_list) 0 ] ]
                   if { $clientless(cookie) != "" } {
                      HTTP::cookie insert name MRHSession value $clientless(cookie)
                      set clientless(insert_mode) 0
                   }
               }
               if { $clientless(insert_mode) } {
                   HTTP::header insert "clientless-mode" 1
                   HTTP::header insert "username" $clientless(username)
                   HTTP::header insert "password" $clientless(password)
               }
               unset clientless
            }
        }
    }
    
    when ACCESS_SESSION_STARTED {
        if { [ info exists user_key ] } {
            ACCESS::session data set "session.user.uuid" $user_key
        }
    }
    
    when ACCESS_POLICY_COMPLETED {
        if { ([info exists "clientless_mode"]) && ($clientless_mode) && ([ACCESS::policy result] equals "deny") } {
            ACCESS::respond 401 noserver WWW-Authenticate "Basic realm=\"$static::Basic_Realm_Text\"" Connection close
            ACCESS::session remove
        } else    if { ([ACCESS::policy result] equals "allow") } {
            ACCESS::session data set "session.sso.token.last.username" $static::sso(username)
            ACCESS::session data set -secure "session.sso.token.last.password" $static::sso(password)
        }
    }
    

    this irule will manage user basic authentication and SSO credential mapping with dummy username and password.