[dancer-users] Writing an Auth plugin for SSL client certificates

Lennart Hengstmengel lennart at farenji.net
Mon Nov 13 13:42:24 GMT 2017


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 at dancer.pm
> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>



More information about the dancer-users mailing list