NAME¶
Catalyst::Authentication::Credential::Remote - Let the webserver (e.g. Apache)
authenticate Catalyst application users
SYNOPSIS¶
# in your MyApp.pm
__PACKAGE__->config(
'Plugin::Authentication' => {
default_realm => 'remoterealm',
realms => {
remoterealm => {
credential => {
class => 'Remote',
allow_regexp => '^(user.*|admin|guest)$',
deny_regexp => 'test',
},
store => {
class => 'Null',
# if you want to have some additional user attributes
# like user roles, user full name etc. you can specify
# here the store where you keep this data
}
},
},
},
);
# in your Controller/Root.pm you can implement "auto-login" in this way
sub begin : Private {
my ( $self, $c ) = @_;
unless ($c->user_exists) {
# authenticate() for this module does not need any user info
# as the username is taken from $c->req->remote_user and
# password is not needed
unless ($c->authenticate( {} )) {
# return 403 forbidden or kick out the user in other way
};
}
}
# or you can implement in any controller an ordinary login action like this
sub login : Global {
my ( $self, $c ) = @_;
$c->authenticate( {} );
}
DESCRIPTION¶
This module allows you to authenticate the users of your Catalyst application on
underlaying webserver. The complete list of authentication method available
via this module depends just on what your webserver (e.g. Apache, IIS,
Lighttpd) is able to handle.
Besides the common methods like HTTP Basic and Digest authentication you can
also use sophisticated ones like so called "integrated
authentication" via NTLM or Kerberos (popular in corporate intranet
applications running in Windows Active Directory environment) or even the SSL
authentication when users authenticate themself using their client SSL
certificates.
The main idea of this module is based on a fact that webserver passes the name
of authenticated user into Catalyst application as REMOTE_USER variable (or in
case of SSL client authentication in other variables like SSL_CLIENT_S_DN on
Apache + mod_ssl) - from this point referenced as WEBUSER. This module simply
takes this value - perfoms some optional checks (see below) - and if
everything is OK the WEBUSER is declared as authenticated on Catalyst level.
In fact this module does not perform any check for password or other
credential; it simply believes the webserver that user was properly
authenticated.
CONFIG¶
class¶
This config item is
REQUIRED.
class is part of the core Catalyst::Plugin::Authentication module, it
contains the class name of the store to be used.
The classname used for Credential. This is part of
Catalyst::Plugin::Authentication and is the method by which
Catalyst::Authentication::Credential::Remote is loaded as the credential
validator. For this module to be used, this must be set to 'Remote'.
source¶
This config item is
OPTIONAL - default is REMOTE_USER.
source contains a name of a variable passed from webserver that contains
the user identification.
Supported values: REMOTE_USER, SSL_CLIENT_*, CERT_*, AUTH_USER
BEWARE: Support for using different variables than REMOTE_USER does not
work properly with Catalyst 5.8004 and before (if you want details see source
code).
Note1: Apache + mod_ssl uses SSL_CLIENT_S_DN, SSL_CLIENT_S_DN_* etc. (has to be
enabled by 'SSLOption +StdEnvVars') or you can also let Apache make a copy of
this value into REMOTE_USER (Apache option 'SSLUserName SSL_CLIENT_S_DN').
Note2: Microsoft IIS uses CERT_SUBJECT, CERT_SERIALNUMBER etc. for storing info
about client authenticated via SSL certificate. AUTH_USER on IIS seems to have
the same value as REMOTE_USER (but there might be some differences I am not
aware of).
deny_regexp¶
This config item is
OPTIONAL - no default value.
deny_regexp contains a regular expression used for check against WEBUSER
(see details below)
allow_regexp¶
This config item is
OPTIONAL - no default value.
deny_regexp contains a regular expression used for check against WEBUSER.
Allow/deny checking of WEBUSER values goes in this way:
1) If
deny_regexp is defined and WEBUSER matches deny_regexp then
authentication FAILS otherwise continues with next step. If deny_regexp is not
defined or is an empty string we skip this step.
2) If
allow_regexp is defined and WEBUSER matches allow_regexp then
authentication PASSES otherwise FAILS. If allow_regexp is not defined or is an
empty string we skip this step.
The order deny-allow is fixed.
cutname_regexp¶
This config item is
OPTIONAL - no default value.
If param
cutname_regexp is specified we try to cut the final usename
passed to Catalyst application as a substring from WEBUSER. This is useful for
example in case of SSL authentication when WEBUSER looks like this 'CN=john,
OU=Unit Name, O=Company, C=CZ' - from this format we can simply cut pure
usename by cutname_regexp set to 'CN=(.*), OU=Unit Name, O=Company, C=CZ'.
Substring is always taken as '$1' regexp substring. If WEBUSER does not match
cutname_regexp at all or if '$1' regexp substring is empty we pass the
original WEBUSER value (without cutting) to Catalyst application.
username_field¶
This config item is
OPTIONAL - default is
username
The key name in the authinfo hash that the user's username is mapped into. This
is useful for using a store which requires a specific unusual field name for
the username. The username is additionally mapped onto the
id key.
METHODS¶
new ( $config, $app, $realm )¶
Instantiate a new Catalyst::Authentication::Credential::Remote object using the
configuration hash provided in $config. In case of invalid value of any
configuration parameter (e.g. invalid regular expression) throws an exception.
authenticate ( $realm, $authinfo )¶
Takes the username form WEBUSER set by webserver, performs additional checks
using optional allow_regexp/deny_regexp configuration params, optionaly takes
substring from WEBUSER and the sets the resulting value as a Catalyst
username.
COMPATIBILITY¶
It is
strongly recommended to use this module with Catalyst 5.80005 and
above as previous versions have some bugs related to $c->engine->env and
do not support $c->req->remote_user.
This module tries some workarounds when it detects an older version and should
work as well.
USING WITH A REVERSE PROXY¶
If you are using a reverse proxy, then the WEBUSER will not be directly
accessible by the Catalyst server. To use remote authentication, you will have
to modify the web server to set a header containing the WEBUSER. You would
then need to modify the PSGI configuration to map the header back to the
WEBUSER variable.
For example, in Apache you would add the configuration
RequestHeader unset X-Forwarded-User
RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule . - [E=RU:%1]
RequestHeader set X-Forwarded-User %{RU}e
You then need to create a Plack::Middleware module to map the header back to the
WEBUSER:
package Plack::Middleware::MyRemote;
use parent qw( Plack::Middleware );
use Plack::Util;
sub call {
my ($self, $env) = @_;
my $user = $env->{HTTP_X_FORWARDED_USER} // "";
$env->{REMOTE_USER} = $user
if ($user && ($user ne '(null)'));
my $res = $self->app->($env);
return $res;
}
1;
Finally, you need to modify
myapp.psgi to use the custom middleware:
use strict;
use warnings;
use MyApp;
use Plack::Builder;
my $app = Drain->apply_default_middlewares(Drain->psgi_app);
builder {
enable "Plack::Middleware::MyRemote";
$app;
};