Package sunlabs.brazil.handler
Class DigestAuthHandler
- java.lang.Object
-
- sunlabs.brazil.handler.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
WWW-Authenticate: Digest realm="myrealm", qop="auth", [req'd for IE] nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41", [optional] domain="/foo" [optional]
Sample client return headerAuthorization: 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.
-
-
Constructor Summary
Constructors Constructor Description DigestAuthHandler()
-
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.
-
-
-
Method Detail
-
init
public boolean init(Server server, java.lang.String propsPrefix)
Description copied from interface:Handler
Initializes the handler.- Specified by:
init
in interfaceHandler
- Parameters:
server
- The HTTP server that created thisHandler
. TypicalHandler
s will useServer.props
to obtain run-time configuration information.propsPrefix
- The handlers name. The string thisHandler
may prepend to all of the keys that it uses to extract configuration information fromServer.props
. This is set (by theServer
andChainHandler
) to help avoid configuration parameter namespace collisions.- Returns:
true
if thisHandler
initialized successfully,false
otherwise. Iffalse
is returned, thisHandler
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 interfaceHandler
- Parameters:
request
- TheRequest
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 callingRequest.sendResponse()
orRequest.sendError
.- Throws:
java.io.IOException
- if there was an I/O error while sending the response to the client. Typically, in that case, theServer
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 aFileNotFoundException
due to not being able to open a file). In that case, theHandler
's duty is to turn thatIOException
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 RFCmethod
- The http request method.h
- Properties containing all the name=value options from the http authentiation header field (seeextractAuth(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 serveruser
- The useridpass
- The password associated with this usermethod
- "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
-
-