Forum Discussion
erik_howl_25558
Nimbostratus
Mar 27, 2007HTTP Authentication
Dear all,
Can LTM use irules to perform HTTP authentication based on local .htaccess / .htpasswd (like in Apache)?
Many thanks.
7 Replies
- Colin_Walker_12Historic F5 AccountI know there have been several people who have used iRules to offload authentication, even HTTP auth, but iRules won't be able to read any information stored on the Webserver's filesystem. If you wanted to store the valid usernames/passwords on the BIG-IP, or in some authentication resource like an LDAP server, there are profiles to allow for the offloading of auth that way.
Colin - Mike_Dahlgren_1
Nimbostratus
I am in a situation where we have websites that are not sensitive but policy requires a password to be placed on them. I was wondering if you could point me in the right direction to writing an iRule that could prompt for a username and password and compare them to something like the string "test" Not secure, but easy.
Having looked through many of the other authentication systems I haven't been able to use any of them since I don't have a license for that component, and I would like to do without the complexity. Any help would be greatly appreciated! - hoolio
Cirrostratus
You can check the wikipedia page (Click here) for details on basic HTTP auth. You could use a rule to check for the authorization header, split the header value, base64 decode the user:pass and verify it's in an allowed list. If not, send back a 401 response.
If it's just one user:pass that you need to support, you could base64 encode the value and check for that rather than base64 decoding every value in the request. If you have multiple logins, you could add them to a datagroup.
Example request with an authorization header:
GET /private/index.html HTTP/1.0
Host: localhost
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Here is an untested example:when RULE_INIT { Set the single username and password here delimited with a colon set ::global_user_pass "testuser:testpass" Base64 encode the user:pass set ::global_user_pass [b64encode $::global_user_pass] log local0. "Encoded \$::global_user_pass: $::global_user_pass " } when HTTP_REQUEST { log local0. "[IP::client_addr]:[TCP::client_port]: New HTTP request to \ [HTTP::host][HTTP::uri] with auth value: [HTTP::header value Authorization]" Check if there is an authorization header with a length if {[string length [HTTP::header value "Authorization"]]}{ Get the second field from the header value set encoded_user_pass [getfield [HTTP::header value "Authorization"] " " 2] log local0. "[IP::client_addr]:[TCP::client_port]: Parsed Authorization value $encoded_user_pass" Check the encoded user:pass from the request against the global user:pass if {$encoded_user_pass eq $::global_user_pass}{ Credentials were okay, so exit this rule (don't send a 401 response log local0. "[IP::client_addr]:[TCP::client_port]: credentials were valid." return } } If we got here, the request didn't contain a valid user:pass, so send a 401 response to prompt user for credentials. The format for HTTP::respond is the content and then space delimited header name followed by the header value HTTP::respond 401 content { "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> Error 401 Unauthorised. } WWW-Authenticate "Basic realm=\"Secure Area\"" log local0. "[IP::client_addr]:[TCP::client_port]: Sending 401 response." }
Once you're done testing, you could remove the intermediate variable, $encoded_user_pass and disable the logging.
Aaron - Mike_Dahlgren_1
Nimbostratus
Aaron,
Thank you very much for your for your solution and your prompt reply. Everything works perfectly.
Thanks,
~ Mike - bikmaek_9916
Nimbostratus
Thank you very much for this iRule - exactly what I need
bikmaek - bikmaek_9916
Nimbostratus
Hello there,
I want to make this iRule more dynamic. So I insert a new META-Tag:HTTP::respond 401 content { "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> Redirect 401 Unauthorised. } WWW-Authenticate "Basic realm=\"Secure Area\""
But now I want to change the "URL" with "[HTTP::host]". I try to do this since hours but it doesn't work.
Perhaps someone has an idea.
bikmaek - hoolio
Cirrostratus
If you use curly braces { } to include the HTML, you don't have to escape the single quotes within the HTML. But the curly braces also prevent expansion of variables. If you replace the curly braces with double quotes, then you can include commands like HTTP::host. But you have to escape the double quotes in the HTML:
HTTP::respond 401 content " ... "
Aaron
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects
