Hi,
I would not start with Dancer2::Plugin::Auth::Extensible - it has lots
of stuff you do not need in your use case - but start with an empty
plugin. It's really quite simple, you need just one function (beware,
untested code!):
package Dancer2::Plugin::Auth::SSLVerify;
use strict;
use warnings;
use utf8;
use Dancer2::Plugin;
sub require_ssl_verified {
my $dsl = shift;
my $coderef = shift;
return sub {
my $app = $dsl->app;
my $request = $app->request;
my $session = $app->session;
my $client_verify = $request->env->{'HTTP_SSL_CLIENT_VERIFY'}
// '';
my $username = $request->env->{'HTTP_SSL_CLIENT_S_DN_EMAIL'} // '';
if ($client_verify eq 'SUCCESS' and $username) {
$session->set( logged_in_user => $username );
return $coderef->($dsl);
} else {
return $dsl->redirect( '/not_authorized' ); # or something
}
};
}
register 'require_ssl_verified' => \&require_ssl_verified;
register_plugin;
1;
Then, you can use this plugin in your route definitions:
use Dancer2::Plugin::Auth::SSLVerify;
get '/whatever' => require_ssl_verified sub {
# your route logic here.
};
Hope this helps.
Regards,
Lennart
On 12-11-17 17:09, perlduck wrote:
Hello,
TL;DR
I'd like to write an authentication plugin that behaves like
Dancer2::Plugin::Auth::Extensible but does NOT require a user's
password but instead relies on the SSL variables SSL_CLIENT_VERIFY and
SSL_CLIENT_S_DN_Email.
Background:
I have a Dancer2 application and currently using
Dancer2::Plugin::Auth::Extensible to authenticate my users with
username/password. I'm currently using two providers (realms), Config
and Database. Config is mainly for testing purpose but I like the idea
of multiple realms. I also need the concept of roles, so DPAE is just
great and everything works like a charm.
Now I want to switch to client certificate authentication. I have set
up an Apache as a proxy to the plackup server. Apache handles the SSL
stuff, sets the variables
<Location />
RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
RequestHeader set SSL_CLIENT_S_DN_Email "%{SSL_CLIENT_S_DN_Email}s"
</Location>
and then redirects to my Dancer2 app (at 127.0.0.1:5000).
Within my routes I can access those variables with
my $client_verify = request->env->{'HTTP_SSL_CLIENT_VERIFY'} // '';
my $username = request->env->{'HTTP_SSL_CLIENT_S_DN_EMAIL'} // '';
This works. Apache sets HTTP_SSL_CLIENT_VERIFY to 'SUCCESS' if the
authentication worked. What I now want to achieve is:
IFF $client_verify eq 'SUCCESS' THEN let the user $username in.
Don't show a /login page. Pick the user's details from the database
(or whatever realm(s) is/are configured). Don't show a /logout page.
In short: allow everything what Dancer2::Plugin::Auth::Extensible
allows but without ever asking for a password or redirecting to a
/login page if the two variables are set (and, of course, $username
can be found in the DB).
A very naive first approach was to use a "before" hook to set the
"logged_in_user" value:
hook before => sub {
my $client_verify = request->env->{'HTTP_SSL_CLIENT_VERIFY'} // '';
my $username = request->env->{'HTTP_SSL_CLIENT_S_DN_EMAIL'} // '';
if ($client_verify eq 'SUCCESS' and $username) {
session logged_in_user => $username;
}
};
This seems to work but looks very dirty to me. So I thought I'd better
write a plugin that behaves like a Dancer2::Plugin::Auth::Extensible
plugin but doesn't require a password and rather uses the two
environment variables instead.
Is Dancer2::Plugin::Auth::Extensible even the right place (base) for
such a plugin?
Cheers
_______________________________________________
dancer-users mailing list
dancer-users@dancer.pm
http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
_______________________________________________
dancer-users mailing list
dancer-users@dancer.pm
http://lists.preshweb.co.uk/mailman/listinfo/dancer-users