I use several internal-only domains intended for system monitoring, Node process management, and log visualization, among others. The domains themselves are publicly accessible, with handy domains like
*.internal.kevinlin.info, but are secured using HTTP basic authentication.
Basic authentication is convenient and relatively painless to configure (can be declared explicitly in an
.htaccess file in the
DocumentRoot or as a configuration directive in
- It's primitive.
- It's insecure (credentials are sent over as a mere base64-encoded hash as an HTTP request header). I hesitate to type credentials into any site that isn't SSL-secured.
- It's generally unappealing from a user experience standpoint; it's a simple popup dialog box with minimal opportunity for customization or branding.
Single sign-on is an authentication scheme whereby a user authenticates against a central authentication server, which then requests for the user to store a short-lived session cookie on the client (browser). Subsequent requests by the client to domains within the cookie's scope supply the value of this cookie in their HTTP headers, which the server validates on every request to ensure that the user is authorized.
Why is this convenient?
- Authorization can be shared across domains. Supply credentials at a single point, and authenticate against any service within the scope of the cookie's domain (in my case, any domain matching the pattern
- There is no longer a need to re-enter passwords. Browsers will generally cache the basic authentication credentials locally, which are automatically sent in the
Authorizationheader of every outgoing request to that domain in that session (i.e. while the browser is open). However, if you close the browser and visit the domain again, you'll be prompted to re-enter your password. SSO eliminates this process by setting a constant expiry time on every distributed session cookie, so you only need to authenticate once every
- Flexibility to extend authentication. Validate against a custom datastore rather than
/etc/apache2/.htpasswd? Sure; just implement application logic to do that. 2FA? Sure; just add additional steps between the initial authentication request and Apache's
- Nicer UI. The authentication layer is just another web application; it can be extended and branded freely.
mod_auth_form supplies all of the server-side logic for distributing and validating session cookies. The only task at hand is to implement a frontend that calls into Apache's APIs to request session cookies appropriately.
mod_auth_form is an Apache module that supplies handler endpoints for validating a user against those in an
/etc/apache2/.htpasswd. In this sense, the authorization mechanism itself is not much different than that of HTTP basic authentication, but successful authorizations return a response with a
Set-Cookie header whose cookie value is recognized by Apache on subsequent incoming requests as authorization tokens.
The greatest aspect of
mod_auth_form is that it sits completely transparently between the client and underlying application. There is thus zero integration overhead associated with auth-walling applications, and it is entirely application and stack agnostic. All logic related to authentication resides in the virtual host configuration for the application, and authentication requests are directed to a dedicated service.
Let's consider the following architecture diagram:
Cookie-based session authentication.
My Kibana dashboard lives at
logs.internal.kevinlin.info and my authentication frontend lives at
auth.kevinlin.info. A typical SSO flow would look something like this:
- Client issues a
logs.internal.kevinlin.info, with no session cookies.
- Apache tries to validate the session cookie, but there is none. The user is not authenticated; issue a 302 redirect to
- Client supplies authentication credentials to the frontend at
auth.kevinlin.info, which submits an AJAX request to
mod_auth_form's auth handler
- Apache validates the credentials using a mechanism of choice (e.g. an
AuthUserFile), creates a session cookie, encrypts it, and sends it to the client using a
- The client (browser) respects the incoming cookie and will include it as a header in all subsequent requests to the cookie's domain scope.
- Another attempt to access
logs.internal.kevinlin.infois made, with a valid session cookie. Apache validates the session cookie and continues to service the request as normal.
Details on what the Apache configuration looks like can be found in the repository's README.
apache-auth is an Express/React frontend application for interfacing with the handlers provided by
mod_auth_form. In practice, it is the visible authentication service that exists on the authentication domain (in my case,
auth.kevinlin.info). Its only functionality is to dispatch requests for accepting and destroying session cookies created by Apache.
It looks suspiciously like OneLogin
mod_auth_form provide a dead-simple implementation of SSO with zero impact to application logic under a secured domain. Please visit the repository for more information.