You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2005/05/17 02:28:29 UTC
svn commit: r170494 - in /geronimo/trunk/modules:
axis-builder/src/java/org/apache/geronimo/axis/builder/
jetty/src/java/org/apache/geronimo/jetty/
jetty/src/test/org/apache/geronimo/jetty/
security/src/java/org/apache/geronimo/security/realm/providers/
webservices/src/java/org/apache/geronimo/webservices/
Author: djencks
Date: Mon May 16 17:28:28 2005
New Revision: 170494
URL: http://svn.apache.org/viewcvs?rev=170494&view=rev
Log:
GERONIMO-648 add security for ejb web services
Added:
geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallback.java
geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.java
geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLoginModule.java
geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java
geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java
- copied, changed from r169699, geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java
Removed:
geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java
Modified:
geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java
geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java
geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java
geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java
geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/ContainerTest.java
geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/SoapHandler.java
Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java (original)
+++ geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java Mon May 16 17:28:28 2005
@@ -112,7 +112,7 @@
try {
classLoader.loadClass(seiClassName);
} catch (ClassNotFoundException e) {
- throw new DeploymentException("Unable to load servlet class for pojo webservice: "+seiClassName, e);
+ throw new DeploymentException("Unable to load servlet class for pojo webservice: " + seiClassName, e);
}
targetGBean.setAttribute("pojoClassName", seiClassName);
@@ -165,7 +165,7 @@
SchemaInfoBuilder schemaInfoBuilder = null;
JavaWsdlMappingType mapping = null;
if (wsdlURI != null) {
- schemaInfoBuilder = new SchemaInfoBuilder(moduleFile, wsdlURI);
+ schemaInfoBuilder = new SchemaInfoBuilder(moduleFile, wsdlURI);
mapping = WSDescriptorParser.readJaxrpcMapping(moduleFile, jaxrpcMappingURI);
}
@@ -237,9 +237,6 @@
}
Map exceptionMap = WSDescriptorParser.getExceptionMap(mapping);
-// Map schemaTypeKeyToSchemaTypeMap = schemaInfoBuilder.getSchemaTypeKeyToSchemaTypeMap();
-// Map complexTypeMap = schemaInfoBuilder.getComplexTypesInWsdl();
-// Map elementMap = schemaInfoBuilder.getElementToTypeMap();
Map wsdlPortMap = service.getPorts();
for (Iterator iterator = wsdlPortMap.entrySet().iterator(); iterator.hasNext();) {
@@ -257,7 +254,7 @@
ServiceEndpointInterfaceMappingType[] endpointMappings = mapping.getServiceEndpointInterfaceMappingArray();
- String credentialsName = credentialsNameMap == null? null: (String) credentialsNameMap.get(port.getName());
+ String credentialsName = credentialsNameMap == null ? null : (String) credentialsNameMap.get(port.getName());
//port type corresponds to SEI
List operations = portType.getOperations();
@@ -274,15 +271,20 @@
javax.wsdl.Service service;
if (serviceQName != null) {
service = definition.getService(serviceQName);
+ if (service == null) {
+ throw new DeploymentException("No service wsdl for supplied service qname " + serviceQName);
+ }
} else {
Map services = definition.getServices();
- if (services.size() != 1) {
+ if (services.size() > 1) {
throw new DeploymentException("no serviceQName supplied, and there are " + services.size() + " services");
}
- service = (javax.wsdl.Service) services.values().iterator().next();
- }
- if (service == null) {
- throw new DeploymentException("No service wsdl for supplied service qname " + serviceQName);
+ if (services.size() == 0) {
+ //partial wsdl
+ service = null;
+ } else {
+ service = (javax.wsdl.Service) services.values().iterator().next();
+ }
}
return service;
}
Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java (original)
+++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java Mon May 16 17:28:28 2005
@@ -19,6 +19,7 @@
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.Principal;
+import java.security.cert.X509Certificate;
import java.util.HashMap;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
@@ -27,8 +28,11 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.security.ContextManager;
import org.apache.geronimo.jetty.interceptor.SecurityContextBeforeAfter;
+import org.apache.geronimo.security.ContextManager;
+import org.apache.geronimo.security.realm.providers.CertificateCallbackHandler;
+import org.apache.geronimo.security.realm.providers.ClearableCallbackHandler;
+import org.apache.geronimo.security.realm.providers.PasswordCallbackHandler;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.UserRealm;
@@ -66,16 +70,22 @@
userMap.remove(username);
}
-
- char[] password;
+ ClearableCallbackHandler callbackHandler;
if (credentials instanceof char[]) {
- password = (char[]) credentials;
+ char[] password = (char[]) credentials;
+ callbackHandler = new PasswordCallbackHandler(username, password);
} else if (credentials instanceof String) {
- password = ((String) credentials).toCharArray();
+ char[] password = ((String) credentials).toCharArray();
+ callbackHandler = new PasswordCallbackHandler(username, password);
+ } else if (credentials instanceof X509Certificate[]) {
+ X509Certificate[] certs = (X509Certificate[]) credentials;
+ if (certs.length < 1) {
+ throw new LoginException("no certificates supplied");
+ }
+ callbackHandler = new CertificateCallbackHandler(certs[0]);
} else {
throw new LoginException("Cannot extract credentials from class: " + credentials.getClass().getName());
}
- PasswordCallbackHandler callbackHandler = new PasswordCallbackHandler(username, password);
//set up the login context
LoginContext loginContext = new LoginContext(loginDomainName, callbackHandler);
@@ -93,7 +103,7 @@
return userPrincipal;
} catch (LoginException e) {
- log.warn(e);
+ log.info("problem", e);
return null;
}
}
Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java (original)
+++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java Mon May 16 17:28:28 2005
@@ -132,8 +132,8 @@
server.removeRealm(realm.getName());
}
- public void addWebService(String contextPath, WebServiceContainer webServiceContainer) throws Exception {
- JettyEJBWebServiceContext webServiceContext = new JettyEJBWebServiceContext(contextPath, webServiceContainer);
+ public void addWebService(String contextPath, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) throws Exception {
+ JettyEJBWebServiceContext webServiceContext = new JettyEJBWebServiceContext(contextPath, webServiceContainer, securityRealmName, realmName, transportGuarantee, authMethod, classLoader);
addContext(webServiceContext);
webServiceContext.start();
webServices.put(contextPath, webServiceContext);
Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java (original)
+++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJBWebServiceContext.java Mon May 16 17:28:28 2005
@@ -25,31 +25,36 @@
import java.util.Map;
import org.apache.geronimo.webservices.WebServiceContainer;
+import org.mortbay.http.Authenticator;
+import org.mortbay.http.BasicAuthenticator;
+import org.mortbay.http.ClientCertAuthenticator;
+import org.mortbay.http.DigestAuthenticator;
import org.mortbay.http.HttpContext;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpHandler;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
+import org.mortbay.http.UserRealm;
/**
* Delegates requests to a WebServiceContainer which is presumably for an EJB WebService.
- *
+ * <p/>
* WebServiceContainer delegates to an EJBContainer that will ultimately provide the JNDI,
* TX, and Security services for this web service.
- *
+ * <p/>
* Nothing stopping us from using this for POJOs or other types of webservices if shared
* Context (JNDI, tx, security) wasn't required to be supplied by the web context.
- *
+ * <p/>
* From a 10,000 foot view the Jetty architecture has:
* Container -> Context -> Holder -> Servlet
- *
+ * <p/>
* A Container has multiple Contexts, typically webapps
* A Context provides the JNDI, TX, and Security for the webapp and has many Holders
* A Holder simply wraps each Servlet
- *
+ * <p/>
* The POJO Web Service architecture on Jetty looks like this:
* Container -> WebApp Context -> JettyPOJOWebServiceHolder -> POJOWebServiceServlet
- *
+ * <p/>
* The EJB Web Service architecure, on the other hand, creates one Context for each EJB:
* Container -> JettyEJBWebServiceContext
*
@@ -59,12 +64,51 @@
private final String contextPath;
private final WebServiceContainer webServiceContainer;
+ private final Authenticator authenticator;
+ private final UserRealm realm;
+ private final boolean isConfidentialTransportGuarantee;
+ private final boolean isIntegralTransportGuarantee;
+ private final ClassLoader classLoader;
private HttpContext httpContext;
- public JettyEJBWebServiceContext(String contextPath, WebServiceContainer webServiceContainer) {
+ public JettyEJBWebServiceContext(String contextPath, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) {
this.contextPath = contextPath;
this.webServiceContainer = webServiceContainer;
+ if (securityRealmName != null) {
+ JAASJettyRealm realm = new JAASJettyRealm(realmName, securityRealmName);
+ setRealm(realm);
+ this.realm = realm;
+ if ("NONE".equals(transportGuarantee)) {
+ isConfidentialTransportGuarantee = false;
+ isIntegralTransportGuarantee = false;
+ } else if ("INTEGRAL".equals(transportGuarantee)) {
+ isConfidentialTransportGuarantee = false;
+ isIntegralTransportGuarantee = true;
+ } else if ("CONFIDENTIAL".equals(transportGuarantee)) {
+ isConfidentialTransportGuarantee = true;
+ isIntegralTransportGuarantee = false;
+ } else {
+ throw new IllegalArgumentException("Invalid transport-guarantee: " + transportGuarantee);
+ }
+ if ("BASIC".equals(authMethod)) {
+ authenticator = new BasicAuthenticator();
+ } else if ("DIGEST".equals(authMethod)) {
+ authenticator = new DigestAuthenticator();
+ } else if ("CLIENT-CERT".equals(authMethod)) {
+ authenticator = new ClientCertAuthenticator();
+ } else if ("NONE".equals(authMethod)) {
+ authenticator = null;
+ } else {
+ throw new IllegalArgumentException("Invalid authMethod: " + authMethod);
+ }
+ } else {
+ realm = null;
+ authenticator = null;
+ isConfidentialTransportGuarantee = false;
+ isIntegralTransportGuarantee = false;
+ }
+ this.classLoader = classLoader;
}
public String getName() {
@@ -84,26 +128,49 @@
req.setContentType("text/xml");
RequestAdapter request = new RequestAdapter(req);
ResponseAdapter response = new ResponseAdapter(res);
-
+
if (req.getParameter("wsdl") != null) {
try {
- webServiceContainer.getWsdl(request,response);
+ webServiceContainer.getWsdl(request, response);
+ //WHO IS RESPONSIBLE FOR CLOSING OUT?
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw (HttpException) new HttpException(500, "Could not fetch wsdl!").initCause(e);
}
} else {
+ if (isConfidentialTransportGuarantee) {
+ if (!req.isConfidential()) {
+ throw new HttpException(403);
+ }
+ } else if (isIntegralTransportGuarantee) {
+ if (!req.isIntegral()) {
+ throw new HttpException(403);
+ }
+ }
+ Thread currentThread = Thread.currentThread();
+ ClassLoader oldClassLoader = currentThread.getContextClassLoader();
+ currentThread.setContextClassLoader(classLoader);
try {
- webServiceContainer.invoke(request,response);
- req.setHandled(true);
- } catch (IOException e) {
- throw e;
- } catch (Exception e) {
- throw (HttpException) new HttpException(500, "Could not process message!").initCause(e);
+ if (authenticator != null) {
+ String pathInContext = org.mortbay.util.URI.canonicalPath(req.getPath());
+ if (authenticator.authenticate(realm, pathInContext, req, res) == null) {
+ throw new HttpException(403);
+ }
+ }
+ try {
+ webServiceContainer.invoke(request, response);
+ req.setHandled(true);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ throw (HttpException) new HttpException(500, "Could not process message!").initCause(e);
+ }
+ } finally {
+ currentThread.setContextClassLoader(oldClassLoader);
}
}
-
+
}
public String getContextPath() {
@@ -123,9 +190,9 @@
}
public java.net.URI getURI() {
- if( uri==null ) {
+ if (uri == null) {
try {
- String uriString = request.getScheme()+"://"+request.getHost()+":"+request.getPort()+request.getURI();
+ String uriString = request.getScheme() + "://" + request.getHost() + ":" + request.getPort() + request.getURI();
//return new java.net.URI(uri.getScheme(),uri.getHost(),uri.getPath(),uri.);
uri = new java.net.URI(uriString);
} catch (URISyntaxException e) {
@@ -149,7 +216,7 @@
public int getMethod() {
Integer method = (Integer) methods.get(request.getMethod());
- return method == null ? UNSUPPORTED: method.intValue();
+ return method == null ? UNSUPPORTED : method.intValue();
}
public String getParameter(String name) {
@@ -164,7 +231,7 @@
return request.getAttribute(name);
}
- public void setAttribute(String name, Object value){
+ public void setAttribute(String name, Object value) {
request.setAttribute(name, value);
}
Modified: geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/ContainerTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/ContainerTest.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/ContainerTest.java (original)
+++ geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/ContainerTest.java Mon May 16 17:28:28 2005
@@ -79,7 +79,7 @@
String contextPath = "/foo/webservice.ws";
MockWebServiceContainer webServiceInvoker = new MockWebServiceContainer();
- kernel.invoke(containerName, "addWebService", new Object[] {contextPath, webServiceInvoker}, new String[] {String.class.getName(), WebServiceContainer.class.getName()});
+ kernel.invoke(containerName, "addWebService", new Object[] {contextPath, webServiceInvoker, null, null, null, null,cl}, new String[] {String.class.getName(), WebServiceContainer.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), ClassLoader.class.getName()});
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:5678" + contextPath).openConnection();
try {
Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallback.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallback.java?rev=170494&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallback.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallback.java Mon May 16 17:28:28 2005
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.security.realm.providers;
+
+import java.security.cert.X509Certificate;
+import javax.security.auth.callback.Callback;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public class CertificateCallback implements Callback {
+ X509Certificate certificate;
+
+ public X509Certificate getCertificate() {
+ return certificate;
+ }
+
+ public void setCertificate(X509Certificate certificate) {
+ this.certificate = certificate;
+ }
+}
Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.java?rev=170494&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.java Mon May 16 17:28:28 2005
@@ -0,0 +1,48 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.security.realm.providers;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public class CertificateCallbackHandler implements ClearableCallbackHandler {
+ X509Certificate certificate;
+ public CertificateCallbackHandler(X509Certificate certificate) {
+ this.certificate = certificate;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof CertificateCallback) {
+ CertificateCallback cc = (CertificateCallback) callback;
+ cc.setCertificate(certificate);
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+
+ public void clear() {
+ certificate = null;
+ }
+}
Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLoginModule.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLoginModule.java?rev=170494&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLoginModule.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLoginModule.java Mon May 16 17:28:28 2005
@@ -0,0 +1,216 @@
+/**
+ *
+ * Copyright 2003-2005 The Apache Software Foundation
+ *
+ * Licensed 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.security.realm.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Collection;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.security.auth.x500.X500Principal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.common.GeronimoSecurityException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.kernel.KernelRegistry;
+import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
+import org.apache.geronimo.system.serverinfo.ServerInfo;
+
+
+/**
+ * An example LoginModule that reads a list of users and group from a file on disk.
+ * Authentication is provided by the SSL layer supplying the client certificate.
+ * All we check is that it is present. The
+ * file should be formatted using standard Java properties syntax. Expects
+ * to be run by a GenericSecurityRealm (doesn't work on its own).
+ *
+ * The usersURI property file should have lines of the form token=certificatename
+ * where certificate name is X509Certificate.getSubjectX500Principal().getName()
+ *
+ * The groupsURI property file should have lines of the form group=token1,token2,...
+ * where the tokens were associated to the certificate names in the usersURI properties file.
+ *
+ * @version $Rev: 169154 $ $Date: 2005-05-08 12:35:23 -0700 (Sun, 08 May 2005) $
+ */
+public class CertificatePropertiesFileLoginModule implements LoginModule {
+ public final static String USERS_URI = "usersURI";
+ public final static String GROUPS_URI = "groupsURI";
+ private static Log log = LogFactory.getLog(CertificatePropertiesFileLoginModule.class);
+ private final Map users = new HashMap();
+ final Map groups = new HashMap();
+
+ Subject subject;
+ CallbackHandler handler;
+ X500Principal principal;
+
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+ this.subject = subject;
+ this.handler = callbackHandler;
+ try {
+ Kernel kernel = KernelRegistry.getKernel((String)options.get(JaasLoginModuleUse.KERNEL_LM_OPTION));
+ ServerInfo serverInfo = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
+ URI usersURI = new URI((String)options.get(USERS_URI));
+ URI groupsURI = new URI((String)options.get(GROUPS_URI));
+ loadProperties(kernel, serverInfo, usersURI, groupsURI);
+ } catch (Exception e) {
+ log.error(e);
+ throw new IllegalArgumentException("Unable to configure properties file login module: "+e);
+ }
+ }
+
+ public void loadProperties(Kernel kernel, ServerInfo serverInfo, URI usersURI, URI groupURI) throws GeronimoSecurityException {
+ try {
+ URI userFile = serverInfo.resolve(usersURI);
+ URI groupFile = serverInfo.resolve(groupURI);
+ InputStream stream = userFile.toURL().openStream();
+ Properties tmpUsers = new Properties();
+ tmpUsers.load(stream);
+ stream.close();
+
+ for (Iterator iterator = tmpUsers.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ users.put(entry.getValue(), entry.getKey());
+ }
+
+ Properties temp = new Properties();
+ stream = groupFile.toURL().openStream();
+ temp.load(stream);
+ stream.close();
+
+ Enumeration e = temp.keys();
+ while (e.hasMoreElements()) {
+ String groupName = (String) e.nextElement();
+ String[] userList = ((String) temp.get(groupName)).split(",");
+
+ Set userset = (Set) groups.get(groupName);
+ if (userset == null) {
+ userset = new HashSet();
+ groups.put(groupName, userset);
+ }
+
+ for (int i = 0; i < userList.length; i++) {
+ String userName = userList[i];
+ userset.add(userName);
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Properties File Login Module - data load failed", e);
+ throw new GeronimoSecurityException(e);
+ }
+ }
+
+
+ public boolean login() throws LoginException {
+ Callback[] callbacks = new Callback[1];
+
+ callbacks[0] = new CertificateCallback();
+ try {
+ handler.handle(callbacks);
+ } catch (IOException ioe) {
+ throw (LoginException) new LoginException().initCause(ioe);
+ } catch (UnsupportedCallbackException uce) {
+ throw (LoginException) new LoginException().initCause(uce);
+ }
+ assert callbacks.length == 1;
+ X509Certificate certificate = ((CertificateCallback)callbacks[0]).getCertificate();
+ if (certificate == null) {
+ return false;
+ }
+ principal = certificate.getSubjectX500Principal();
+
+ return users.containsKey(principal.getName());
+ }
+
+ public boolean commit() throws LoginException {
+ Set principals = subject.getPrincipals();
+
+ principals.add(principal);
+ String userName = (String) users.get(principal.getName());
+ principals.add(new GeronimoUserPrincipal(userName));
+
+ Iterator e = groups.keySet().iterator();
+ while (e.hasNext()) {
+ String groupName = (String) e.next();
+ Set users = (Set) groups.get(groupName);
+ Iterator iter = users.iterator();
+ while (iter.hasNext()) {
+ String user = (String) iter.next();
+ if (userName.equals(user)) {
+ principals.add(new GeronimoGroupPrincipal(groupName));
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean abort() throws LoginException {
+ principal = null;
+
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+ principal = null;
+
+ return true;
+ }
+
+ /**
+ * Gets the names of all principal classes that may be populated into
+ * a Subject.
+ */
+ public String[] getPrincipalClassNames() {
+ return new String[]{GeronimoUserPrincipal.class.getName(), GeronimoGroupPrincipal.class.getName()};
+ }
+
+ /**
+ * Gets a list of all the principals of a particular type (identified by
+ * the principal class). These are available for manual role mapping.
+ */
+ public String[] getPrincipalsOfClass(String className) {
+ Collection s;
+ if(className.equals(GeronimoGroupPrincipal.class.getName())) {
+ s = groups.keySet();
+ } else if(className.equals(GeronimoUserPrincipal.class.getName())) {
+ s = users.values();
+ } else if(className.equals(X500Principal.class.getName())) {
+ s = users.keySet();
+ } else {
+ throw new IllegalArgumentException("No such principal class "+className);
+ }
+ return (String[]) s.toArray(new String[s.size()]);
+ }
+}
Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java?rev=170494&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java Mon May 16 17:28:28 2005
@@ -0,0 +1,26 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed 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.security.realm.providers;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public interface ClearableCallbackHandler extends CallbackHandler {
+ void clear();
+}
Copied: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java (from r169699, geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java)
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java?p2=geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java&p1=geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java&r1=169699&r2=170494&rev=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java (original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java Mon May 16 17:28:28 2005
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.geronimo.jetty;
+package org.apache.geronimo.security.realm.providers;
import java.util.Arrays;
import javax.security.auth.callback.Callback;
@@ -26,7 +26,7 @@
/**
* @version $Revision$ $Date$
*/
-public class PasswordCallbackHandler implements CallbackHandler {
+public class PasswordCallbackHandler implements ClearableCallbackHandler {
private final String username;
private final char[] password;
Modified: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/SoapHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/SoapHandler.java?rev=170494&r1=170493&r2=170494&view=diff
==============================================================================
--- geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/SoapHandler.java (original)
+++ geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webservices/SoapHandler.java Mon May 16 17:28:28 2005
@@ -21,7 +21,7 @@
*/
public interface SoapHandler {
- void addWebService(String contextPath, WebServiceContainer webServiceContainer) throws Exception;
+ void addWebService(String contextPath, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) throws Exception;
void removeWebService(String contextPath);