I want to write a servlet that wraps around a set of resources and needs to protect them with basic HTTP auth; the submitted username/pass will be checked against the backend database before serving the file.
Does anyone have any working examples of this? I tried the sample at http://www.coderanch.com/t/352345/Servlets/java/HTTP-basic-authentication-Web-Applications but it kept returning an IllegalStateException
in the sendError
call.
For HTTP basic authentication, each request must include an authentication header, with a base-64 encoded value. Where siteName is the company name you use to log in to Eloqua, and username and password are your Eloqua username and password.
Basic authentication is easy to define. In the global securityDefinitions section, add an entry with type: basic and an arbitrary name (in this example - basicAuth). Then, apply security to the whole API or specific operations by using the security section.
Basic authentication is a simple authentication method. Clients can authenticate via username and password. These credentials are sent in the Authorization HTTP header in a specific format. It begins with the Basic keyword, followed by a base64-encoded value of username:password.
Here is some code that returns a Credential object (bean object holding login and password).
public Credentials credentialsWithBasicAuthentication(HttpServletRequest req) {
String authHeader = req.getHeader("Authorization");
if (authHeader != null) {
StringTokenizer st = new StringTokenizer(authHeader);
if (st.hasMoreTokens()) {
String basic = st.nextToken();
if (basic.equalsIgnoreCase("Basic")) {
try {
String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8");
LOG.debug("Credentials: " + credentials);
int p = credentials.indexOf(":");
if (p != -1) {
String login = credentials.substring(0, p).trim();
String password = credentials.substring(p + 1).trim();
return new Credentials(login, password);
} else {
LOG.error("Invalid authentication token");
}
} catch (UnsupportedEncodingException e) {
LOG.warn("Couldn't retrieve authentication", e);
}
}
}
}
return null;
}
It works well, even with a password as funky as :&=/?é$£.
Here is a basic unit test for the class, using jMock:
public void testCredentialsWithBasicAuthentication() {
// Setup
final HttpServletRequest request = context.mock(HttpServletRequest.class);
AuthentificationHelper helper = new AuthentificationHelper();
String login = "mickael";
String password = ":&=/?é$£";
String base64Hash = Base64.encodeString(login + ":" + password);
final String authHeader = "Basic " + base64Hash;
// Expectations
context.checking(new Expectations() {
{
oneOf (request).getHeader("Authorization");
will(returnValue(authHeader));
}
});
// Execute
Credentials credentials = helper.credentialsWithBasicAuthentication(request);
// Verify
assertNotNull(credentials);
assertEquals(login, credentials.getLogin());
assertEquals(password, credentials.getPassword());
context.assertIsSatisfied();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With