blob: 5dd426d6057e0cbc68dfe4bbfc9c23a85adf6af1 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.components.jaspi;
import org.apache.geronimo.components.jaspi.model.ConfigProviderType;
import org.apache.geronimo.components.jaspi.model.JaspiType;
import org.apache.geronimo.components.jaspi.model.JaspiXmlUtil;
import org.xml.sax.SAXException;
import javax.security.auth.AuthPermission;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.config.AuthConfigFactory;
import javax.security.auth.message.config.AuthConfigProvider;
import javax.security.auth.message.config.RegistrationListener;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Implementation of the AuthConfigFactory.
*
* @version $Rev: $ $Date: $
*/
public class AuthConfigFactoryImpl extends AuthConfigFactory {
public static final String JASPI_CONFIGURATION_FILE = "org.apache.geronimo.jaspic.configurationFile";
private static final File DEFAULT_CONFIG_FILE = new File("var/config/security/jaspic/jaspic.xml");
public static CallbackHandler staticCallbackHandler;
private static ClassLoader contextClassLoader;
private JaspiType jaspiType = new JaspiType();
private final CallbackHandler callbackHandler;
private final File configFile;
static {
contextClassLoader = java.security.AccessController
.doPrivileged(new java.security.PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
}
public AuthConfigFactoryImpl(CallbackHandler callbackHandler, File configFile) {
JaspiXmlUtil.initialize(callbackHandler);
this.callbackHandler = callbackHandler;
this.configFile = configFile;
loadConfig();
}
public AuthConfigFactoryImpl() {
this(staticCallbackHandler, getConfigFile());
}
private static File getConfigFile() {
String fileLocation = java.security.AccessController
.doPrivileged(new java.security.PrivilegedAction<String>() {
public String run() {
return System.getProperty(JASPI_CONFIGURATION_FILE);
}
});
File file;
if (fileLocation == null) {
file = DEFAULT_CONFIG_FILE;
} else {
file = new File(fileLocation);
}
return file;
}
public synchronized String[] detachListener(RegistrationListener listener, String layer, String appContext) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AuthPermission("detachAuthListener"));
}
List<String> ids = new ArrayList<String>();
for (Map.Entry<String, ConfigProviderType> entry : getRegistrations().entrySet()) {
ConfigProviderType ctx = entry.getValue();
if ((layer == null || layer.equals(ctx.getMessageLayer())) &&
(appContext == null || appContext.equals(ctx.getAppContext()))) {
if (ctx.getListeners().remove(listener)) {
ids.add(entry.getKey());
}
}
}
return ids.toArray(new String[ids.size()]);
}
private Map<String, ConfigProviderType> getRegistrations() {
return jaspiType.getConfigProvider();
}
public synchronized AuthConfigProvider getConfigProvider(String layer, String appContext, RegistrationListener listener) {
if (layer == null) {
throw new NullPointerException("messageLayer");
}
if (appContext == null) {
throw new NullPointerException("appContext");
}
ConfigProviderType ctx = getRegistrations().get(ConfigProviderType.getRegistrationKey(layer, appContext));
if (ctx == null) {
ctx = getRegistrations().get(ConfigProviderType.getRegistrationKey(null, appContext));
}
if (ctx == null) {
ctx = getRegistrations().get(ConfigProviderType.getRegistrationKey(layer, null));
}
if (ctx == null) {
ctx = getRegistrations().get(ConfigProviderType.getRegistrationKey(null, null));
}
if (ctx != null) {
if (listener != null) {
ctx.getListeners().add(listener);
}
return ctx.getProvider();
}
return null;
}
public synchronized RegistrationContext getRegistrationContext(String registrationID) {
return getRegistrations().get(registrationID);
}
public synchronized String[] getRegistrationIDs(AuthConfigProvider provider) {
List<String> ids = new ArrayList<String>();
for (Map.Entry<String, ConfigProviderType> entry : getRegistrations().entrySet()) {
ConfigProviderType ctx = entry.getValue();
if (provider == null ||
provider.getClass().getName().equals(ctx.getProvider().getClass().getName())) {
ids.add(entry.getKey());
}
}
return ids.toArray(new String[ids.size()]);
}
public synchronized void refresh() throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AuthPermission("refreshAuth"));
}
loadConfig();
}
public String registerConfigProvider(AuthConfigProvider authConfigProvider, String layer, String appContext, String description) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AuthPermission("registerAuthConfigProvider"));
}
return registerConfigProvider(authConfigProvider, layer, appContext, description, false, null, null);
}
public synchronized String registerConfigProvider(final String className, final Map constructorParam, String layer, String appContext, String description) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AuthPermission("registerAuthConfigProvider"));
}
String key = registerConfigProvider(null, layer, appContext, description, true, constructorParam, className);
saveConfig();
return key;
}
private String registerConfigProvider(AuthConfigProvider provider, String layer, String appContext, String description, boolean persistent, Map<String, String> constructorParam, String className) {
String key = ConfigProviderType.getRegistrationKey(layer, appContext);
// Get or create context
ConfigProviderType ctx = getRegistrations().get(key);
if (ctx == null) {
ctx = new ConfigProviderType(layer, appContext, persistent, persistent? null: this);
getRegistrations().put(key, ctx);
} else {
if (persistent != ctx.isPersistent()) {
throw new IllegalArgumentException("Cannot change the persistence state");
}
}
// Create provider
ctx.setDescription(description);
if (persistent) {
if (provider != null) {
throw new IllegalStateException("Config provider supplied but should be created");
}
ctx.setClassName(className);
ctx.setProperties(constructorParam);
ctx.initialize(callbackHandler);
} else {
if (provider == null) {
throw new IllegalStateException("No config provider to set");
}
ctx.setProvider(provider);
}
// Notify listeners
List<RegistrationListener> listeners = ctx.getListeners();
for (RegistrationListener listener : listeners) {
listener.notify(ctx.getMessageLayer(), ctx.getAppContext());
}
// Return registration Id
return key;
}
public synchronized boolean removeRegistration(String registrationID) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AuthPermission("removeAuthRegistration"));
}
ConfigProviderType ctx = getRegistrations().remove(registrationID);
saveConfig();
if (ctx != null) {
List<RegistrationListener> listeners = ctx.getListeners();
for (RegistrationListener listener : listeners) {
listener.notify(ctx.getMessageLayer(), ctx.getAppContext());
}
return true;
}
return false;
}
private void loadConfig() {
if (configFile != null && configFile.length() > 0) {
try {
FileReader in = new FileReader(configFile);
try {
jaspiType = JaspiXmlUtil.loadJaspi(in);
} finally {
in.close();
}
} catch (ParserConfigurationException e) {
throw new SecurityException("Could not read config", e);
} catch (IOException e) {
throw new SecurityException("Could not read config", e);
} catch (SAXException e) {
throw new SecurityException("Could not read config", e);
} catch (JAXBException e) {
throw new SecurityException("Could not read config", e);
} catch (XMLStreamException e) {
throw new SecurityException("Could not read config", e);
}
}
}
private void saveConfig() {
if (configFile != null) {
try {
OutputStream outStream = new FileOutputStream(configFile);
Writer out = new OutputStreamWriter(outStream, "UTF-8");
try {
JaspiXmlUtil.writeJaspi(jaspiType, out);
} finally {
out.close();
}
} catch (IOException e) {
throw new SecurityException("Could not write config", e);
} catch (XMLStreamException e) {
throw new SecurityException("Could not write config", e);
} catch (JAXBException e) {
throw new SecurityException("Could not write config", e);
}
}
}
}