Class DigestAuthHandler

  • All Implemented Interfaces:
    Handler

    public class DigestAuthHandler
    extends java.lang.Object
    implements Handler
    Perform digest authentication. This is a minimal implementation of RFC 2617 The "optional" qos parameter is required by IE (only qop="auth" is supported). The "password" file is read at startup time, either as a resource or from the file system, and may contain either plain text or digested passwords (see main() below to digest passwords).

    Future enhancements

    • Better dynamic operation
    • Optional digest parameter handling
    • Nonce time-to-live checking
    Sample auth request header
      
     WWW-Authenticate: Digest
        realm="myrealm",
        qop="auth",                                 [req'd for IE]
        nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
        opaque="5ccc069c403ebaf9f0171e9517f40e41",  [optional]
        domain="/foo"                                       [optional]
     
    Sample client return header
      Authorization: Digest
        username="name",
        realm="foo@bar",
        nonce="mynonce10",
        uri="/da.html",
        response="d58f3f9fa7554da651d3f1901d22ea04",
        qop=auth,
        nc=00000001,
        cnonce="b6ac242cb324c38a"
    
     response algorithm:
     
     A1 = md5(user:realm:pass)
     A2 = md5(method:uri)
     response=md5(A1:nonce:nonceCount:cnonce:qop:A2)
     - all MD5's are represented as hex: [0-9a-f]
     - all quotes (") are removed before digesting
     
    prefix, suffix, glob, match
    Specify which url's this handler applies to.
    realm
    The string presented to the user for validation. This must also match any "digested" passwords.
    credentials
    A java-properties format file of credentials. The keys are the users, the values are either the "A1" values described above, or the user's password.
    isDynamic
    If set (to anything), when authentication for a user is requested that is not in the credentials table and the credentials table has changed since last read, the table is re-read, in case the user has been added since the credentials were loaded.
    allowBogusIE
    Internet Explorer does not use the query parameters as part of the "uri" calculation. This is a bug (and a security risk, as it allows replay attacts to other than the url requested). If this variable is set, then it allows IE to work in this case.
    username
    If the user was validated, this field is filled out by the handler.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static java.lang.String computeA1​(java.lang.String user, java.lang.String realm, java.lang.String pass)
      Compute the A1 parameter as per the RFC.
      static java.lang.String computeA2​(java.lang.String method, java.lang.String uri)
      Compute the A2 parameter as per the RFC.
      static java.lang.String computeResponse​(java.lang.String A1, java.lang.String A2, java.lang.String nonce, java.lang.String nc, java.lang.String cnonce, java.lang.String qop)
      Compute the expected client response attribute value.
      static java.util.Properties extractAuth​(java.lang.String header)
      Parse an auth header, placing the results into a Properties object.
      static java.lang.String genResponseHeader​(java.lang.String request, java.lang.String user, java.lang.String pass, java.lang.String method, java.lang.String uri, java.lang.String nc, java.lang.String cnonce)
      Given the "WWW-Authenticate" header value and additional client info, generate the value of the "Authorization" header.
      boolean init​(Server server, java.lang.String propsPrefix)
      Initializes the handler.
      static boolean isMd5Digest​(java.lang.String s)
      See if a string is a valid md5 digest.
      static void main​(java.lang.String[] args)
      Convert a "plain text" password file into a digested one.
      static java.lang.String md5Digest​(java.lang.String s)
      Compute the md5 digest of a string, returning the digest as a hex string.
      boolean respond​(Request request)
      Responds to an HTTP request.
      static boolean responseOk​(java.lang.String A1, java.lang.String method, java.util.Properties h)
      Check the digest response string.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • DigestAuthHandler

        public DigestAuthHandler()
    • Method Detail

      • init

        public boolean init​(Server server,
                            java.lang.String propsPrefix)
        Description copied from interface: Handler
        Initializes the handler.
        Specified by:
        init in interface Handler
        Parameters:
        server - The HTTP server that created this Handler. Typical Handlers will use Server.props to obtain run-time configuration information.
        propsPrefix - The handlers name. The string this Handler may prepend to all of the keys that it uses to extract configuration information from Server.props. This is set (by the Server and ChainHandler) to help avoid configuration parameter namespace collisions.
        Returns:
        true if this Handler initialized successfully, false otherwise. If false is returned, this Handler should not be used.
      • respond

        public boolean respond​(Request request)
                        throws java.io.IOException
        Description copied from interface: Handler
        Responds to an HTTP request.
        Specified by:
        respond in interface Handler
        Parameters:
        request - The Request object that represents the HTTP request.
        Returns:
        true if the request was handled. A request was handled if a response was supplied to the client, typically by calling Request.sendResponse() or Request.sendError.
        Throws:
        java.io.IOException - if there was an I/O error while sending the response to the client. Typically, in that case, the Server will (try to) send an error message to the client and then close the client's connection.

        The IOException should not be used to silently ignore problems such as being unable to access some server-side resource (for example getting a FileNotFoundException due to not being able to open a file). In that case, the Handler's duty is to turn that IOException into a HTTP response indicating, in this case, that a file could not be found.

      • responseOk

        public static boolean responseOk​(java.lang.String A1,
                                         java.lang.String method,
                                         java.util.Properties h)
        Check the digest response string.
        Parameters:
        A1 - The "A1" hash from the RFC
        method - The http request method.
        h - Properties containing all the name=value options from the http authentiation header field (see extractAuth(String)).
      • computeA1

        public static java.lang.String computeA1​(java.lang.String user,
                                                 java.lang.String realm,
                                                 java.lang.String pass)
        Compute the A1 parameter as per the RFC.
      • computeA2

        public static java.lang.String computeA2​(java.lang.String method,
                                                 java.lang.String uri)
        Compute the A2 parameter as per the RFC.
      • computeResponse

        public static java.lang.String computeResponse​(java.lang.String A1,
                                                       java.lang.String A2,
                                                       java.lang.String nonce,
                                                       java.lang.String nc,
                                                       java.lang.String cnonce,
                                                       java.lang.String qop)
        Compute the expected client response attribute value.
      • genResponseHeader

        public static java.lang.String genResponseHeader​(java.lang.String request,
                                                         java.lang.String user,
                                                         java.lang.String pass,
                                                         java.lang.String method,
                                                         java.lang.String uri,
                                                         java.lang.String nc,
                                                         java.lang.String cnonce)
        Given the "WWW-Authenticate" header value and additional client info, generate the value of the "Authorization" header. The "request" should contain "realm", "nonce", "qop" and optionally "opaque". This is a convenience method for clients to use to athenticate to this server implementation.
        Parameters:
        request - The string value of the "WWW-Authenticate" header from the server
        user - The userid
        pass - The password associated with this user
        method - "GET", "POST", etc.
        uri - The requested url (e.g. "/index.html")
        nc - The "nonce count", or number of times the client has used The "nonce" presented by the server (e.g. "0000001").
        cnonce - An opaque value provided by the client
      • md5Digest

        public static java.lang.String md5Digest​(java.lang.String s)
        Compute the md5 digest of a string, returning the digest as a hex string.
      • isMd5Digest

        public static boolean isMd5Digest​(java.lang.String s)
        See if a string is a valid md5 digest.
      • extractAuth

        public static java.util.Properties extractAuth​(java.lang.String header)
        Parse an auth header, placing the results into a Properties object. Format is: Digest key=value, key=value, ... values may be in "'s.
      • main

        public static void main​(java.lang.String[] args)
                         throws java.lang.Exception
        Convert a "plain text" password file into a digested one. Any existing digests are left alone.
         Usage: DigestAuthHandler [realm]
         
        The stdin, in Properties format, is emitted on stdout with all plain-text passwords digested. If an entry is already digested, it is left alone.

        Note, this handler will except either plaintext or digested passwords in the credentials file.

        Throws:
        java.lang.Exception