Chapter 10. Setting Up Authentication and Session Management (STEP 3)

Veil2 provides built-in mechanisms for authentication and session management. You can choose to use these as they are, extend them, or replace them entirely.

Look for "STEP 3" in the file veil2_demo--<version>.sql.

10.1. Create Your Authentication Methods

If you need an authentication method other than bcrypt you will need to define it as a type and then create authentication functions for it.

New authentication methods should be created by creating new authentication functions and new records in veil2.authentication_types.

New authentication functionality is created by creating new functions with the same signature as veil2.authenticate_bcrypt().

The Veil2 demo chooses to use plaintext authentication which is a really terrible idea but makes for an easy implementation. Don't do this.

10.2. Associate Accessors And Authentication Contexts

Veil2 determines the authentication context for an accessor through the veil2.accessor_contexts view. Since the actual association between them is provided by your database, you must provide a custom version of this view (called veil2.my_accessor_contexts).

To make your version of the view take effect, as described here, use the veil2.init() function.

Note that veil2.implementation_status() will also install your user-defined functions and views as it itself calls veil2.init().

10.3. Define Your my_get_accessor() Function

For user authentication purposes Veil2 needs the accessor_id for the accessors record that represents the user. Since Veil2 does not itself store usernames, email addresses and whatever else that might be used to uniquely identify a user in their authentication context, we need a function that returns an accessor_id for a username. The get_accessor() function is that function.

Your version of this function will be called veil2.my_get_accessor(). As described above you make it current by calling veil2.init().

10.4. Notes on Session Management

If your application requires any special session management functionality, this is the time to create it. There is little we can say here about what that functionality might be, as it will very much depend on your needs. This section simply tries to provide some useful background information.

There are 2 distinct types of sessions provided:

  • shared-connection sessions;

    These are used when a single database user account is used to handle multiple connected users. Each database connection will typically be shared among many users through some sort of connection-pooling system. This is the type of session generally used by web applications.

    It is important with such systems that we can reliably identify which user is connected, and that the privileges of one user are not inadvertently transferred to another. This means that when the connection starts to be used by a new user there must be some form of secure identification of the user.

  • dedicated sessions.

    These are typically used for reporting applications, where each reporting user will have their own database account. In this case, Veil2 determines the user's access rights based upon database roles, and there is no need for further authentication - we assume that database authentication is sufficient.

10.4.1. Shared-Connection Sessions

Within a shared connection environment, such as provided by most web applications, a database connection will be shared amongst many users. When the application needs to perform some database action on behalf of a user, the connection will be retrieved from the pool, and possibly re-initialized, before executing one or more queries on the user's behalf.

Unless we provide the connection with extra information, the database cannot know which user it is executing queries for.

Veil2 provides 3 session management functions to identify and keep track of users:

  • veil2.create_session();
  • veil2.open_connection();
  • veil2.close_connection().

Your application server must call create_session() to identify each new user, and open_connection() before the user begins issuing queries. close_connection() should be called before returning the database connection to the pool.

A detailed description of this can be found in the Authentication Protocols appendix, which describes the functions, their parameters, and describes error handling.

10.4.2. Dedicated Sessions

If you have users that connect directly to your database, perhaps through some reporting tool, you will want to set them up as users of dedicated sessions.

This is done by recording the database username in the username field of the veil2.accessors record.

To begin a dedicated session after connecting to the database, the user must call veil2.hello(), which will return true if Veil2 has successfully authenticated the user.

select veil2.hello();
	

If your reporting tool does not allow such function calls, you will need to create a view that calls it, which the reporting tool can call. Something like this would work:

create or replace 
view session_start as 
select veil2.hello();
	

or, if you need the view to return no rows:

create or replace 
view session_start as 
  with session as (
  select 1 as result from veil2.hello()
  )
select * from session where result = 0;
	

For an example of this, take a look at the Veil2 unit tests (in file tests/test_session.sql). The database user veil2_alice is set up as a dedicated session user (as well as a shared session user).