Class HttpDigestAuthenticationHandler

  • All Implemented Interfaces:
    PluginComponent, java.lang.Comparable<AuthenticationHandler>

    public class HttpDigestAuthenticationHandler
    extends AuthenticationHandler
    Authenticates user using HTTP Authorization.

    In order to use this handler YOU MUST perform the following operation :

    1. Prior to using the handler, you MUST save the Members' hash 'HA1' in the ExtraData of each Member allowed to use this authentication.
        
          Member mbr = ...;
          Member updated = (Member) mbr.getUpdateInstance();
          updated.setExtraDataMap(Util.getHashMap(mbr.getExtraDataMap()));
          HttpDigestAuthenticationHandler.putHA1InMemberExtraData(updated, "MyRealm", "The member's clear text password");
          updated.performUpdate(admin);
         
      Note : building the HA1 requires the clear text password of the user but the password is NOT saved (see explanation below).
    2. To request an HTTP Authentication, invoke the method setHttpDigestAuthorizationHeader(HttpSession, HttpServletResponse, String).
      This will trigger a HTTP Authorization response, the handler will deal with decoding of the next request.
      For example :
         <%@ include file="/jcore/doInitPage.jspf" %><% 
         %><%@ page import="com.jalios.jcms.authentication.handlers.HttpDigestAuthenticationHandler" %><%
       
           if (loggedMember == null) {
             HttpDigestAuthenticationHandler.setHttpDigestAuthorizationHeader(session, response, "MyRealm");
             return;
           }
         %>
         

    HA1 explanation: : HTTP Digest authentication requires either the password in clear text form (we definitely do not want that) or the hash HA1 (md5(user:realm:clear-text-password)) on the server side.
    That's why the HA1 MUST be saved from the clear text password of the Member when it's available (for example using a DataController when editing its profile).

    More informations on Digest authentication can be found here :

    • http://tools.ietf.org/html/rfc2617
    • http://en.wikipedia.org/wiki/Digest_access_authentication
    • http://ryandaigle.com/articles/2009/1/30/what-s-new-in-edge-rails-http-digest-authentication
    Since:
    jcms-6.1.0
    Version:
    $Revision: 107554 $
    Author:
    Olivier Jaquemet
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static Member checkAuthenticationFromHTTPAuthorization​(javax.servlet.http.HttpServletRequest request)
      Returns the member corresponding to the HTTP Authorization header available in the request.
      static java.lang.String getDefaultRealm()
      Retrieve the default REALM used for HTTP Digest authentication.
      static java.lang.String getExtraDataKey​(java.lang.String realm)
      Retrieve the ExtraData key used to store the HASH HA1 for the specified realm
      static java.lang.String getHA1​(Member member, java.lang.String realm, java.lang.String clearTextPassword)
      Compute and retrieve the HASH key HA1 for the specified parameters
      static java.lang.String getHA1FromMemberExtraData​(Member member, java.lang.String realm)
      Retrieve the previously stored HASH key HA1 frm the member's ExtraData (or ExtraDBData for DBMember)
      static java.lang.String getHA2​(javax.servlet.http.HttpServletRequest request)
      Compute and retrieve the HASH key HA2 for the specified request
      static HttpDigestAuthenticationHandler getInstance()  
      void loadProperties()
      This method will be called by the AuthenticationManager each time the Channel properties are loaded/reloaded.
      You can use it to reload properties that might have been changed.
      This method is called during initialization of the AuthenticationManager
      void login​(AuthenticationContext ctxt)
      Authenticate a member.
      static void putHA1InMemberExtraData​(Member member, java.lang.String realm, java.lang.String clearTextPassword)
      Compute and add the HASH key HA1 in the member's ExtraData (or ExtraDBData for DBMember)
      static java.lang.String removeSurroundingQuote​(java.lang.String str)  
      static void setHttpDigestAuthorizationHeader​(javax.servlet.http.HttpSession session, javax.servlet.http.HttpServletResponse response, java.lang.String realm)
      Set a 401 status code (UNAUTHORIZED) and add the "WWW-Authenticate" header to the given response using the given realm.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • ORDER_DIGEST_HTTP_HANDLER

        public static final int ORDER_DIGEST_HTTP_HANDLER
        Order used by the HttpDigestAuthenticationHandler
        See Also:
        Constant Field Values
    • Method Detail

      • loadProperties

        public void loadProperties()
        Description copied from class: AuthenticationHandler
        This method will be called by the AuthenticationManager each time the Channel properties are loaded/reloaded.
        You can use it to reload properties that might have been changed.
        This method is called during initialization of the AuthenticationManager
        Overrides:
        loadProperties in class AuthenticationHandler
      • login

        public void login​(AuthenticationContext ctxt)
                   throws java.io.IOException
        Description copied from class: AuthenticationHandler
        Authenticate a member.
        This method is invoked by the authentication chain on each request.
        A typical implementation of this method would follow the following pattern :
        1. Examine informations required to perform the authentication through the AuthenticationContext object (request, response, login.. etc)
        2. Perform your authentication before chain invokation and set the logged Member AuthenticationContext.setLoggedMember(com.jalios.jcms.Member)
        3. a) Either invoke the next entity in the chain using AuthenticationContext.doChain(),
        4. b) or else skip the chain invokation and block other authentication handler of the chain (do this with caution...)
        5. Perform redirection, set information/warning/error message or any other process, after chain invokation, using AuthenticationContext.

        Default implementation is to invoke the next handler in the chain.
        Overrides:
        login in class AuthenticationHandler
        Parameters:
        ctxt - the AuthenticationContext used for this login
        Throws:
        java.io.IOException
      • checkAuthenticationFromHTTPAuthorization

        public static final Member checkAuthenticationFromHTTPAuthorization​(javax.servlet.http.HttpServletRequest request)
                                                                     throws java.io.IOException
        Returns the member corresponding to the HTTP Authorization header available in the request.
        http://www.ietf.org/rfc/rfc2617.txt
        We only handle the "DIGEST" Authentication Scheme.
        Parameters:
        request - the request where to look for HTTP Authorization header
        Returns:
        the authenticated member or null if not found
        Throws:
        java.io.IOException - if the underneath login operation with the userId/password could not be performed
        Since:
        jcms-5.5.0
      • removeSurroundingQuote

        public static java.lang.String removeSurroundingQuote​(java.lang.String str)
      • setHttpDigestAuthorizationHeader

        public static final void setHttpDigestAuthorizationHeader​(javax.servlet.http.HttpSession session,
                                                                  javax.servlet.http.HttpServletResponse response,
                                                                  java.lang.String realm)
        Set a 401 status code (UNAUTHORIZED) and add the "WWW-Authenticate" header to the given response using the given realm.
        Use this methods to request an HTTP Authorization using the "Basic" Authentication Scheme.
        Parameters:
        session - the current session being used for authentication
        response - the HttpServletResponse of which to set status and add header
        realm - the Realm to set in the response
        Since:
        jcms-5.5.0
      • getHA1

        public static java.lang.String getHA1​(Member member,
                                              java.lang.String realm,
                                              java.lang.String clearTextPassword)
        Compute and retrieve the HASH key HA1 for the specified parameters
        Parameters:
        member - the member for which the HASH is generated
        realm - the HASH realm
        clearTextPassword - the member's clear text password
        Returns:
        the hash MD5( "{login}:{realm}:{clearTextPassword}" )
      • putHA1InMemberExtraData

        public static void putHA1InMemberExtraData​(Member member,
                                                   java.lang.String realm,
                                                   java.lang.String clearTextPassword)
        Compute and add the HASH key HA1 in the member's ExtraData (or ExtraDBData for DBMember)
        Parameters:
        member - the member for which hash is set
        realm - the HASH realm
        clearTextPassword - the clear text password of the user, REQUIRED
      • getHA1FromMemberExtraData

        public static java.lang.String getHA1FromMemberExtraData​(Member member,
                                                                 java.lang.String realm)
        Retrieve the previously stored HASH key HA1 frm the member's ExtraData (or ExtraDBData for DBMember)
        Parameters:
        member - the member for which hash is retrieved
        realm - the HASH realm
        Returns:
        the previously stored hash or null if none was stored
      • getExtraDataKey

        public static java.lang.String getExtraDataKey​(java.lang.String realm)
        Retrieve the ExtraData key used to store the HASH HA1 for the specified realm
        Parameters:
        realm - the realm
        Returns:
        the extradata key (eg. "authentication.digest.myrealm.ha1")
      • getHA2

        public static java.lang.String getHA2​(javax.servlet.http.HttpServletRequest request)
        Compute and retrieve the HASH key HA2 for the specified request
        Parameters:
        request - the HttpServletRequest for which the HA2 is being generated
        Returns:
        the hash MD5( "{login}:{realm}:{clearTextPassword}" )
      • getDefaultRealm

        public static java.lang.String getDefaultRealm()
        Retrieve the default REALM used for HTTP Digest authentication.
        Returns:
        the default realm specified by property "authentication.digest.default-realm" or "JCMS" is property is empty.