Forum Moderators: phranque

Message Too Old, No Replies

weird issue with authentication and location directives

auth location

         

infinitiguy

4:26 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



Hi,
I'm having a strange issue with passing a username and password within a URL to a location protected uri.

If I do [username:password@domain.com...] I get prompted about a dozen times (for various images/components within the webapp). If I type in the username and password all of those times, it eventually completes.

However if I just hit [domain.com...] and login with the same username and password the normal way, I am only prompted once.

Why is there a difference, and is there a way to resolve that?

infinitiguy

6:10 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



a bit of an update here... it actually looks like this works fine in google chrome... meaning I can provide [username:password@domain.com...] in an incognito browser session and it just sends me on through, but [username:password@domain.com...] in firefox prompts me for a login 3 times!

So, that tells me that there's a configuration setting in firefox that I could maybe hopefully change. Any ideas anyone?

sublime1

9:42 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



infiniteguy --

I think you'll find the support for adding username and password in this form as part of URL is spotty, and especially ugly especially when used in an https context (I think it's still basic authentication) -- it's the most clear-text way of passing (and recording in the logs!) a userid and password known to man, so looked upon as ... undesirable.

Chances are that what's happening is that the first request (to the page URL) is returning and remembering your authentication using a cookie. Requests for other assets (images, css, javascript) are made without the auth info, asynchronously and may not yet have access to the authenticated information from the cookie. Browsers can vary widely in how they handle this. Another possibility is that the browser is "pre-fetching" stuff it might need -- not sure about this one. Check out Live HTTP Headers FF plugin -- it's awesome and will show you exactly what's going back and forth over the wire, headers and all. Don't know if there's a similar Chrome extension.

So I guess my bigger question is: is there no other way you can accomplish your goal than passing auth information as part of the URL? I had tried to do this for a scripting task a while back (with wget or curl or something) and it turned out that at some point, some component wasn't happy using this method, and I needed to implement the two-step authentication anyway.

Tom

infinitiguy

9:55 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



The reason for it is running a test using selenium with monitoring to ensure an application is up, and serving valid content by doing a little user emulation of clicking pages/searching for words. Passing the uname and pass is seleniums answer for dealing with basic auth. I'm not concerned about security as it's only going to be on an internal server, that is highly protected in terms of who has access to it.

Firebug shows exactly what is happening. Other assets, just as you suspected (images, css) are responding with a 401 status code requiring auth. If I provide credentials again, they continue on their merry way. What is strange to me is why logging in the normal way, works perfectly fine. What is being set differently when not providing the credentials as part of the url? Also, once I fully authenticate, passing another request using uname:password@domain works fine and never prompts for additional auth (presumably because it already has cached all it needs). Closing the browser nicely puts me back to square one.

sublime1

12:35 am on Oct 7, 2010 (gmt 0)

10+ Year Member



OK, I'll dismount my high horse on the security thing :-)

I'll guess the reason it behaves differently is a matter of timing.

A normal basic auth login is a two step process: first request is met with a "401" response from the server, saying "I need authentication", also returning some information about the "Realm" and probably other stuff. Once the user provides credentials, they are sent in a cookie that the server reads, accepts, and returns with a cookie that is valid for subsequent requests to the domain for some time (set by the server according to configuration) or the end of the browser session, whichever comes first. The key is that the first response establishes a cookie. (Again, this is a combination of what happens in the protocol, combined with my wild guess as to how it's actually implemented by the browser)

My guess is that in the case of passing the credentials in the URL, the authentication is effectively instantaneous; the server immediately sends back an authorized response (one containing the Set-cookie header that would have been returns in the 401 response normally) and the browser renders the page which, in turn causes all the requests to the assets to start firing off back to the server. All of this happens in a split-second, and potentially fast enough that the cookie is not saved by the browser before all those image requests get fired off.

This theory or some variants of it are confirmed by the fact that closing the browser (ending the session, thereby deleting the session cookie) creates a need to re-authenticate.

Check out Live HTTP Headers in firefox -- it will show you exactly what's going back and forth. I would bet that (as per your original question) there's some setting that allows you to change how FF handles this. If you're doing a Greasemonkey script or something you could probably make the setting at the beginning, and restore at the end or on an exception. In other words, I don't know the answer to your question, but I'll bet I am close in terms of understanding why :-)

Tom

jdMorgan

1:28 am on Oct 7, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I concur with the above "instantaneous auth" analysis, except that the auth info, while resembling a cookie in provenance and usage-per-request, isn't a cookie -- it's a auth header.

Jim

sublime1

1:36 am on Oct 7, 2010 (gmt 0)

10+ Year Member



Jim --

That cookie part was just a test to see if you were paying attention :-)

Once again, you put the rest of us schmoes to shame.

Tom

infinitiguy

1:46 am on Oct 7, 2010 (gmt 0)

10+ Year Member



so, from the sounds of it I may need to wrap this thing in some sort of additional script to slow it down.

So the reason why we suspect it works through a normal prompt is apache gets the request for authorization.. waits for my input, and when I input it has time to fully populate my auth into an auth header before loading the rest of the page... whereas the other way around, the authheader is not completed before the page loads and then causes additional requests for authorization? My only question is... sometimes I am prompted 2 or 3 times (depending on the number of objects in a particular application). Is this variance due to the whole page loading before the auth_header and therefore all those requests get queued up and won't auth at all except for manual intervention?

Just wanted to make sure I understood it all :) Other applications we have work fine, but I suspect they may have been designed better than this one?

sublime1

2:00 am on Oct 7, 2010 (gmt 0)

10+ Year Member



Live HTTP Headers (and other tools -- maybe PageSpeed?) can tell you what's happening in what order. If the result is deterministic (same thing happens every time, in the same order), then that might lead you one direction. If things don't always happen the same, that suggests some sort of async processing, which would lead you in a different direction.

I am mostly guessing still, but if this is a test, you might consider trying to replicate reality more closely, that is, push the un-authenticated request out there, respond (in your browser script) to the 401 as user would -- most likely this would work. I am out of my league with further speculation, especially insofar as it seems to be different depending on browser.

Tom

infinitiguy

3:27 am on Oct 7, 2010 (gmt 0)

10+ Year Member



This is a weird one. I'll play around with live http headers.. my first pass through shows me exactly what we kind of determined already, and is what I saw in firebug earlier.. (many objects wanting authentication).. It does appear that all of the 401's get sent sort of async because the headers stopped and I had 2 remaining authentications to get through, while the rest of the page continued to load..

strange indeed...

jdMorgan

2:53 pm on Oct 7, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It's not strange. It has to do with the "state machine" behind authentication/authorization.

With the "login-page" auth, no on-page objects are requested because the browser is looking at the "please log in" page, not the actual page that was being requested. After the auth state is completed sucessfully, the credentials accepted by the server are then sent with another request for the "real page" and as that page is loaded, the credentials are also sent along with each request for the included on-page objects.

But with the "auth-in-URL" method, the initial page seen by the browser is the "real" page, and none of the included-object links on that "real page" contain the auth-string, and since the server has not yet accepted the auth, it sends a re-authorization request in response to each included-object request.

In order for the auth-in-URL method to work, all on-page links would have to include the username and password string. So you'd have to link to <img src="https://username:password@www.domain.com/logo.gif"> to allow the browser to successfully request and load the on-page logo graphic, for example.

Apparently, Chrome is detecting that you're trying to use the "auth-in-URL" method, and is modifying this into a standard login-page request somehow. Or it is prepending the auth-info from the requested page URL to the requested-object URLs -- likely specified as page- or server-relative links. However, this is not being done by the other browsers you're testing, accounting for the different test results you're seeing between browsers.

Because this auth-in-URL method is so insecure, I doubt that there will be much interest in supporting it within the browser development community. So if you continue to use it, then you may be stuck with a "Chrome-only" test environment -- or in this case, a Chrome-only "test-of-test" environment. :)

Jim

[edited by: jdMorgan at 3:25 pm (utc) on Oct 7, 2010]

infinitiguy

3:06 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



that's what I was figuring :) Selenium I guess has a way to write wrapper scripts to get tests to play in other browsers. It's a lot more involved than I was hoping to get into with this.. was wishing for a simple "this just works" solution, but alas... :)

Thanks for the explanation. It really helps to understand the reasons why this is happening :)

sublime1

3:45 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



was wishing for a simple "this just works" solution


Ha! This is why us computer pros get paid the big bucks -- if it were too easy, any old joe could do it :-)

May the force be with you.