ESAPIS Hash Authentication

Overview

We have incorporated a new method of client authentication into csf-security. We are calling this method "Hash Authentication", as it relies on a hashing algorithm to authenticate the client. It will be primarily used for APIs. The purpose of this authentication method is to allow client applications to authenticate to our web APIs without having to provide Touchstone credentials or manage an X509 certificate. Hash authentication was first used in the Nelnet APIs (Nelnet is an external system that exchanges data with MITSIS via an API).

How Hash Authentication Works

See here.

When Should We Use Hash Authentication?

We should use this authentication method when the API user is:

Configuring a Web App for Hash Authentication

The code for Hash Authentication resides in CSF Security (v2.0.36-SNAPSHOT). To make use of this feature, a web application must:

1. Import a Spring hash authentication config file from CSF Security. The import should be done in the web app's Spring Security config file:

     <import resource="classpath*:applicationContext-csf-security-hash-authn.xml" />

2. Include a reference to the Hash Authentication filter in the filterChainProxy's list of filters. The filter id is "hashAuthenticationProcessingFilter" and should be the first authentication related filter in the chain - example:

     <security:filter-chain pattern="/**" filters="esapisSecurityContextNonPersistenceFilter,
              logoutFilter,
            hashAuthenticationProcessingFilter,
              esapisAuthenticationProcessingFilter,
              basicAuthenticationProcessingFilter,
              exceptionTranslationFilter,
              filterSecurityInterceptor"
     />

3. Place two properties files in the web app properties directory. These files are:

a) hash-authn-api-users.properties

This file lists the "user ids" representing clients permitted to use hash authentication along with the user's authorizations. The format of the file is a combination of Spring Security's user details property file format and our own roles/qualifiers format for specifying authorizations. The format for one user entry is:

   username=password,authority[&authority],[enabled|disabled],secretKey

where authority is of the form:

   role|qualifier[ qualifier]

e.g.

   math.mit.edu=,DEPTAUDIT_USER|18 8&OTHER_API_ADMIN,true,gr4!d

This example identifies a user id "math.mit.edu" which has no password and has two authorities: role of DEPTAUDIT_USER for departments 18 and 8; and role of OTHER_API_ADMIN (no qualifier). The user id is enabled, and the shared secret is "gr4!d".

So there are various delimiters in play:

b) hash-authn-api-hash-fields.properties

This file defines the list of input fields (API parameters) that should be used in the hashing process. The key field is a API's URI and the property value field is a comma-delimited list of field names. The format for one entry is:

   uri=fieldName[,fieldName]

e.g.

   /dept-undergrad-audit/v1.0/students=deptId,termCode

This specifies that hash authentication for v1.0 of the departmental undergrad audit API uses two fields, department Id and term code in the hashing process.

Invoking a Hash Authentication API

In order to trigger the hash authentication process, the request URL must contain certain key parameters:

Testing a Hash Authentication API

The fact that the hash value depends in part on the timestamp, and that the timestamp must be current means testing is more effort than for APIs using other means of authentication - you have to regenerate timestamps and hashes frequently. A utility is planned to autogenerate timestamp and hashes.

For local testing, an API can use simple basic authentication. Simply omit the "hash" parameter from the request URL and the filter chain will pass control to the basic authentication filter as with regular ES web apps. Just make sure that the user you authenticate as has the appropriate authorizations for the API you are testing.