There are many solutions to implement Single Sign On technology in one form or another. By single sign-on is understood the situation when having authorized once on some dedicated authorization server (or just on your own machine), you get access to all available network resources without additional authorization.
We are now gradually engaged in 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, but if you limit yourself to single-sign-on for a set of web applications only, there is a relatively simple solution that allows you to implement this feature without changing or slightly changing the application code. This decision is called
Pubcookie , and it will be discussed.
')
If we use Pubcookie, then when entering a protected resource, we will automatically be redirected to a special dedicated login server, on which we will log in and automatically return back. At the same time, we do not need to change anything in the protected application, it
REMOTE_USER receives the name of the current user from
REMOTE_USER .
Let's see how you can configure this mechanism.
Scheme of workThe authentication process involves the following components:
- Client browser;
- The application server on which the application requiring authentication is deployed, in our case, it is 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 user 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 checks that it is not associated with a valid current session and does not contain information from the login server (the so-called granting cookie) to create a new session.
In case of 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 transmitted in encrypted form. - The client browser redirects (granting request) to the login server with the granting request cookie sent to it. 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 content. The server generates the login form and sends it to the client.
- The user enters his login and password into the form and sends it to the login server;
- The login server receives the login 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 check is successful, the login server generates a response containing a redirect and two new cookies. The first, granting cookie, is intended for the application server and contains a verified username and additional information, including a random number generated in clause 2, signed with the private key of the access server and encrypted with the symmetric key used on the application server and the access server. The second one, login cookie, is intended for the login server and is used in the event of subsequent user visits 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, checks 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 request is processed by the application. This also generates a session cookie, for subsequent access to protected resources. The response generated by the application is sent to the user.
If, in step 4, granting request also contains a valid login cookie (set in step 8), steps 5, 6 and 7 are skipped and the login server proceeds directly to step 8, generating a granting cookie using the username obtained from the login cookie. Thus, we get a Single Sign On technology element for a set of web applications: no need to log in for each web application, just enter your login and password once.
AssemblyWe will consider for Ubuntu, under FreeBSD also does not cause problems:
Download the distribution from
www.pubcookie.org . Before building, we make two patches:
1. Patches configure for a problem with APXS:
3783c3783 < APACHE_PREFIX=`$APXS -q PREFIX` --- > APACHE_PREFIX="/usr/share/apache2"
Here by the method of striking with a hammer, it is possible and correct, probably, to do.
2. Patches src / index.cgi.c for UTF-8 encoding:
461c461 < print_header (p, "Content-Type: text/html; charset=ISO-8859-1\n")
When configuring, we point out the assembly of the module and cgi-applications to enter:
$./configure --enable-apache --with-apxs=/usr/bin/apxs2 --enable-login
Then we collect, preferably in the deb-package.
Generating keys and certificatesHttps is used to work with protected resources. Well, then 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 (see 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 verifying granting cookies:
$ openssl req -new -x509 -out granting.crt -newkey rsa:1024 -nodes -keyout granting.key
An example of a purely demonstration, 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 the login server
Let the server be called access.techart.intranet
The access server runs a key server and an authentication application managed by a web server.
The key server distributes symmetric keys used to encrypt the contents of cookies. It runs under xinetd, respectively, we write 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 server is available on port 2222.
The authentication application is a regular CGI application that should be accessible via https. Accordingly, it is necessary to configure a virtual host for it:
<VirtualHost *:443> ServerName login.techart.intranet DocumentRoot /usr/local/pubcookie/login DirectoryIndex index.cgi AddHandler cgi-script cgi <Directory /> Options FoolowSymLinks Options +ExecCGI AllowOverride None </Directory> SSLEngine on SSLCertificateFile /usr/local/pubcookie/keys/server.crt SSLCertificateKeyFile /usr/local/pubcookie/keys/server.key </VirtualHost>
It remains to configure pubcookie. Edit the file / usr / local / pubcookie / config:
# 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 the verify_fork mode, when an arbitrary external program is returned as the authentication service, which returns a normal or erroneous exit code depending on whether the user has been identified. At the same time, the program reads the user name 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 recorded in
keys/access.techart.intranet . This operation must be performed for each host using Pubcookie.
After performing all these manipulations at
access.techart.intranet, we should see the login form.
Setting up an application server.On the application server, we configure the pubcookie configuration file in the same way as on the access server. In addition, it is necessary to connect the mod_pubcookie module to Apache.
To do this, create the 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 set up the application itself:
<VirtualHost *:443> ServerName app1.techart.intranet <Directory /srv/http/app1> AuthType EGNetID require valid-user PubcookieAppID app1 Options Indexes FollowSymLinks MultiViews AllowOverride None AllowOverride AuthConfig Order allow,deny allow from all </Directory> SSLEngine on SSLCertificateFile /usr/local/pubcookie/keys/server.cert SSLCertificateKeyFile /usr/local/pubcookie/keys/server.key </VirtualHost>
In this case, we closed access to the entire application, however, we could specify authentication options for a particular subdirectory, put them in
.htaccess , etc.
Setting the
AllowOverride AuthConfig allows an application to get the current user name from REMOTE_USER.
We restart Apache, and if everything went fine, then when entering
app1.techart.intranet, we should be redirected to
login.techart.intranet , where we log in and automatically return back.
Virtual hostsAll of the above works for virtual hosts bound to a dedicated IP. To work with name-based virtual hosts,
SNI support is required in OpenSSL (from version 0.9.8j) and in Apache (since 2.2.12). In addition, SNI is not supported for IE versions below 7.
For this configuration, the Common Name field should contain a list of used hosts. Edit openssl.cnf and re-generate a set of keys.
[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 register:
SLCipherSuite HIGH SSLProtocol all -SSLv2
and restart apache.
Configure the access server user interfaceThe appearance of the login form and service pages of the login server can be
configured using templates that are located in the login_templates directory. To use UTF-8 you need to patch
index.cgi.c .
Logout setupSession closure can be performed both in a separate application and on the login server. The easiest way to do this on the login server is to create a
logout subdirectory with
.htaccess containing a single directive:
PubcookieEndSession redirect
TotalIn general, the mechanism is quite simple, the main difficulty in setting is associated not so much with Pubcookie, as with OpenSSL.
Accordingly, in the case of implementation, the most important thing is to properly configure the basic infrastructure for managing keys / certificates.
At the same time, in a situation where there are quite a lot of legacy applications on the intranet, the use of Pubcookie allows you to implement centralized access control for them with minimal effort.
Several links: