001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010:
011: package org.mmbase.security.implementation.basic;
012:
013: import org.w3c.dom.Element;
014: import org.mmbase.util.XMLBasicReader;
015: import org.mmbase.util.XMLEntityResolver;
016:
017: import org.mmbase.security.*;
018: import org.mmbase.security.SecurityException;
019:
020: import java.util.*;
021:
022: import org.mmbase.util.logging.Logger;
023: import org.mmbase.util.logging.Logging;
024:
025: /**
026: * Authentication based on a config files. There is an XML file (`authentication.xml') which defines
027: * several modules (conected to the 'module/method' String). There are now three moduiles in this
028: * implementation. 'anonymous' for the anonyunous user. 'name/password' for 'basic users'. The
029: * username/passwords of the basic users are defined in an account.properties file. The last module
030: * is 'admin' which authenticates only on password.
031: *
032: * @todo MM: I think it should be possible for admin to login with name/password to, how else could
033: * you use HTTP authentication (e.g. admin pages).
034: * @author Eduard Witteveen
035: * @version $Id: AuthenticationHandler.java,v 1.13 2007/07/25 06:47:11 michiel Exp $
036: */
037: public class AuthenticationHandler extends Authentication {
038: private static final Logger log = Logging
039: .getLoggerInstance(AuthenticationHandler.class);
040:
041: public static final String PUBLIC_ID_BASICSECURITY_1_0 = "-//MMBase//DTD securitybasicauth config 1.0//EN";
042: public static final String DTD_BASICSECURITY_1_0 = " securitybasicauth_1_0.dtd";
043:
044: static {
045: XMLEntityResolver.registerPublicID(PUBLIC_ID_BASICSECURITY_1_0,
046: DTD_BASICSECURITY_1_0, AuthenticationHandler.class);
047: }
048:
049: private Map<String, LoginModule> modules = new HashMap<String, LoginModule>();
050: private Map<String, Rank> moduleRanks = new HashMap<String, Rank>();
051:
052: protected void load() {
053: XMLBasicReader reader;
054: try {
055: org.xml.sax.InputSource in = MMBaseCopConfig.securityLoader
056: .getInputSource(configResource);
057: log.debug("using: '" + configResource
058: + "' as config file for authentication");
059: reader = new XMLBasicReader(in, getClass());
060: } catch (Exception e) {
061: throw new SecurityException(e);
062: }
063:
064: log.debug("Trying to load all loginmodules:");
065: for (Element modTag : reader.getChildElements(reader
066: .getElementByPath("authentication"), "loginmodule")) {
067: String modName = reader.getElementAttributeValue(modTag,
068: "name");
069: if (modName.equals("")) {
070: throw new SecurityException(
071: "module attribute name was not defined in :"
072: + configResource);
073: }
074: String modClass = reader.getElementAttributeValue(modTag,
075: "class");
076: if (modClass.equals("")) {
077: throw new SecurityException(
078: "module attribute class was not defined in :"
079: + configResource + " for module: "
080: + modName);
081: }
082: String modRankString = reader.getElementAttributeValue(
083: modTag, "rank");
084: Rank modRank;
085: if (modRankString.equals("")) {
086: modRank = null;
087: } else {
088: modRank = Rank.getRank(modRankString);
089: }
090:
091: log.debug("Trying to load login module with name: "
092: + modName);
093:
094: // create the module...
095: LoginModule module;
096: try {
097: Class moduleClass = Class.forName(modClass);
098: module = (LoginModule) moduleClass.newInstance();
099: } catch (Exception e) {
100: log
101: .error("Could not create Login Module with class name "
102: + modClass);
103: throw new SecurityException(
104: "Could not create Login Module with class name "
105: + modClass);
106: }
107:
108: // retrieve the properties...
109: Map<String, Object> properties = new HashMap<String, Object>();
110: for (Element propTag : reader.getChildElements(modTag,
111: "property")) {
112: String propName = reader.getElementAttributeValue(
113: propTag, "name");
114: String propValue = reader.getElementValue(propTag)
115: .trim();
116: properties.put(propName, propValue);
117: log.debug("\tadding key : " + propName
118: + " with value : " + propValue);
119: }
120: properties.put("_parentFile", configResource);
121: // if module's configuration uses filenames, they probably want to be relative to this one.
122: module.load(properties);
123: modules.put(modName, module);
124: moduleRanks.put(modName, modRank);
125: log.debug("Loaded loginmodule with name: " + modName);
126: }
127: log.debug("Loaded all loginmodules " + listModules());
128: }
129:
130: public UserContext login(String moduleName, Map loginInfo,
131: Object[] parameters)
132: throws org.mmbase.security.SecurityException {
133: LoginModule module = modules.get(moduleName);
134: if (module == null) {
135: log
136: .error("Login Module with name '" + moduleName
137: + "' not found ! (available:"
138: + listModules() + ")");
139: throw new UnknownAuthenticationMethodException(
140: "Login Module with name '" + moduleName
141: + "' not found ! (available:"
142: + listModules() + ")");
143: }
144: NameContext newUser = new NameContext(moduleRanks
145: .get(moduleName), moduleName);
146: if (module.login(newUser, loginInfo, parameters)) {
147: // our login succeeded..
148: // check if the identifier was set by the loginModule, when invalid will trow exception..
149: newUser.getIdentifier();
150: return newUser;
151: }
152: return null;
153: }
154:
155: private String listModules() {
156: StringBuffer loginModulesAvailable = new StringBuffer();
157: for (String mod : modules.keySet()) {
158: loginModulesAvailable.append("\"").append(mod)
159: .append("\" ");
160: }
161: return loginModulesAvailable.toString();
162: }
163:
164: /**
165: * this method does nothing..
166: */
167: public boolean isValid(UserContext usercontext)
168: throws org.mmbase.security.SecurityException {
169: return true;
170: }
171: }
|