Forum Discussion
APM authentication User ID changed by application query
Hello all.
I have kind of strange situation that I am trying to sort out, we ahve an existing application that is going to use the APM for authentication but our problem is the existing app has 1000s of users with application specfic Login User IDs that are not associated with our AD server so currently the application looks up the app specfic ID in a database to find the SAM account name then authenticates the user against AD the passwords are the same just the userid is the problem, Is there a way for the APM to replicate this function.
Proposed Application flow
User is directed to the APM for login --> user enters site username and password --> APM needs to send username to server and server will return sam accountname to be used to authenticate against AD --> APM will then take the returned sam account name and user supplied password from the login page and authenticate against AD --> Upon successful AD authentication allow user access to site adding orginal login userid to the header.
Please let me know if this can be accomplished and what would be the best way to accompish this.
thanks in advance,
Jason
6 Replies
- Kevin_Stewart
Employee
The answer is yes, no, and possibly. Yes APM can perform lookups, but no it can't talk directly to a (SQL) database. You can, possibly, still get this to work if you're willing to stand up a web service in front of your database to handle the actual DB querying. In this fashion, APM can perform a sideband call to the web service, mid-policy, and query for the SAM. In any case, most of the authentication agents in the visual policy require the same two session variables: session.logon.last.username and session.logon.last.password. The logon page also produces the same two variables, so between the logon page, the sideband call (via iRule agent), and the AD auth agent, you'll need to store the real username into a separate variable so that the SAM value can be written into the username variable.
Alternatively, if you can store these application account values in the AD user account (via added schema objects) then you can do an AD/LDAP query directly in APM, which would be much simpler. - Jason_41583
Nimbostratus
Thanks Kevin, great suggestion. we got the development team to stand up a web API that will answer with the SAM when sent a GET request with the client username so now I have to figure out the iRule to pull it together hopefully I will get that sorted out today and post the results.
thanks.
Jason - Kevin_Stewart
Employee
How about something like this:when RULE_INIT { enable or disable debug logging set static::rule_debug 1 } when ACCESS_POLICY_AGENT_EVENT { switch [ACCESS::policy agent_id] { "LOOKUP" { set ws server connection (direct or virtual name if load balancing) set server "10.70.0.1:80" establish the connection set conn [connect -timeout 3000 -idle 30 -status conn_status $server] if the conenction fails - log and exit if { $conn eq "" } { if { $static::rule_debug } { log local0. "Sideband WS call failed" } } establish the query parameter (derived from access session data?) set getdata "/samlookup.php?user=ted" establish request string set data "GET $getdata HTTP/1.0\r\n\r\n" send the data set send_info [send -timeout 3000 -status send_status $conn $data] receive the data set recv_data [recv -status recv_status -timeout 30 $conn] close the connection close $conn find the payload after the response headers set payload [findstr $recv_data "\r\n\r\n" 4 " "] create a new access session variable with the paylaod data if { $payload ne "" } { ACCESS::session data set session.custom.sam [string trim $payload] if { $static::rule_debug } { log local0. "payload = $payload" } } } } }
This is a VERY simple example of a sideband call, so you'll likely have to modify to suit your needs. Edit the server, getdata, and data variables for your own environment, and then create an iRule event agent in your APM visual polciy with an ID of "LOOKUP". If it works it'll create a new session variable called session.custom.sam. - Jason_41583
Nimbostratus
Thanks Kevin for all of the help you saved me at least a couple of weeks of trial and error. Below is the iRule that I have which I think is just about right - if you have a second please look it over and let me know if I should change anything.
Thanks again.
Jason
Irule:
when ACCESS_POLICY_AGENT_EVENT {
if { [ACCESS::policy agent_id] eq "change_username" } {
get client login
set SKlogin [ACCESS::session data get "session.logon.last.username"]
open the connection to SK-API
set conn [connect -timeout 100 -idle 30 -status conn_status 192.168.1.99:80]
log local0. "Lookup Log: Connection returns $conn and status $conn_status "
Now request the SamAccountName
!!for prod use real get string!! GET /api/security/GetADUsername?skUsername=$SK-login
set req "GET /$SKlogin HTTP/1.0\r\n\r\nConnection: Close\r\n\r\n"
log local0. "Request is: $req"
set send_info [send -timeout 200 -status send_status $conn $req]
log local0. "Send status is: $send_status"
set recv_data [recv -timeout 200 -status recv_status $conn]
log local0. "Recieve status: $recv_status and data: $recv_data"
close the connection
close $conn
find the payload after the response headers
set SAM [findstr $recv_data "user=" 5 " "]
create a new access session variable with the paylaod data
if { $SAM ne "" } {
Set a SamAccountName session variable to the value 'SAM'
ACCESS::session data set session.temp.username [string trim $SAM]
log local0. "SAM= $SAM"
}
}
} - Kevin_Stewart
Employee
Other than maybe throwing in some catch statements and other error logic, it looks good. - Jason_41583
Nimbostratus
Kevin,
Thanks for all of your help on this, I have one last issue with this deployment the application team wants to use their login page hosted on the server the application is on. Is there a way to call their login page and preform the same lookup ? I tried using the following which needs help but it does not seem to being getting called anyway; any guidance you have is greatly appreciated.
thanks,
Jason
Begin iRULE:
when HTTP_REQUEST {
Check the requested HTTP path
switch -glob [string tolower [HTTP::path]] {
"/api/*" -
"api" -
"/api/" {
Enable APM for these paths
ACCESS::enable
}
default {
Disable APM for all other paths
ACCESS::disable
}
}
Check for post requests to Login URI
if {[HTTP::uri] starts_with "/api/security/Login" && [HTTP::method] eq "GET"}{
Collect up to 1Mb of request content
if { [HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] < 1048577 } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 1048576
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
}
}
when HTTP_REQUEST_DATA {
Parse the username and password from the collected payload
set SKlogin [HTTP::username]
set password [HTTP::password]
HTTP::release
}
when ACCESS_SESSION_STARTED {
if { [ info exists username ] } {
get client login
set SKlogin [ACCESS::session data get "session.logon.last.username"]
open the connection to SK-API
set conn [connect -timeout 100 -idle 30 -status conn_status 172.19.16.100:5538]
log local0. "Lookup Log: Connection returns $conn and status $conn_status "
set req " GET /api/security/GetADUsername?skUsername=$SKlogin HTTP/1.0\r\n\r\nConnection: Close\r\n\r\n"
log local0. "Request is: $req"
set send_info [send -timeout 200 -status send_status $conn $req]
log local0. "Send status is: $send_status"
set recv_data [recv -timeout 200 -status recv_status $conn]
log local0. "Recieve status: $recv_status and data: $recv_data"
close the connection
close $conn
find the payload after the response headers
set SAM [findstr $recv_data "user=" 5 " "]
create a new access session variable with the paylaod data
if { $SAM ne "" } {
Set a SamAccountName session variable to the value 'SAM'
ACCESS::session data set session.temp.username [string trim $SAM]
log local0. "SAM= $SAM"
HTTP::header insert "X-USERNAME" $SAM
}
}
}
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
