GoogleAuth is a Java server library that implements the Time-based One-time Password (TOTP) algorithm specified in RFC 6238.
This implementation borrows from Google Authenticator, whose C code has served as a reference, and was created upon code published in this blog post by Enrico M. Crisostomo.
The library does not store nor load user credentials directly, and a hook is provided to users who want to integrate this functionality. The ICredentialRepository interface defines the contract between a credential repository and this library and a custom implementation can be plugged in and used by the library as a user-provided credential repository.
The following methods take a user name as a parameter and require a credential repository to be available:
String getSecretKey(String userName)
.void saveUserCredentials(String userName, ...)
.
The credentials repository establishes the relationship between a user name and its credentials. This way, API methods receiving only a user name instead of credentials can be used:
public GoogleAuthenticatorKey createCredentials(String userName)
.boolean authorizeUser(String userName, ...)
.
If an attempt is made to use such methods when no credential repository is configured, a meaningful error is emitted:
java.lang.UnsupportedOperationException: An instance of the
com.warrenstrange.googleauth.ICredentialRepository service must be
configured in order to use this feature.
The library looks for instances of this interface using the
Java ServiceLoader API (introduced in Java 6), that is,
scanning the META-INF/services
package looking for a file named
com.warrenstrange.googleauth.ICredentialRepository
and, if found, loading the
provider classes listed therein.
To successfully compile this library a Java SE 7 compiler is required and sources must be compiled at least at language level 7.0.
This library depends on the following libraries:
- Apache Commons Codec.
- Apache HTTP client.
- JUnit (test scope).
Since this library is a Maven project, always refer to pom.xml
for up-to-date
dependencies and further details.
Both the Google Authenticator client applications (available for iOS, Android and BlackBerry) and its PAM module can be used to generate codes to be validated by this library.
However, this library can also be used to build custom client applications if Google Authenticator is not available on your platform or if it cannot be used.
This library includes full JavaDoc documentation and a JUnit test suite that can be used as example code for most of the library purposes.
Texinfo documentation sources are also included and a PDF manual can be
generated by an Autotools-generated Makefile
:
-
To bootstrap the Autotools, the included
autogen.sh
script can be used. -
Configure and build the documentation:
$ ./configure $ make pdf
Since typical users will not have a TeX distribution installed in their computers, the PDF manuals for every version of GoogleAuth will be hosted at this address.
The following code creates a new set of credentials for a user. No user name is provided to the API and it's responsibility of the caller to save them for later use during the authorisation phase.
GoogleAuthenticator gAuth = new GoogleAuthenticator();
final GoogleAuthenticatorKey key = gAuth.createCredentials();
The following code creates a new set of credentials for the user caller
and
stores them on the configured ICredentialRepository
instance:
GoogleAuthenticator gAuth = new GoogleAuthenticator();
final GoogleAuthenticatorKey key = gAuth.createCredentials("caller");
If a credential repository is not configured the code will fail throwing an
UnsupportedOperationException
.
The following code checks the validity of the specified code
against the
provided Base32-encoded secretKey
:
GoogleAuthenticator gAuth = new GoogleAuthenticator();
boolean isCodeValid = gAuth.authorize(secretKey, code);
The following code checks the validity of the specified code
against the
secret key of the user caller
returned by the configured
ICredentialRepository
instance:
GoogleAuthenticator gAuth = new GoogleAuthenticator();
boolean isCodeValid = ga.authorizeUser("caller", code);
Bug reports can be sent directly to the authors.