bare-bones-digest is an implementation of the HTTP
Digest
authentication scheme for Android. With a small effort you can use it
to get HTTP digest working with HttpURLConnection
or any other HTTP
stack.
bare-bones-digest aims to support all features of HTTP digest that is used in real-life applications. The goal is to be interoperable with any server with a HTTP digest implementation.
As of version 1.0.0, bare-bones-digest is stable. Changes will only be made as results of bug reports or feature requests.
Android's standard class for HTTP communication, HttpURLConnection, has no built-in support for HTTP Digest. If you need HTTP digest anyway here are some possible approaches:
- Use the Apache HttpClient that is (or at least was) included in Android and that supports HTTP digest. Apache HttpClient has been included in Android from the very start, but Google recommends against using it unless you are targeting very old versions of Android (Froyo and older). The version of HttpClient included in Android is old and Google is not actively working on it and they have not been for some time. In API 23 the client was removed altogether. Read this blog post on the Android Developers blog for Google's stance.
- Use a newer version of Apache HttpClient. Note however that Apache has discontinued the HttpClient for Android project.
- Use OkHttp for HTTP requests. At the moment of this writing OkHttp does not natively support HTTP digest, but you can use a third-party authenticator such as okhttp-digest.
If none of the approaches above suit your needs you can use this
library to implement HTTP digest on top of HttpURLConnection
(or
some other HTTP stack) without too much trouble.
Include bare-bones-digest as a dependency in your project's
build.gradle
:
dependencies {
implementation 'com.albroco:bare-bones-digest:1.0.2'
}
bare-bones-digest is available from Maven Central. If dependency
resolution fails, make sure mavenCentral()
is in your list of
repositories:
repositories {
mavenCentral()
}
Versioning follows semver. The public API for bare-bones-digest is the project javadoc.
HTTP Digest is defined in RFC 2617. Wikipedia has a good explanation, especially the example is good for a quick overview. The basics are as follows:
- The client makes a HTTP request to the server.
- The server responds with status code 401, Unauthorized, and a
challenge in a
WWW-Authenticate
HTTP header. - The client sends the request again, now with an added
Authorization
HTTP header with a response to the challenge. The response contains a hash including the user's credentials, information about the request, and parts of the challenge. - To avoid sending each request twice, in subsequent requests the client can reuse the challenge. Only the first request will have to be sent twice.
Here is an example of how to make a request and respond to a Digest challenge:
// Step 1. Create the connection
URL url = new URL("http://httpbin.org/digest-auth/auth/user/passwd");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Step 2. Make the request and check to see if the response contains an authorization challenge
if (connection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
// Step 3. Create a authentication object from the challenge...
DigestAuthentication auth = DigestAuthentication.fromResponse(connection);
// ...with correct credentials
auth.username("user").password("passwd");
// Step 4 (Optional). Check if the challenge was a digest challenge of a supported type
if (!auth.canRespond()) {
// No digest challenge or a challenge of an unsupported type - do something else or fail
return;
}
// Step 5. Create a new connection, identical to the original one...
connection = (HttpURLConnection) url.openConnection();
// ...and set the Authorization header on the request, with the challenge response
connection.setRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
auth.getAuthorizationForRequest("GET", connection.getURL().getPath()));
}
DigestAuthentication
is the main entry point of the API, read the documentation for more examples. Some other useful
classes include:
WwwAuthenticateHeader
which can be used to parse challenges fromWWW-Authenticate
headers, including challenges of other types than Digest.DigestChallenge
which provides functionality for parsing digest challenges.DigestChallengeResponse
which provides functionality for generating responses to digest challenges.
- Supports
MD5
,MD5-sess
,SHA-256
, andSHA-256-sess
algorithms. - Supports
auth
,auth-int
and RFC 2069 quality of protection. - Somewhat lenient parsing, where common server mistakes (such as not
quoting the
qop
directive) does not cause the parsing to fail.
bare-bones-digest has been tested for interoperability with the following servers:
- Apache HTTP Server v2.4 with mod_auth_digest.
- nodejs v4.2.6 with Passport v0.3.2 and passport-http v0.3.0.
- nodejs v4.2.6 with node-http-digest v0.1.0.
- An Axis M1054 camera.
- httpbin v0.5.
For each valid combination of qop and algorithm that the server supports a single request has been successfully authenticated.
bare-bones-digest has been tested with, and is not compatible with, the following servers:
- nodejs v4.2.6 with node-digest v0.0.5 because of this issue.
The implementation is based on RFC 2617. Features from RFC 7616 (which obsoletes RFC 2617) are only partially implemented.
Please file a github issue if you have any problems! In particular, file an issue if bare-bones-digest is not interoperable with your server of choice.
- RFC 2069 (obsolete): An Extension to HTTP : Digest Access Authentication.
- RFC 2616 (obsolete): Hypertext Transfer Protocol -- HTTP/1.1.
- RFC 2617 (obsolete): HTTP Authentication: Basic and Digest Access Authentication.
- RFC 5234: Augmented BNF for Syntax Specifications: ABNF.
- RFC 7230: Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing.
- RFC 7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication.
- RFC 7615: HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields.
- RFC 7616: HTTP Digest Access Authentication.
- Wikipedia on Digest access authentication.
- draft-smith-sip-auth-examples-00.txt: Digest Authentication Examples for Session Initiation Protocol (SIP).