Undertow - IdentityManager - Digest Authentication

Version 1

    IdentityManager - Digest Authentication

    This article is specifically describing the Undertow requirements related to the IdentityManager implementation with regards to Digest authentication.

     

    One point to clarify first is the reason why this IdentityManager exists in the first place - the reason for the IdentityManager is to minimise any dependencies used by Undertow, by providing this IdentityManager interface existing identity related solutions can be wrapped as Undertow is integrated into server environments.  As an example we already have one implementation to wrap the CallbackHandler based security realms used within WildFly for securing the management interfaces and we have a second implementation wrapping the JAAS domains available within WildFly - a third (and most important) implementation will be a wrapper around PicketLink IDM.

     

    For the purpose of Digest authentication the following are the methods that will be used: -

     

    public interface IdentityManager {
        Account verify(final Account account);
        Account verify(final String id, final Credential credential);
    }
    

     

    The verify methods return an Account instance of verification was a success, otherwise they return null.

     

    The first method is not used a lot of Digest authentication although it does deserve a mention.  The purpose of that method is for situations where Undertow already has cached an Account instance and is re-using it for a subsequent request, the verify method is used to verify that the Account is still useable and to provide an opportunity for group membership / role mapping to be reloaded for that Account.  An example of where the first verify method would fail and return null would be if the account has been marked as disabled.

     

    The second verify method is where a supplied account id and a Credential are passed to the underlying IDM, the default Credential interface is just a marker - for Digest authentication the following is the proposed DigestCredential: -

     

    public interface DigestCredential extends Credential {
        DigestAlgorithm getAlgorithm();
        boolean verifyHA1(final byte ha1[]);
    }
    

     

    The DigestAlgorithm returned from the getAlgorithm() method is an enumeration of the algorithms supported by the Undertow Digest mechanism, this can be used to obtain the name of the hash and also to obtain a new MessageDigest instance for creating digests.

     

    The verifyHA1() method can then be used by the IdentityManager to pass in a prepared hexadecimal encoded digest of the username, realm, password combination - the actual implementation of the DigestCredential can then verify this against the actual message being exchanged, if verification is successful true will be returned and the IdentityManager implementation can then return the Account instance.

     

    One point to note - Undertow calling the verify method of the IdentityManager is not a single of a user being authenticated, there are scenarios where this could be called even though it is already known that authentication will not be completed such as if an invalid nonce is received, the call to the IdentityManager is required so that Undertow can mark the nonce as stale if authentication would have otherwise succeeded.  Undertow does however have the ability for security related notifications which could be paired with the IdentityManager integration to recieve notifications for successful and failed authentication attemps.  An IdentityManager implementation can then take the call to verify as a sign that authentication is being attempted for a specific account with the notification being used to determine the actual outcome of the attempt.

     

    A couple of points related to this DigestCredential API: -

    • Undertow does not receive the plain text password, the IdentityManager can choose to use the MessageDigest from the DigestAlgorithm or it can instantiate it's own.
    • The verifyHA1 method also provides an opportunity for the value to be cached, this is useful for a couple of scenarios: -
      • Session based Digest i.e. it is cached against the Digest session.
      • QOP where the mechanism is proving it knows the password or is creating a digest over the response.
    • The protocol specific comparison is within the DigestCredential implementation, this means the IdentityManager implementation does not need to be aware of protocol specifics.
      • The same patern can be used for verifying SASL Digest as is used for HTTP Digest.