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: package org.mmbase.security.classsecurity;
011:
012: import java.util.*;
013:
014: import org.mmbase.security.*;
015: import org.mmbase.security.SecurityException;
016: import org.mmbase.util.*;
017: import org.mmbase.util.logging.*;
018: import org.mmbase.util.xml.DocumentReader;
019: import org.w3c.dom.*;
020: import org.xml.sax.InputSource;
021: import org.xml.sax.SAXException;
022:
023: /**
024: * ClassAuthenticationWrapper wraps another Authentication implemention, and adds an extra
025: * configuration file. In this configuration file the wrapped Authentication can be specified (and
026: * <em>its</em> configuration file if it needs one). Besides that, also authentication credentials
027: * can be linked to classes in this XML configuration file.
028: *
029: * @author Michiel Meeuwissen
030: * @version $Id: ClassAuthenticationWrapper.java,v 1.7 2005/01/30 16:46:39 nico Exp $
031: * @since MMBase-1.8
032: */
033: public class ClassAuthenticationWrapper extends Authentication {
034: private static final Logger log = Logging
035: .getLoggerInstance(ClassAuthenticationWrapper.class);
036:
037: private Authentication wrappedAuthentication;
038:
039: /**
040: * Instantiates an Authentication implementation
041: */
042: private Authentication getAuthenticationInstance(String className)
043: throws SecurityException {
044: Authentication result;
045: try {
046: Class classType = Class.forName(className);
047: Object o = classType.newInstance();
048: result = (Authentication) o;
049: } catch (ClassNotFoundException cnfe) {
050: throw new SecurityException(cnfe);
051: } catch (IllegalAccessException iae) {
052: throw new SecurityException(iae);
053: } catch (InstantiationException ie) {
054: throw new SecurityException(ie);
055: }
056: return result;
057: }
058:
059: /**
060: * {@inheritDoc}
061: * Reads the configuration file and instantiates and loads the wrapped Authentication.
062: */
063: protected void load() throws SecurityException {
064: try {
065: InputSource in = MMBaseCopConfig.securityLoader
066: .getInputSource(configResource);
067: Document document = DocumentReader.getDocumentBuilder(true, // validate aggresively, because no further error-handling will be done
068: new XMLErrorHandler(false, 0), // don't log, throw exception if not valid, otherwise big chance on NPE and so on
069: new XMLEntityResolver(true, getClass()) // validate
070: ).parse(in);
071:
072: Node authentication = document.getElementsByTagName(
073: "authentication").item(0);
074:
075: String wrappedClass = authentication.getAttributes()
076: .getNamedItem("class").getNodeValue();
077: String wrappedUrl = authentication.getAttributes()
078: .getNamedItem("url").getNodeValue();
079:
080: wrappedAuthentication = getAuthenticationInstance(wrappedClass);
081: wrappedAuthentication.load(manager, configWatcher,
082: wrappedUrl);
083: ClassAuthentication.stopWatching();
084: ClassAuthentication.load(configResource);
085:
086: } catch (java.io.IOException ioe) {
087: throw new SecurityException(ioe);
088: } catch (SAXException se) {
089: throw new SecurityException(se);
090: }
091:
092: }
093:
094: /**
095: * logs-in using the first match on the class from the configuration file.
096: * @param loginInfo If there are possible credentials already, they can be in this map. The new
097: * one will be added. If it is null, a new Map is instantiated.
098: * @param parameters Required by the login method of Authentication. I think noone ever uses it.
099: */
100: protected UserContext login(Map loginInfo, Object[] parameters)
101: throws SecurityException {
102: ClassAuthentication.Login l = ClassAuthentication
103: .classCheck(null);
104: if (l != null) {
105: if (loginInfo == null)
106: loginInfo = new HashMap();
107: loginInfo.putAll(l.map);
108: return wrappedAuthentication.login(l.application,
109: loginInfo, parameters);
110: }
111: return null;
112: }
113:
114: /**
115: * {@inheritDoc}
116: */
117: public UserContext login(String application, Map loginInfo,
118: Object[] parameters) throws SecurityException {
119:
120: // first try 'cleanly':
121: try {
122: return wrappedAuthentication.login(application, loginInfo,
123: parameters);
124: } catch (UnknownAuthenticationMethodException uam) { // no luck
125: return login(loginInfo, parameters);
126: } catch (SecurityException se) { // perhaps not recognized
127: log.warn("Authentication did not succeed "
128: + se.getMessage() + " trying self");
129: return login(loginInfo, parameters);
130: }
131: }
132:
133: /**
134: * {@inheritDoc}
135: */
136: public boolean isValid(UserContext userContext)
137: throws SecurityException {
138: return wrappedAuthentication.isValid(userContext);
139: }
140:
141: }
|