Attention! Helicon Tech Blog has moved to www.helicontech.com/articles/

Wednesday, February 18, 2009

HTTP Authentication and Authorization

Let's start with definitions:
  • Authentication or authenticity check is a comparison of person's real credentials with the ones he enters (e.g. login and password).
  • Authorization is the process of granting rights to a user (or a group of users) to perform specific actions based on evaluation of necessary parameters.
Helicon Ape (as well as Apache) uses the following authorization and authentication modules:
For authentication types (AuthType directive):
  • mod_auth_basic (Basic authentication)
  • mod_auth_digest (Digest authentication)
For authentication providers (login/password verification):
  • mod_authn_alias
  • mod_authn_anon
  • mod_authn_dbd
  • mod_authn_dbm
  • mod_authn_default
  • mod_authn_file
  • mod_authnz_ldap
For authorizators (Require directive; verify if authenticated user is allowed to access):
  • mod_authnz_ldap
  • mod_authz_dbm
  • mod_authz_default
  • mod_authz_groupfile
  • mod_authz_owner
  • mod_authz_user

Authentication and authorization - how they work?

Authentication/authorization process happens in 3 steps:
Receipt of authentication data. On this stage mod_auth_basic or mod_auth_digest is operating. They read Authentication request header and retrieve authentication credentials. For Basic authentication it's just a username:password pair in base64 encoding. For Digest authentication it's MD5-Digest of username, password, authname and other parameters that we'll mention later in more details.
Authentication (verification of authentication data). On this step mod_authn_*** modules verify authentication data. mod_authn_file module, for instance, looks for username:password pair in the text file. The result may be: authenticated successfully (AUTH_GRANTED), access denied (AUTH_DENIED) or user not found (AUTH_USER_NOT_FOUND).
Authorization (rights granting). On this final stage mod_authz_*** modules verify if authenticated user may access the resource. For example, having Require user tomas specified in the config, mod_authz_user will concede access only to tomas user and will deny it for anyone else. If Require valid-user is set, mod_authz_user will grant to access to all successfully authenticated users.

Basic authentication: mod_auth_basic

Now we'll look more closely at mod_auth_basic module. Here's the content of .htaccess in c:\inetpub\wwwroot\private\ corresponding to URI /private/:
# Authentication type
AuthType Basic
# Name of zone authentication will be used for (aka realm)
AuthName "private zone"

# Authentication provider. Here - mod_authn_file
AuthBasicProvider file
# Info for mod_authn_file - path to password file
AuthUserFile c:\inetpub\secured\.htpasswds
# Access will be granted to authenticated user john,
# i.e. only john will be authorized
Require user john
Here comes request to /private/. During request processing mod_auth_basic verifies whether requested resource may be accessed by this user. It searches Authentication header in the request. If there's no such header, module stops request processing and server gives out "401 Unauthorized" response with WWW-Authenticate: Basic realm="private zone" header. Having received such response browser prompts to enter username and password for 'private zone'. After the necessary data was entered the browser sends the same request with Authentication header. Username and password are encoded using base64 and look as follows:
base64encode('john:secret') -> 'am9objpzZWNyZXQ='
Authentication header looks like:
Authentication: Basic am9objpzZWNyZXQ=
Now during request processing mod_auth_basic will retrieve authentication data from Authentication header:
base64decode('am9objpzZWNyZXQ=') -> 'john:secret'
These username and password are then passed by mod_auth_basic to authentication provider (in the above example it's mod_authn_file) for verification. In case of successful verification request processing goes on, in the event of failure mod_auth_basic stops request processing and server gives out 401 Unauthorized.

Authentication provider: mod_authn_file

Let's now have a look at mod_authn_file. This module is an authentication provider for mod_auth_basic and mod_auth_digest. mod_authn_file performs a search of username:password pair in the text file. The file may be created manually or using Password utility included to Helicon Ape Manager (Options -> Insert user password...).
Helicon Ape Manager
mod_auth_basic password generation
Helicon Ape .htpasswd
To enable authentication via mod_authn_file module you should specify
# for Basic
AuthBasicProvider file
# or for Digest
AuthDigestProvider file
and path to password file
AuthUserFile c:\inetpub\secured\.htpasswd
Note! Path may be absolute or .htaccess-relative.
This authentication provider is the most used one as it's fast and easy to use. Besides, password file may be edited manually (e.g. comment out some user using # character). The drawback is slow processing of large password files. For security reasons it is not advisable to put password file to the root of the site.

Authorization: mod_authz_user

mod_authz_user is used to authorize authenticated user. In other words the user that was successfully authenticated (username:password matched) is granted or prohibited access to the requested resource.
This module performs a check of Require directive. The line
Require valid-user
means that the module will authorize (grant access) all authenticated users. The line
Require user john tom
says that the module will only authorize john and tom users.

Host-dependent authorization: mod_authz_host

mod_authz_host module stands detached from other authorization modules. During request processing this module is invoked earlier than other authentication/authorization modules and is used to control access based on client host data (host name, address) and request parameters (via environment variables). This is probably the most popular Apache module for access control.
The module uses 3 directives: Order, Allow, Deny. Order directive defines the sequence of rules validation:
Order allow,deny
means that Allow rules will be checked first and Deny rules will be checked after. If no rules are specified, the default action is Deny all. Directive
Order deny,allow
means the opposite. Deny rules will be checked first and Allow rules will be checked after. Default action is Allow all. Allow and Deny directives define the rules for the check:
# allow all clients from  .org zone
Allow from .org
# three identical rules: allow from 192.168 subnet
Allow from 192.168
Allow from 192.168.0.0/16
Allow from 192.168.0.0/255.255.0.0
# deny from the following IPv6 adress
Deny from 2001:db8::a00:20ff:fea7:ccea
The rules are checked until the first match. The rule gets matched if it corresponds to the client info. If Allow rule gets matched, access is granted; if Deny one, access is denied.

User group authorization: mod_authz_groupfile

mod_authz_groupfile module provides athorization of authenticated user based on its membership in some group. Example:
Require group developers managers
Groups and their members are defined in a plain text file: each line starts with a group name: and a space- or tab-separated list of group members. Example:
# file c:\inetpub\secured\groupfile.txt
testers: tom tony
developers: jack john
managers: jane bill
File path is set by AuthGroupFile directive:
AuthGroupFile c:\inetpub\secured\groupfile.txt
The aforementioned syntax of Require directive may be rewritten in the following way:
Require user tom tony jack john jane bill
Utilization of mod_authz_groupfile allows to group users and then apply group-based access policies.

Anonymous authorization: mod_authn_anon

mod_authn_anon provides authentication of anonymous users. The username is usually represented by anonymous (but may be different) and password is user's email. This email may be saved to log. Together with other authentication providers (e.g., mod_authn_file) mod_authn_anon makes it possible to monitor access of registered users and have the site opened for non-registered users as well. Here's an example of mod_authn_anon config:
AuthName "Protected area"
# authentication type
AuthType Basic
# list of authentication providers, applied sequentially
AuthBasicProvider file anon
# path to password file for mod_authn_file
AuthUserFile c:\inetpub\secured\.htpasswd# mod_authn_anon parameters
# can the name fiels be empty or any (on or off)
Anonymous_NoUserID off
# can the password (email) be empty (on or off)
Anonymous_MustGiveEmail on
# check if the password is email (on or off)
Anonymous_VerifyEmail on
# log email (on or off)
Anonymous_LogEmail on
# list of anonymous users
Anonymous anonymous guest www test welcomeRequire valid-user
Note! mod_authn_anon can work only with Basic authentication. Email check (enabled by Anonymous_MustGiveEmail on directive) is rather trivial - the line must contain '@' and '.' characters.

Authentication and Authorization fallbacks

mod_authn_default module is the last, fallback module in authentication process. If no authentication module is configured for the requested resource (e.g., mod_auth_basic with AuthType Basic etc.), mod_authn_default simply rejects any authentication data and terminates request prosessing with the result 401 Authorization Required. This may happen if mod_auth_basic is not authoritative (AuthBasicAuthoritative Off - see next chapter) and cannot authenticate the user.
mod_authz_default module is the last, fallback module in authorization process. If no authorization module fired for the request (e.g., mod_authz_user with Require user john), and that is possible if Require contains some unidentified values (e.g., Require unknown requirement), mod_authz_default simply terminates request prosessing with the result 401 Authorization Required.

Authoritative modules

Authentication (mod_auth_basic, mod_auth_digest) and authorization (mod_authz_user, mod_authz_groupfile) modules have directives that define their authoritarianism: AuthBasicAuthoritative On|Off, AuthzUserAuthoritative On|Off, AuthzGroupFileAuthoritative On|Off. These directives entitle consequent modules to continue authentication/authorization process. By default the modules are autoritative - Auth*Authoritative On.
In mod_auth_basic authoritarianism works in the following manner. As a rule each authentication provider listed in AuthBasicProvider directive attempts to authenticate the user and if the user isn't found by the module, access will be denied saying 401 Authorization Required. Disabling module authoritarianism - AuthBasicAuthoritative Off - in such cases gives other modules (e.g. third-party modules that cannot be defined in AuthBasicProvider directive) a chance to authenticate user and not deny access immediately. Request processing order for these modules is not configured and is defined in their source code.
Disabling authoritarianism for mod_authz_user - AuthzUserAuthoritative Off - allows other modules (e.g., mod_authz_groupfile) continue authorization if mod_authz_user failed to find information about authenticated user. Example:
...
AuthzUserAuthoritative Off
Require user john group developers
mod_authz_user can't authorize tom user (as only john user is mentioned in Require statement) but as it's not authoritative, it gives mod_authz_groupfile an opportunity to check whether tom belongs to developers group.
If none of the modules (being non-authoritative) has managed to authorize the user, the last in the queue will be mod_authz_default that will give out 401 Authorization Required.

Conclusion

In this article we tried to cover all basic aspects of authentication and authorization processes, help you gain clear understanding of these matters with our easy-to-grasp examples and tell about some non-evident issues. If someone has found at least some bytes of helpful info in our article, our efforts were not vain, 'cause it's a great pleasure to be able to do something for you.

1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete