http://socialtext.useperl.at/vienna-pm/index.cgi?hackmeet_am_1_12_2008
Yesteday we met to try to hack on OpenID server that will use pause as authentication mechanism. After initial fights with Git repository (git clone git@git.useperl.at:PAUSE-OpenID) and eating pizza we created 26 commits:
Was nice, was fun. We finished at midnigh. Lot of thinks to be done still. What I've learned?
xhtml is NOT html.(how many times do I have to repeat this to my self?)
WWW::Mechanize knows:
sub is_html { my $self = shift; return defined $self->ct && ($self->ct eq 'text/html'); }
just forget that you'll use it on xhtml documents, without cheating like:
no warnings 'redefine';
sub WWW::Mechanize::is_html {
my $self = shift;
return defined $self->{ct} && (
($self->{ct} eq 'text/html')
|| ($self->{ct} eq 'application/xhtml+xml')
|| ($self->{ct} eq 'application/vnd.wap.xhtml+xml')
);
}
LWP server ssl certificate validation is not so easy
If in the request header an "If-SSL-Cert-Subject" is passed it's validated agains certificate subject if it fails then exception is triggered. Server certificate can be validated but I was not able to generate exception if the validation fails. All there was was an response header $res->headers->{'client-ssl-warning'} but that's too late as the credentials were already send :-( Any way, here is the snipped how to check password against pause or any server with basic authentication:
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'https://pause.perl.org/pause/authenquery');
$req->header('If-SSL-Cert-Subject' => '/CN=pause.perl.org');
local $ENV{HTTPS_CA_DIR} = $c->config->{'ssl'}->{'ca_dir'};
$ua->credentials('pause.perl.org:443', 'PAUSE', $username, $password);
my $res = $ua->request($req);
# but this is bad as the certificate is checked AFTER the credentials are send :-(
die 'pause server certificate validation failed'
if exists $res->headers->{'client-ssl-warning'};
if ($res->code == 200) {
$c->log->info('login pass');
$c->res->redirect($c->uri_for('/login_pass'));
}
else {
$c->log->warn('login failed');
$c->res->redirect($c->uri_for('/login_failed'));
}
OpenID is not so simple
It seems that OpenID is not so simple but looks really nice. Besides having single password for the internet services, it can be used for intranet also to have a single-sign-in.
6h is nothing :-)Well this was just a start. 6h is not a lot. But with a little refactoring there can be username+password abstraction put to a separate module(s) that can be choosed via config file. Then the OpenID server will be not tight just to a PAUSE or http basic authentication. DB or LDAP or ??? can be used to check the credetials having an general OpenID server implementation.