Session or form-based authentication

Session vs. Basic authentication

Pros: Cons:

Features

Requirements

  1. follow the installation documentation
  2. some new Perl modules:
    • CGI::Session (Debian/Ubuntu: apt install libcgi-session-perl)
    • WWW::CSRF (Debian/Ubuntu: apt install libwww-csrf-perl)
  3. two configurations for Apache und WebDAV CGI:
    1. web interface needs a session setup
    2. WebDAV uses another Perl script

Setup recommendations

BackendModPerlsetuid/setgid wrapperRequired CGI scripts/wrappersAuthentication handler
AFSbest performanceUID/GID not usedwebdav.pl and session.plSessionAuthenticationHandler::AfsKerberosAuthHandler
SMBbest performanceUID/GID not usedwebdav.pl and session.plSessionAuthenticationHandler::KerberosAuthHandler
DBBbest performanceUID/GID not usedwebdav.pl and session.plSessionAuthenticationHandler::LdapBindAuthHandler SessionAuthenticationHandler::HtpasswdAuthHandler
FS / GFS / GIT / RCSno effect on wrapped webdav.pl script but usable for session.pl and webdav-susession.plon user-based, group-based, or ACL-based file/folder access rightssession.pl, webdav-susession.pl, webdavwrapper, webdav.plSessionAuthenticationHandler::LdapBindAuthHandler SessionAuthenticationHandler::HtpasswdAuthHandler

Setup

WebDAV CGI

The WebDAV and the web interface setup differ in two aspects: The following setups are additional to the normal WebDAV CGI setup like database, backend, and extension configuration. Hint: You cannot reuse the WebDAV setup for your web interface setup with 'require ...' if you use ModPerl.
WebDAV setup: /etc/webdav.conf:
...

# set this only if you don't use domain based defaults (see defaults in %SESSION domain setup):
$DOCUMENT_ROOT='/myuserpath/'; 
$BACKED = 'FS';

$VIRTUAL_BASE='/webdav/?';

# additional: disable web interface to prevent misuse:
$FANCYINDEXING = 0;
# and redirect the user to the right session login:
$REDIRECT_TO = '/';

# to be sure we have no session setup for the WebDAV access:
undef %SESSION;

...
Web interface setup: /etc/webdav-session.conf:

## reuse webdav.conf because $INSTALL_BASE, $DOCUMENT_ROOT, $BACKEND, $DBI_... are the same:
## but if you use ModPerl, 'require' doesn't work
require '/etc/webdav.conf';

$FANCYINDEXING = 1;
$VIRTUAL_BASE = '/';

%SESSION = (
	## keep it secret like a database password, because it will be used to protect the CSRF token:
	secret => 'YOUR SECRET PASSWORD COMES HERE',

	## if the session timeout is too short, the users cry, if it's to long, admin cries (security!):
	## see manual of CGI::Session for more information 
	expire => '+10m',

	## in seconds - normally, tokens a refreshed with a folder change,
	## but a tokenmaxage is not a session timeout, so it should live longer:
	tokenmaxage => 36000,

	## the tokenname should not be changed unless you know you are doing (avoid clashes with form/post parameters):
	tokenname => 'TOKEN',

	## here comes the path to the session files 
	## (hint: setup a daily cronjob to remove old session files, e.g. find /tmp -name cgisess\* -mtime +1 -delete ) 
	temp => '/tmp',

	## logout_redir defines a URL to an alternate logout page
	## (only for regular logout with logout button [query: ?logout=1])
	## hint: with a multi domain setup it makes sense to redirect to the start path, e.g. logout_redir=>'/?logout=1',
	# logout_redir => undef,

	## a callback module that is called per request 
	# callback => qw( Helper::AdsSmbConfiguratorSessionAdapter ),
	# callback_param => { debug=>1, nameserver=>['8.8.8.8'], memcached=>'127.0.0.1:11211', allowflag=>'webfiles' }, 

	## post configuration file only loaded for logged-in users for every request
	## (same content like webdav.conf but with access to $REMOTE_USER variable for special user-based setups)
	# postconfig => '/etc/webdav-session-post.conf',

	## setuid/setgid wrapper called from session.pl and webdav-susession.pl for logged-in users
	## required for setuid/setgid setups
	# wrapper => '/etc/webdavcgi/cgi-bin/webdavwrapper',
	
	## okay, the domain based authentication:
	domains => {
		## this domain name should be readable for a user if you have more than one:
		'mydomain' => {

			## this is an example, because the TestAuthHandler knows only one user: testuser1 (password: testuser1)
			## (see Authentication handler section for more)
			authhandler => qw( SessionAuthenticationHandler::TestAuthHandler ),

			## handler setup stuff (TestAuthHandler doesn't need it):
			# config => { },

			## this defaults overwrite some webdav.conf defaults:
			# defaults => {
			#	DOCUMENT_ROOT => '/somewhereelse/',
			#	BACKEND => 'GFS',
			# },

			## domain based session timeout overwrites expire from %SESSION:
			# expire => '+10m',

			## a callback module that is called per request 
			# callback => qw( Helper::AdsSmbConfiguratorSessionAdapter ),
			# callback_param => { debug=>1, nameserver=>['8.8.8.8'], memcached=>'127.0.0.1:11211', allowflag=>'webfiles' }, 

			## post configuration file only loaded for logged-in users for every request
			## after the session postconfig (see above)
			## (same content like webdav.conf but with access to $REMOTE_USER variable for special user-based setups)
			# postconfig => '/etc/webdav-session-mydomain-post.conf',

			## this optional _order flag influences the domain selection sort order in the login form:
			# _order => 1,
		},
		## if you have more domains and more than one auth handler for a domain you can do this:
		'myseconddomain' => [
			{
				authhandler => qw ( SessionAuthenticationHandler::LdapBindAuthHandler ),
				config => {
					server => 'myldapserver.mydomain.test',
					basedn => 'dc=mydomain,dc=test',
				},
			},
			{
				authhandler=> qw ( SessionAuthenticationHandler::LdapBindAuthHandler ),
				config => {
					server => 'mysecondldapserver.mydomain.test',
					basedn => 'dc=mydomain,dc=test',
				},
			},
		],
	},
);

# ... and here maybe follows extension setup

Okay, now we need a logout button for the web interface, maybe like this one: /etc/webdavcgi/templates/simple/help.custom.tmpl:
<li class="logout-button" data-href="?logout=1"><div class="label">Logout</div></li>
And if you want to customize the login screen, you should copy the login.tmpl to login.custom.tmpl and edit the custom template:
cp /etc/webdavcgi/templates/simple/login.tmpl /etc/webdavcgi/templates/simple/login.custom.tmpl

Apache

The Apache configuration depends on your needs:
## yes: session.pl handles WebDAV with Basic authentication:
ScriptAlias /_dav /etc/webdavcgi/cgi-bin/session.pl
ScriptAlias /_web /etc/webdavcgi/cgi-bin/webdav.pl

## or for setuid/setgid wrapping:
# ScriptAlias /_web /etc/webdavcgi/cgi-bin/webdav-susession.pl


## ModPerl:
# PerlRequire /etc/webdavcgi/helper/mod_perl_startup.pl

<Location /_>

	Require all granted

	## ModPerl:
	# PerlOptions +SetupEnv
	# PerlResponseHandler ModPerl::RegistryPrefork
	# Options +ExecCGI
</Location>

## WebDAV acccess: it gets its own WEBDAVCONF but the the wrapper needs the web interface setup in SESSIONCONF;
## change E parameter like DOMAIN and REALM as you need;
## when all domains should be checked, omit the DOMAIN env  
# the session.pl needs the session configuration, the webdav.conf,
# and the HTTP header 'Authorization' to handle Basic auth:
RewriteRule /webdav /_dav \
    [PT,L,E=WEBDAVCONF:/etc/webdav.conf,E=SESSIONCONF:/etc/webdav-session.conf,E=DOMAIN:mydomain,E=REALM:WebDAV,E=AUTHHEADER:%{HTTP:Authorization},E=PERLLIB:/etc/webdavcgi/lib/perl]

## you see: WEBDAVCONF differs because this is for the web interface:
RewriteRule / /_web [PT,L,E=WEBDAVCONF:/etc/webdav-session.conf,E=PERLLIB:/etc/webdavcgi/lib/perl]

Authentication handler

LDAP

The LDAP authentication handler requires the Perl module Net::LDAP (Debian/Ubuntu: apt install libnet-ldap-perl). The necessary distinguished name (dn) for LDAP bind authentication can be searched or given by a parameter (userdn).
# this is the default:
authhandler => qw( SessionAuthenticationHandler::LdapBindAuthHandler ),
config => {
    server => 'localhost',

    ## security:
    starttls   => 1,
    sslversion => 'tlsv1_2',
    verify     => 'required',     

    ## faster than search:
    userdn =>  undef,         # usage: 'uid=%s,dc=localhost'
    
    ## for search:  
    basedn    => 'dc=localhost',
    filter    => '(uid=%s)',
    timelimit => 5,
    sizelimit => 5,
    scope     => 'sub',
    binddn    => undef,
    password  => undef,
},

Kerberos

... used for ADS/SMB share access and requires Perl module Env::C (cpan install Env::C).
authhandler => qw( SessionAuthenticationHandler::KerberosAuthHandler ),
config => {
    krb5_config    => undef, # overwrites KRB5CCNAME environment (system default: /etc/krb5.conf)
    ticketfilename => '/tmp/krb5cc_webdavcgi_%s',
    ticketlifetime => 600, ## real ticket lifetime >= ticketlifetime >= expire
  
    log => undef, # log severity: 1:error, 2:warn, 4:info, 8:debug, 15: all; combine severties: add
  
    kinit    => q{kinit '%s' 1>/dev/null 2>&1}, # %s is replaced by username
    kdestroy => q{kdestroy   1>/dev/null 2>&1},  
},

AFS

AFS authentication handles require Perl module AFS::PAG (Debian/Ubuntu: apt install libafs-pag-perl).
authhandler => qw( SessionAuthenticationHandler::AfsKerberosAuthHandler ),
config => {
    ## all options from Kerberos authentication handler and additionally:
    aklog => 'aklog', # path to aklog binary
},

Apache htpasswd (file-based)

Requires Perl module Authen::Htpasswd (Debian/Ubuntu: apt install libauthen-htpasswd-perl)
authhandler => qw( SessionAuthenticationHandler::HtpasswdAuthHandler),
config => {
    htpasswd => '/etc/apache2/users';  # path to user file managed with htpasswd command
},

Maintenance

Cluster

Security

© ZE CMS, Humboldt-Universität zu Berlin | Written 2010-2017 by Daniel Rohde