/*
* $Id: BasicAuthorization.java,v 1.5 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.basic;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import anvil.server.Zone;
import anvil.server.AccessPreferences;
import anvil.server.Authorization;
import anvil.server.Realm;
import anvil.server.Citizen;
import anvil.server.Templates;
import anvil.server.Context;
import anvil.server.MimeTypes;
import anvil.server.ConfigurationError;
/**
* class BasicAuthorization
*
* @author: Simo Tuokko
* @author: Jani Lehtim�ki
*/
public class BasicAuthorization implements Authorization
{
private Zone _zone;
private AccessPreferences _prefs;
public BasicAuthorization()
{
}
public void initialize(Zone zone)
{
_zone = zone;
_prefs = zone.getAccessPreferences();
_zone.log().info("Authorization " + this + " initialized");
}
public Realm getRealm()
{
return _zone.getRealm(_prefs.getRealm());
}
public boolean isSessionRequired()
{
return true;
}
public boolean authorize(Context context) throws IOException
{
if (!_prefs.getRequired()) {
return true;
}
Realm realm = getRealm();
if (realm == null) {
context.log().error("Couldn't get realm named '"+_prefs.getRealm()+"'");
try {
String contentType = MimeTypes.guessContentType(context.getRequest());
Templates.message(context, contentType, 500);
} catch(IOException e) {
context.log().error("Error while writing '500 Internal Server Error' response", e);
}
return false;
}
String auth = context.getRequest().getHeader("Authorization");
context.log().info("basic: Authorization="+auth);
boolean authenticated = false;
if ((auth != null) && (auth.length()>0)) {
int i = auth.indexOf(' ');
if (i > -1) {
String authType = auth.substring(0, i);
String authCode = auth.substring(i + 1);
String decoded = new String(new sun.misc.BASE64Decoder().decodeBuffer(authCode));
i = decoded.indexOf(':');
if (i > -1) {
String username = decoded.substring(0, i);
String password = decoded.substring(i + 1);
Citizen citizen = context.getCitizen();
if (citizen != null) {
if (!citizen.getRealm().equals(realm)) {
citizen = null;
} else if (!citizen.getName().equals(username)) {
citizen = null;
}
}
if (citizen == null) {
context.log().info("basic: login="+username);
citizen = realm.getCitizen(username);
}
if (citizen != null) {
if (citizen.verifyCredentials(password)) {
context.setCitizen(citizen);
context.log().info("basic: authentication ok");
authenticated = true;
} else {
context.log().info("basic: authentication failed");
}
} else {
context.log().info("basic: no user, authentication failed");
}
}
}
}
if (!authenticated) {
HttpServletResponse response = context.getResponse();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "Basic realm=\"" + _prefs.getTitle() + '"');
String contentType = MimeTypes.guessContentType(context.getRequest());
response.setContentType(contentType);
try {
Templates.message(context, contentType, 401);
} catch(IOException e) {
context.log().error("Error while writing '401 Unathorized' response", e);
}
return false;
} else {
return true;
}
}
public void stop()
{
_zone.log().info("Authorization " + this + " stopped");
}
}