Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

automating basic authentication

by cLive ;-) (Prior)
on Sep 13, 2003 at 09:16 UTC ( [id://291226]=perlquestion: print w/replies, xml ) Need Help??

cLive ;-) has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to write a proxy server that will automatically add basic authentication to a request to a particular host. I've been having a play with BooK's HTTP::Proxy, but can't seem to get it to work as expected. Here's the server:

#!/usr/bin/perl use HTTP::Proxy qw(); use strict; use warnings; my $proxy = HTTP::Proxy->new( port => 3128 ); $proxy->push_headers_filter( request => sub { my $headers = shift; # grabbed from http request header of logged in browser $headers->header( Authorization => "BASIC cm9verMSZXZhadDpRHRq +"); }, response => sub { $_[0]->remove_header(qw(WWW-Authenticate)); }, ); $proxy->start;
So far, the proxy server works OK as far as other domains go. But, when I try to connect to the authentication server, I still get the enter password box.

Any suggestions on how to proceed?

I'm not 100% sure I'm doing this the right way either - the docs for the module are quite basic, and I haven't found any tutorials yet on writing proxies.

The above example is for just one password. In reality, there may be a few, and I need to add the correct encrypted password to the request header as appropriate.

Or maybe there's a better way to achieve this? What I need to be able to do is:

  • authenticate users via proxy (probably set a session cookie)
  • when authenticated by the proxy, if a user calls a password protected server in my list, I automatically add Authorization headers to requests, so they get a seamless login and don't have to know passwords (and I can lock them out as needed)
  • only call the push_headers_filter() method if user's sessioncookie is valid and site is on list.

I do not have access to the machine sending the username/password challenges.

Any thoughts or suggestions?

cLive ;-)

Replies are listed 'Best First'.
Re: automating basic authentication
by liz (Monsignor) on Sep 13, 2003 at 10:16 UTC
    The password box is caused by a status code 401 (Authorization Required) if I remember correctly. I don't see you changing the status of the request towards the final client. The client should get a status 200 (OK). No sure how to do that with HTTP::Proxy.

    Hope this helps.

    Liz

Re: automating basic authentication
by bsb (Priest) on Sep 13, 2003 at 10:54 UTC
    Disclaimer: I know nothing about HTTP::Proxy
    Claimer: I know way too much about Basic Authentication (1)

    I'm assuming url credentials like http://username:password@some.host/ aren't relevant.

    LWP's GET -eSUd is a good debugging aid here. It'll show you the basic headers to compare to your own.

    Another idea: put up your own server and watch the requests (or proxy your proxy to see what it's trying to do)

    ---
    (1) I tried to write a module that would fallback to using the basic credentials as a pseudo-cookie if a client had cookies switched off. Many 401's and 30x's later I discovered that it wasn't practically possible if you want to support Mozilla and changing user(IE works though). "wasn't practically possible" is a big call, let's say I couldn't do it.

      The username/password combo is base64 encoded and sent as a line of the request header.

      I'm looking to intercept the request to add this authentication header. I just had the remove header in while playing around with it.

      I guess I just want to see a non trivial example of this module in action.

      .02

      cLive ;-)

Re: automating basic authentication
by BooK (Curate) on Sep 16, 2003 at 14:32 UTC

    What you want to do is to add auto-authentication to a particular web site. I'll talk about how you could do this with the next version of HTTP::Proxy, which will be out someday, when I have more time to work on the remaining details.

    I must admit I haven't read your code that much, and that the old API is a little behind me now, but:

    • You simply have to add a filter that adds the correct WWW-Authenticate: header (you can sniff the connection, for example). You shouldn't receive any 401, since you are authenticated.
    • You should only push this filter for request that you need to authenticate:
      proxy->push_headers_filter( host => 'www\\.example\\.com', # it's a regexp request => sub { my ( $headers, $message ) = @_; $headers->header( Authorization => "Basic cm9verMSZXZhadDpRHRq +" ); } );
    • There is no need for a response filter, if the answer you get is a 200. If you are correctly authenticated by the server, it won't send back a WWW-Authenticate: header.
    • If you send the wrong password, you'll get a 401.
    • Did you try Basic instead of BASIC?
    • A possible application would be a filter that catches WWW-Authenticate: and Authorization: to store/cache authentication information and reuse it for all users.

    In your post you say:

    the docs for the module are quite basic

    I resent that... ;-) In version 0.09, the HTTP/Proxy.pm file is 974 lines long, and there are 303 lines of pod documentation. Please tell me what's missing, so I can improve that in the next version (where 12 new modules will appear).

    Warning: The HTTP::Proxy API will change a lot in version 0.10. It should be much easier to write simple filters, and a lot of helper filters and examples will be included. The latest CVS snapshot is always available from http://http-proxy.mongueurs.net/.

    For those interested, an example proxy is running most of the time on home.bruhat.net:8080. (It's a proxy: you need to configure your browser to use it.)

      "Please tell me what's missing"

      Just some more slightly complicated examples :) I get the general idea, but it would be good to include an example that does quite a bit more based on the request - eg, cookie retrieval and testing and then proceeding based on cookie value etc...

      But thanks for the reply. Much appreciated :)

      cLive ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://291226]
Approved by gmax
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (8)
As of 2024-04-24 10:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found