Pubcookie: Single Authentication Point for Web Applications
There are many solutions that allow one way or another to implement the technology of single sign-on (Single Sign On). Single sign-on refers to the situation when you log in once on some dedicated authorization server (or just on your machine), you get access to all available network resources without additional authorization.
We are now gradually refactoring our internal intranet services, which have often developed spontaneously, and are considering various technologies, the use of which can make our internal infrastructure more convenient and safer.
SSO technologies, as a rule, are rather complicated, however, if we restrict ourselves to the task of single sign-on only for a set of web applications, there is a relatively simple solution that allows you to realize this opportunity without changing or slightly changing the application code. This solution is called Pubcookie , and it will be discussed.
If we use Pubcookie, then when we enter a protected resource, we will automatically be redirected to a special dedicated login server, on which we log in and automatically go back. At the same time, we do not need to change anything in the protected application; it, as before, gets the name of the current user from
Let's see how you can configure this mechanism.
Scheme of work
The following components are involved in the authentication process:
Authentication is as follows:
If in step 4 the granting request also contains a valid login cookie (set in step 8), steps 5, 6 and 7 are skipped and the login server goes directly to step 8, generating a granting cookie using the username obtained from the login cookie. Thus, we get an element of Single Sign On technology for a set of web applications: you do not need to log in for each web application, just enter your username and password once.
Assembly
We will consider for Ubuntu, under FreeBSD it also does not cause problems:
Download the distribution kit from www.pubcookie.org . Before assembling, we make two patches:
1. The configure patch for a problem with APXS:
Here, by hammering, you can probably do it more correctly.
2. Patch src / index.cgi.c for UTF-8 encoding:
When configuring, specify the assembly of the module and cgi-application to enter:
Then we collect, preferably in a deb package.
Key and certificate generation
. Https is used to work with protected resources. Well, that's why they are protected.
We generate two pairs of keys.
The first is the SSL key pair, used by the apache for SSL and the key server (about it below):
The second is the granting key pair, for signing and checking granting cookies: The
example is purely demo, we use self-signed certificates, in reality it’s more complicated. Accordingly, we generate a toy CA bundle:
As a result, we get the files: server.crt, server.key, granting.crt, granting.key, ca-bundle.crt.
Setting up the login server.
Let the server be called access.techart.intranet.
The key server and the authentication application running the web server are running on the access server.
The key server distributes symmetric keys used to encrypt the contents of the cookies. It runs under xinetd, respectively, we prescribe it there:
After restarting xinetd, the server is available on port 2222.
The authentication application is a regular CGI application that must be accessible via https. Accordingly, for it it is necessary to configure virtual host: It remains to configure pubcookie. Edit the file / usr / local / pubcookie / config:
In this example, we use verify_fork mode when an arbitrary external program is used as the authentication service, returning a normal or erroneous termination code depending on whether the user was identified. In this case, the program reads the username and password from stdin.
In our case, this is a php script that can, for example, access a database or a text file, while other modes are supported, for example, working with LDAP and Kerberos.
Now we generate a key that allows the login server to connect to the key server:
The generated key will be written to
After performing all these manipulations at access.techart.intranetwe should see the login form.
Setting up the application server.
On the application server, we configure the pubcookie configuration file in the same way as on the access server. In addition, you need to connect the mod_pubcookie module to Apache.
To do this, create a file
Then everything is as usual:
Now we configure the application itself: In this case, we closed access to the entire application, however we could prescribe authentication options for a specific subdirectory, put them in , etc. Setting this option allows the application to get the name of the current user from REMOTE_USER. We restart Apache, and if everything went fine, then when you go to app1.techart.intranet
we should be redirected to login.techart.intranet , where we log in and automatically return.
Virtual hosts
All of the above works for virtual hosts tied to a dedicated IP. To work with name-based virtual hosts, SNI support is required in OpenSSL, (since version 0.9.8j) and in Apache (since 2.2.12). In addition, SNI is not supported on IE versions lower than 7.
For this configuration, the Common Name field should contain a list of hosts used. Edit openssl.cnf and regenerate the key set.
In the description of the virtual host in Apache, we write:
and restart apache.
Configure access server user interface
The appearance of the login form and service pages of the login server can be configured using the templates that are in the login_templates directory. To use UTF-8 you need to patch
Configuring logout
Closing a session can be performed both in a separate application and on a login server. The easiest way to do this on the login server is to create a subdirectory
Total.
In general, the mechanism is quite simple, the main difficulty in setting up is not so much with Pubcookie as with OpenSSL.
Accordingly, in the case of implementation, the most important thing is to correctly configure the basic key / certificate management infrastructure.
At the same time, in a situation where there are a lot of legacy applications on the intranet, using Pubcookie allows you to implement centralized access control for them with minimal effort.
A few links:
We are now gradually refactoring our internal intranet services, which have often developed spontaneously, and are considering various technologies, the use of which can make our internal infrastructure more convenient and safer.
SSO technologies, as a rule, are rather complicated, however, if we restrict ourselves to the task of single sign-on only for a set of web applications, there is a relatively simple solution that allows you to realize this opportunity without changing or slightly changing the application code. This solution is called Pubcookie , and it will be discussed.
If we use Pubcookie, then when we enter a protected resource, we will automatically be redirected to a special dedicated login server, on which we log in and automatically go back. At the same time, we do not need to change anything in the protected application; it, as before, gets the name of the current user from
REMOTE_USER
. Let's see how you can configure this mechanism.
Scheme of work
The following components are involved in the authentication process:
- Client browser
- An application server on which an application requiring authentication is deployed, in our case Apache with the Pubookie module and, in fact, the protected application;
- The login server, in our case, is again Apache with a standard authentication application and our settings for this application;
- Actually, the authentication service.
Authentication is as follows:
- A custom browser requests a specific resource from an application server configured to use Pubcookie.
- The Pubcookie module installed on the application server intercepts the request and verifies that it is not connected to a valid current session and does not contain information from the login server (the so-called granting cookie) to create a new session.
Upon successful verification, the module generates a response containing a redirect and two cookies: a presession cookie for the application and a granting request cookie for the login server. Both cookies contain, among other information, a random number generated by the module. All cookies are encrypted. - The client browser performs a redirect (granting request) to the login server with a granting request cookie. The request data allows the access server to determine the application server for which authentication is requested, the URL of the original request, the type of authorization, etc.
- The login server decodes the granting request cookie and interprets the contents. The server generates a login form and sends it to the client.
- The user enters their username and password into the form and sends it to the login server;
- The login server receives the username and password and sends them to the authentication service used for verification.
- The login server receives the verification result from the authentication service.
- If the verification is successful, the login server generates a response containing a redirect and two new cookies. The first, a granting cookie, is for an application server and contains a verified username and additional information, including the random number generated in step 2, signed by the private key of the access server and encrypted with the symmetric key used on the application server and access server. The second, login cookie, is intended for the login server and is used in case of subsequent visits of the user to it.
- The user browser re-requests the protected resource from the application server. The request contains a granting cookie and a presession cookie.
- The pubcookie module on the application server intercepts the request, decrypts the granting cookie, verifies the signature, and compares the random number in the granting cookie with the same number in the presession cookie. If everything converges, the username is passed to the application and the application processes the request. A session cookie is also generated for subsequent access to protected resources. The response generated by the application is sent to the user.
If in step 4 the granting request also contains a valid login cookie (set in step 8), steps 5, 6 and 7 are skipped and the login server goes directly to step 8, generating a granting cookie using the username obtained from the login cookie. Thus, we get an element of Single Sign On technology for a set of web applications: you do not need to log in for each web application, just enter your username and password once.
Assembly
We will consider for Ubuntu, under FreeBSD it also does not cause problems:
Download the distribution kit from www.pubcookie.org . Before assembling, we make two patches:
1. The configure patch for a problem with APXS:
3783c3783
< APACHE_PREFIX=`$APXS -q PREFIX`
---
> APACHE_PREFIX="/usr/share/apache2"
Here, by hammering, you can probably do it more correctly.
2. Patch src / index.cgi.c for UTF-8 encoding:
461c461
< print_header (p, "Content-Type: text/html; charset=ISO-8859-1\n");
---
> print_header (p, "Content-Type: text/html; charset=utf-8\n");
When configuring, specify the assembly of the module and cgi-application to enter:
$./configure --enable-apache --with-apxs=/usr/bin/apxs2 --enable-login
Then we collect, preferably in a deb package.
Key and certificate generation
. Https is used to work with protected resources. Well, that's why they are protected.
We generate two pairs of keys.
The first is the SSL key pair, used by the apache for SSL and the key server (about it below):
$ openssl req -new -x509 -out server.crt -newkey rsa:1024 -nodes -keyout server.key
The second is the granting key pair, for signing and checking granting cookies: The
$ openssl req -new -x509 -out granting.crt -newkey rsa:1024 -nodes -keyout granting.key
example is purely demo, we use self-signed certificates, in reality it’s more complicated. Accordingly, we generate a toy CA bundle:
$ cp server.crt ca-bundle.crt
As a result, we get the files: server.crt, server.key, granting.crt, granting.key, ca-bundle.crt.
Setting up the login server.
Let the server be called access.techart.intranet.
The key server and the authentication application running the web server are running on the access server.
The key server distributes symmetric keys used to encrypt the contents of the cookies. It runs under xinetd, respectively, we prescribe it there:
service keyserver
{
type = UNLISTED
protocol = tcp
port = 2222
disable = no
socket_type = stream
wait = no
user = root
group = tty
server = /usr/local/pubcookie/keyserver
}
After restarting xinetd, the server is available on port 2222.
The authentication application is a regular CGI application that must be accessible via https. Accordingly, for it it is necessary to configure virtual host: It remains to configure pubcookie. Edit the file / usr / local / pubcookie / config:
ServerName login.techart.intranet
DocumentRoot /usr/local/pubcookie/login
DirectoryIndex index.cgi
AddHandler cgi-script cgi
Options FoolowSymLinks
Options +ExecCGI
AllowOverride None
SSLEngine on
SSLCertificateFile /usr/local/pubcookie/keys/server.crt
SSLCertificateKeyFile /usr/local/pubcookie/keys/server.key
# Уровень детализации логов
logging_level: 1
# Используемый сервис аутентификации.
# В нашем примере мы используем пользовательский скрипт auth.php,
# который обращается к базе данных.
basic_verifier: verify_fork
verify_exe: /usr/local/pubcookie/auth.php
# Пара ключей SSL
ssl_key_file: /usr/local/pubcookie/keys/server.key
ssl_cert_file: /usr/local/pubcookie/keys/server.crt
# Пара granting ключей
granting_key_file: /usr/local/pubcookie/keys/granting.key
granting_cert_file: /usr/local/pubcookie/keys/granting.crt
# Логин-сервер (CGI)
login_uri: https://access.techart.intranet/
login_host: access.techart.intranet
enterprise_domain: .techart.intranet
logout_prog: /logout/index.cgi
# Сервер ключей
keymgt_uri: localhost:2222
ssl_ca_file: /usr/local/pubcookie/keys/ca-bundle.crt
# Срок жизни сессии
default_l_expire: 8h
# Параметры шаблонов логин-сервера, в частности, сообщение о закрытии сессии.
app_logout_string-app1.techart.intranet-app1: Разлогинились из app1
In this example, we use verify_fork mode when an arbitrary external program is used as the authentication service, returning a normal or erroneous termination code depending on whether the user was identified. In this case, the program reads the username and password from stdin.
In our case, this is a php script that can, for example, access a database or a text file, while other modes are supported, for example, working with LDAP and Kerberos.
Now we generate a key that allows the login server to connect to the key server:
$ sudo keyclient -P access.techart.intranet
The generated key will be written to
keys/access.techart.intranet
. This operation must be performed for each host using Pubcookie. After performing all these manipulations at access.techart.intranetwe should see the login form.
Setting up the application server.
On the application server, we configure the pubcookie configuration file in the same way as on the access server. In addition, you need to connect the mod_pubcookie module to Apache.
To do this, create a file
/etc/apache2/mods-available/pubcookie.conf
: PubcookieGrantingCertFile /usr/local/pubcookie/keys/granting.crt
PubcookieSessionKeyFile /usr/local/pubcookie/keys/server.key
PubcookieSessionCertFile /usr/local/pubcookie/keys/server.crt
PubcookieKeyDir /usr/local/pubcookie/keys/
PubcookieLogin https://access.techart.intranet/
PubcookieLoginMethod POST
PubcookieDomain .techart.intranet
PubcookieEncryption AES
PubcookieAuthTypeNames EGNetID
Then everything is as usual:
/etc/apache2/mods-available/pubcookie.load:
LoadModule pubcookie_module /usr/lib/apache2/modules/mod_pubcookie.so
$ sudo a2enmod pubcookie
$ sudo service restart apache2
Now we configure the application itself: In this case, we closed access to the entire application, however we could prescribe authentication options for a specific subdirectory, put them in , etc. Setting this option allows the application to get the name of the current user from REMOTE_USER. We restart Apache, and if everything went fine, then when you go to app1.techart.intranet
ServerName app1.techart.intranet
AuthType EGNetID
require valid-user
PubcookieAppID app1
Options Indexes FollowSymLinks MultiViews
AllowOverride None
AllowOverride AuthConfig
Order allow,deny
allow from all
SSLEngine on
SSLCertificateFile /usr/local/pubcookie/keys/server.cert
SSLCertificateKeyFile /usr/local/pubcookie/keys/server.key
.htaccess
AllowOverride AuthConfig
we should be redirected to login.techart.intranet , where we log in and automatically return.
Virtual hosts
All of the above works for virtual hosts tied to a dedicated IP. To work with name-based virtual hosts, SNI support is required in OpenSSL, (since version 0.9.8j) and in Apache (since 2.2.12). In addition, SNI is not supported on IE versions lower than 7.
For this configuration, the Common Name field should contain a list of hosts used. Edit openssl.cnf and regenerate the key set.
[req_distinguished_name]
0.commonName = Common Name (eg, YOUR name)
0.commonName_default = app1.techart.intranet
0.commonName_max = 64
1.commonName = Common Name (eg, YOUR name)
1.commonName_default = app2.techart.intranet
1.commonName_max = 64
...
In the description of the virtual host in Apache, we write:
SLCipherSuite HIGH
SSLProtocol all -SSLv2
and restart apache.
Configure access server user interface
The appearance of the login form and service pages of the login server can be configured using the templates that are in the login_templates directory. To use UTF-8 you need to patch
index.cgi.c
. Configuring logout
Closing a session can be performed both in a separate application and on a login server. The easiest way to do this on the login server is to create a subdirectory
logout
with .htaccess
one directive: PubcookieEndSession redirect
Total.
In general, the mechanism is quite simple, the main difficulty in setting up is not so much with Pubcookie as with OpenSSL.
Accordingly, in the case of implementation, the most important thing is to correctly configure the basic key / certificate management infrastructure.
At the same time, in a situation where there are a lot of legacy applications on the intranet, using Pubcookie allows you to implement centralized access control for them with minimal effort.
A few links:
- http://www.pubcookie.org - project site, latest version from 02/01/2010;
- Installing pubcookie 3.3 on Ubuntu 7.10 with Apache2 - the article is old, but still relevant;
- Single Sign On with PubCookie is another article.