You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/03/25 05:26:56 UTC
svn commit: r522150 - in /incubator/openejb/trunk/openejb3:
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
container/openejb-core/src/main/java/org/apache/openejb/config/
server/openejb-client/src/main/java/org/apache/openej...
Author: dain
Date: Sat Mar 24 20:26:50 2007
New Revision: 522150
URL: http://svn.apache.org/viewvc?view=rev&rev=522150
Log:
Added client side login module
Added:
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientIdentityPrincipal.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientLoginModule.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/StaticUsernamePasswordCallbackHandler.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/UsernamePasswordCallbackHandler.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/client.login.conf
incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/ClientLoginTest.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/LoginTestUtil.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
Removed:
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/App.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/AppTest.java
Modified:
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ClientInfo.java
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java
incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Main.java
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?view=diff&rev=522150&r1=522149&r2=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Sat Mar 24 20:26:50 2007
@@ -434,6 +434,9 @@
if (clientInfo.mainClass != null) {
containerSystem.getJNDIContext().bind("java:openejb/client/" + clientInfo.moduleId + "/comp/mainClass", clientInfo.mainClass);
}
+ if (clientInfo.callbackHandler != null) {
+ containerSystem.getJNDIContext().bind("java:openejb/client/" + clientInfo.moduleId + "/comp/callbackHandler", clientInfo.callbackHandler);
+ }
ArrayList<Injection> injections = new ArrayList<Injection>();
JndiEncInfo jndiEnc = clientInfo.jndiEnc;
for (EjbReferenceInfo info : jndiEnc.ejbReferences) {
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ClientInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ClientInfo.java?view=diff&rev=522150&r1=522149&r2=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ClientInfo.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ClientInfo.java Sat Mar 24 20:26:50 2007
@@ -28,7 +28,8 @@
public String largeIcon;
public String moduleId;
public String mainClass;
-
+ public String callbackHandler;
+
public JndiEncInfo jndiEnc;
public final List<CallbackInfo> postConstruct = new ArrayList<CallbackInfo>();
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java?view=diff&rev=522150&r1=522149&r2=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java Sat Mar 24 20:26:50 2007
@@ -354,6 +354,7 @@
clientInfo.displayName = applicationClient.getDisplayName();
clientInfo.codebase = clientModule.getJarLocation();
clientInfo.mainClass = clientModule.getMainClass();
+ clientInfo.callbackHandler = applicationClient.getCallbackHandler();
clientInfo.moduleId = getClientModuleId(clientModule);
JndiEncInfoBuilder jndiEncInfoBuilder = new JndiEncInfoBuilder(appInfo.ejbJars);
Modified: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java?view=diff&rev=522150&r1=522149&r2=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java (original)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java Sat Mar 24 20:26:50 2007
@@ -18,7 +18,6 @@
import java.io.IOException;
import java.io.ObjectInput;
-import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
@@ -28,10 +27,20 @@
import java.util.logging.Logger;
public class Client {
+ private static final Logger logger = Logger.getLogger("OpenEJB.client");
- private static Logger logger = Logger.getLogger(Client.class.getName());
+ private static Client client = new Client();
+
+ // This lame hook point if only of testing
+ public static void setClient(Client client) {
+ Client.client = client;
+ }
public static Response request(Request req, Response res, ServerMetaData server) throws RemoteException {
+ return client.processRequest(req, res, server);
+ }
+
+ protected Response processRequest(Request req, Response res, ServerMetaData server) throws RemoteException {
if (server == null)
throw new IllegalArgumentException("Server instance cannot be null");
@@ -56,7 +65,7 @@
}
}
- //If no servers responded, thow an error
+ // If no servers responded, throw an error
if (conn == null) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < uris.length; i++) {
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientIdentityPrincipal.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientIdentityPrincipal.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientIdentityPrincipal.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientIdentityPrincipal.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,40 @@
+/**
+ *
+ * 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.openejb.client;
+
+import java.security.Principal;
+import java.io.Serializable;
+
+public class ClientIdentityPrincipal implements Principal, Serializable {
+ private static final long serialVersionUID = -4620883427203231384L;
+ private final String name;
+ private final Object clientIdentity;
+
+ public ClientIdentityPrincipal(String name, Object clientIdentity) {
+ this.name = name;
+ this.clientIdentity = clientIdentity;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getClientIdentity() {
+ return clientIdentity;
+ }
+}
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientLoginModule.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientLoginModule.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientLoginModule.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/ClientLoginModule.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,151 @@
+/**
+ *
+ * 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.openejb.client;
+
+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.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.spi.LoginModule;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.rmi.RemoteException;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class ClientLoginModule implements LoginModule {
+ private static final Logger log = Logger.getLogger("OpenEJB.client");
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+ private String serverUri;
+ private boolean debug;
+
+ private String user;
+ private Object clientIdentity;
+ private ClientIdentityPrincipal principal;
+
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+
+ // determine the server uri
+ serverUri = System.getProperty("openejb.server.uri");
+ if (serverUri == null) {
+ serverUri = (String) options.get("openejb.server.uri");
+ }
+
+ this.debug = "true".equalsIgnoreCase((String) options.get("debug"));
+ if (debug) {
+ log.config("Initialized ClientLoginModule: debug=" + debug);
+ }
+ }
+
+ public boolean login() throws LoginException {
+ // determine the server location
+ URI location = null;
+ try {
+ location = new URI(serverUri);
+ } catch (Exception e) {
+ if (serverUri.indexOf("://") == -1) {
+ try {
+ location = new URI("foo://" + serverUri);
+ } catch (URISyntaxException giveUp) {
+ throw new LoginException("Invalid openejb.server.uri " + serverUri);
+ }
+ }
+ }
+ ServerMetaData server = new ServerMetaData(location);
+
+ // create the callbacks
+ Callback[] callbacks = new Callback[2];
+ callbacks[0] = new NameCallback("Username: ");
+ callbacks[1] = new PasswordCallback("Password: ", false);
+
+ // get the call back values (username and password)
+ try {
+ callbackHandler.handle(callbacks);
+ } catch (IOException ioe) {
+ throw new LoginException(ioe.getMessage());
+ } catch (UnsupportedCallbackException uce) {
+ throw new LoginException(uce.getMessage() + " not available to obtain information from user");
+ }
+ user = ((NameCallback) callbacks[0]).getName();
+ char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
+ if (tmpPassword == null) tmpPassword = new char[0];
+
+ // authenticate
+ AuthenticationRequest authReq = new AuthenticationRequest(user, new String(tmpPassword));
+ AuthenticationResponse authRes;
+ try {
+ authRes = (AuthenticationResponse) Client.request(authReq, new AuthenticationResponse(), server);
+ } catch (RemoteException e) {
+ throw (LoginException) new LoginException("Unable to authenticate with server " + serverUri).initCause(e);
+ }
+
+ // check the response
+ if (authRes.getResponseCode() == ResponseCodes.AUTH_GRANTED) {
+ clientIdentity = authRes.getIdentity().getClientIdentity();
+ } else {
+ throw new FailedLoginException("This principle is not authorized.");
+ }
+
+ if (debug) {
+ log.config("login " + user);
+ }
+ return true;
+ }
+
+ public boolean commit() throws LoginException {
+ principal = new ClientIdentityPrincipal(user, clientIdentity);
+ subject.getPrincipals().add(principal);
+
+ if (debug) {
+ log.config("commit");
+ }
+ return true;
+ }
+
+ public boolean abort() throws LoginException {
+ clear();
+
+ if (debug) {
+ log.config("abort");
+ }
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+ subject.getPrincipals().remove(principal);
+
+ if (debug) {
+ log.config("logout");
+ }
+ return true;
+ }
+
+ private void clear() {
+ user = null;
+ clientIdentity = null;
+ principal = null;
+ }
+}
Modified: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Main.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Main.java?view=diff&rev=522150&r1=522149&r2=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Main.java (original)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/Main.java Sat Mar 24 20:26:50 2007
@@ -18,15 +18,21 @@
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
+import javax.naming.NameNotFoundException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
import java.io.File;
-import java.net.URLClassLoader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
import java.net.URL;
+import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
/**
* @version $Rev$ $Date$
@@ -37,19 +43,38 @@
System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, "org.apache.openejb.client");
+ // the new initial context is automatically hooked up to the server side
+ // java:openejb/client/${clientModuleId} tree
InitialContext initialContext = new InitialContext();
-
+ // path to the client jar file
String path = (String) initialContext.lookup("java:comp/path");
// TODO: Download the file
File file = new File(path);
+ // Create a child class loader containing the application jar
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- classLoader = new URLClassLoader(new URL[]{file.toURL()}, classLoader);
+ if (classLoader == null) {
+ classLoader = new URLClassLoader(new URL[]{file.toURL()});
+ } else {
+ classLoader = new URLClassLoader(new URL[]{file.toURL()}, classLoader);
+ }
+ Thread.currentThread().setContextClassLoader(classLoader);
+ // load the main class and get the main method
+ // do this first so we fail fast on a bad class path
String mainClassName = (String) initialContext.lookup("java:comp/mainClass");
-
Class mainClass = classLoader.loadClass(mainClassName);
+ final Method mainMethod = mainClass.getMethod("main", String[].class);
+
+ // load the callback handler class
+ // again do this before any major work so we can fail fase
+ Class callbackHandlerClass = null;
+ try {
+ String callbackHandlerName = (String) initialContext.lookup("java:comp/callbackHandler");
+ callbackHandlerClass = classLoader.loadClass(callbackHandlerName);
+ } catch (NameNotFoundException ignored) {
+ }
InjectionMetaData injectionMetaData = (InjectionMetaData) initialContext.lookup("java:comp/injections");
for (Injection injection : injectionMetaData.getInjections()) {
@@ -65,13 +90,66 @@
}
}
- Method mainMethod = mainClass.getMethod("main", args.getClass());
- mainMethod.invoke(null, new Object[]{args});
+ // if there is no security then just call the main method
+ final Object[] mainArgs = new Object[] {args};
+ if (callbackHandlerClass == null) {
+ invoke(mainMethod, mainArgs);
+ } else {
+ // create the callback handler
+ CallbackHandler callbackHandler = (CallbackHandler) callbackHandlerClass.newInstance();
+
+ // initialize the jaas system
+ loadJassLoginConfig(classLoader);
+
+ // login
+ LoginContext loginContext = new LoginContext("ClientLogin", callbackHandler);
+ loginContext.login();
+ // success - get the subject
+ Subject subject = loginContext.getSubject();
+
+ // call the main method in a doAs so the subject is associated with the thread
+ try {
+ Subject.doAs(subject, new PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ invoke(mainMethod, mainArgs);
+ return null;
+ }
+ });
+ } finally {
+ // And finally, logout
+ loginContext.logout();
+ }
+ }
+ }
+
+ private static void invoke(Method mainMethod, Object[] mainArgs) throws Exception {
+ try {
+ mainMethod.invoke(null, mainArgs);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof Exception) {
+ throw (Exception) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+ throw new Error(e);
+ }
+ }
+
+ private static void loadJassLoginConfig(ClassLoader classLoader) {
+ String path = System.getProperty("java.security.auth.login.config");
+ if (path == null) {
+ URL resource = classLoader.getResource("client.login.config");
+ if (resource != null) {
+ path = resource.getFile();
+ System.setProperty("java.security.auth.login.config", path);
+ }
+ }
}
private static String[] siftArgs(String[] args) {
- List<String> argsList = new ArrayList();
+ List<String> argsList = new ArrayList<String>();
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.indexOf("-D") == -1) {
@@ -82,18 +160,16 @@
System.setProperty(prop, val);
}
}
- return (String[]) argsList.toArray(new String[argsList.size()]);
+ return argsList.toArray(new String[argsList.size()]);
}
private static void setAccessible(final Field field) {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
field.setAccessible(true);
return null;
}
});
}
-
-
}
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/StaticUsernamePasswordCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/StaticUsernamePasswordCallbackHandler.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/StaticUsernamePasswordCallbackHandler.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/StaticUsernamePasswordCallbackHandler.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,63 @@
+/**
+ *
+ * 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.openejb.client;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.NameCallback;
+import java.io.IOException;
+
+/**
+ * A JASS username password CallbackHandler.
+ */
+public class StaticUsernamePasswordCallbackHandler implements CallbackHandler {
+ private static String username;
+ private static String password;
+
+
+ public static void setUsername(String username) {
+ StaticUsernamePasswordCallbackHandler.username = username;
+ }
+
+ public static void setPassword(String password) {
+ StaticUsernamePasswordCallbackHandler.password = password;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof PasswordCallback) {
+ PasswordCallback passwordCallback = (PasswordCallback) callback;
+ if (password == null) {
+ passwordCallback.setPassword(null);
+ } else {
+ passwordCallback.setPassword(password.toCharArray());
+ }
+ } else if (callback instanceof NameCallback) {
+ NameCallback nameCallback = (NameCallback) callback;
+ if (username == null) {
+ nameCallback.setName(null);
+ } else {
+ nameCallback.setName(username);
+ }
+ }
+ }
+ }
+}
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/UsernamePasswordCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/UsernamePasswordCallbackHandler.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/UsernamePasswordCallbackHandler.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/java/org/apache/openejb/client/UsernamePasswordCallbackHandler.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,60 @@
+/**
+ *
+ * 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.openejb.client;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.NameCallback;
+import java.io.IOException;
+
+/**
+ * A JASS username password CallbackHandler.
+ */
+public class UsernamePasswordCallbackHandler implements CallbackHandler {
+
+ private final String username;
+ private final String password;
+
+ public UsernamePasswordCallbackHandler(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof PasswordCallback) {
+ PasswordCallback passwordCallback = (PasswordCallback) callback;
+ if (password == null) {
+ passwordCallback.setPassword(null);
+ } else {
+ passwordCallback.setPassword(password.toCharArray());
+ }
+ } else if (callback instanceof NameCallback) {
+ NameCallback nameCallback = (NameCallback) callback;
+ if (username == null) {
+ nameCallback.setName(null);
+ } else {
+ nameCallback.setName(username);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/client.login.conf
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/client.login.conf?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/client.login.conf (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/main/resources/client.login.conf Sat Mar 24 20:26:50 2007
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+ClientLogin {
+ org.apache.openejb.client.ClientLoginModule required
+ debug=true
+ openejb.server.uri="oejb://localhost:4201";
+};
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/ClientLoginTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/ClientLoginTest.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/ClientLoginTest.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/ClientLoginTest.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,73 @@
+/**
+ *
+ * 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.openejb.client;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+public class ClientLoginTest extends TestCase {
+ protected void setUp() throws Exception {
+ super.setUp();
+ LoginTestUtil.initialize();
+ }
+
+ public void testAuthGranted() throws LoginException {
+ // setup the server response
+ LoginTestUtil.setAuthGranted();
+
+ // attempt a login
+ LoginContext context = new LoginContext("ClientLogin", new UsernamePasswordCallbackHandler("jonathan", "secret"));
+ context.login();
+
+ // Verify stored server request
+ assertTrue("serverRequest should be an instance of AuthenticationRequest", LoginTestUtil.serverRequest instanceof AuthenticationRequest);
+ AuthenticationRequest authenticationRequest = (AuthenticationRequest) LoginTestUtil.serverRequest;
+ assertEquals("jonathan", authenticationRequest.getPrincipal());
+ assertEquals("secret", authenticationRequest.getCredentials());
+
+ // get the subject
+ Subject subject = context.getSubject();
+
+ // verify subject
+ assertEquals("Should have one principal", 1, subject.getPrincipals().size());
+ assertEquals("Should have one user principal", 1, subject.getPrincipals(ClientIdentityPrincipal.class).size());
+ ClientIdentityPrincipal principal = subject.getPrincipals(ClientIdentityPrincipal.class).iterator().next();
+ assertEquals("jonathan", principal.getName());
+ assertEquals("SecretIdentity", principal.getClientIdentity());
+
+ context.logout();
+
+ assertEquals("Should have zero principals", 0, subject.getPrincipals().size());
+ }
+
+ public void testAuthDenied() throws Exception {
+ LoginTestUtil.setAuthDenied();
+
+ LoginContext context = new LoginContext("ClientLogin", new UsernamePasswordCallbackHandler("nobody", "secret"));
+ try {
+ context.login();
+ fail("Should have thrown a FailedLoginException");
+ } catch (FailedLoginException doNothing) {
+ }
+
+ }
+}
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/LoginTestUtil.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/LoginTestUtil.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/LoginTestUtil.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/LoginTestUtil.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,57 @@
+/**
+ *
+ * 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.openejb.client;
+
+import java.rmi.RemoteException;
+import java.net.URL;
+
+public class LoginTestUtil {
+ public static Request serverRequest;
+ public static AuthenticationResponse serverResponse;
+
+ public static void initialize() throws Exception {
+ String path = System.getProperty("java.security.auth.login.config");
+ if (path == null) {
+ URL resource = ClientLoginTest.class.getClassLoader().getResource("client.login.conf");
+ if (resource != null) {
+ path = resource.getFile();
+ System.setProperty("java.security.auth.login.config", path);
+ }
+ }
+ System.out.println("Path to login config: " + path);
+
+ Client.setClient(new Client() {
+ protected Response processRequest(Request req, Response res, ServerMetaData server) throws RemoteException {
+ serverRequest = req;
+ return serverResponse;
+ }
+ });
+ }
+
+ static void setAuthGranted() {
+ serverResponse = new AuthenticationResponse();
+ serverResponse.setIdentity(new ClientMetaData("SecretIdentity"));
+ serverResponse.setResponseCode(ResponseCodes.AUTH_GRANTED);
+ }
+
+ static void setAuthDenied() {
+ // setup the server response
+ serverResponse = new AuthenticationResponse();
+ serverResponse.setResponseCode(ResponseCodes.AUTH_DENIED);
+ }
+}
Added: incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java?view=auto&rev=522150
==============================================================================
--- incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java (added)
+++ incubator/openejb/trunk/openejb3/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java Sat Mar 24 20:26:50 2007
@@ -0,0 +1,248 @@
+/**
+ *
+ * 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.openejb.client;
+
+import junit.framework.TestCase;
+
+import javax.naming.spi.InitialContextFactory;
+import javax.naming.spi.NamingManager;
+import javax.naming.spi.InitialContextFactoryBuilder;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.Binding;
+import javax.naming.NameParser;
+import javax.naming.NameNotFoundException;
+import javax.security.auth.Subject;
+import javax.security.auth.login.FailedLoginException;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.TreeMap;
+import java.security.AccessController;
+
+public class MainTest extends TestCase {
+ static {
+ try {
+ NamingManager.setInitialContextFactoryBuilder(new MockContextFactoryBuilder());
+ } catch (NamingException e) {
+ }
+ }
+
+ public static Map<String,Object> jndi = new TreeMap<String,Object>();
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ LoginTestUtil.initialize();
+
+ jndi.clear();
+ jndi.put("java:comp/path", "fake.jar");
+ jndi.put("java:comp/injections", new InjectionMetaData());
+ }
+
+ public void testSecureMain() throws Exception {
+ jndi.put("java:comp/callbackHandler", StaticUsernamePasswordCallbackHandler.class.getName());
+
+ StaticUsernamePasswordCallbackHandler.setUsername("victoria");
+ StaticUsernamePasswordCallbackHandler.setPassword("secret");
+ LoginTestUtil.setAuthGranted();
+
+ jndi.put("java:comp/mainClass", SecureMain.class.getName());
+ Main.main(new String[0]);
+ }
+
+ public void testSecureMainFailed() throws Exception {
+ jndi.put("java:comp/callbackHandler", StaticUsernamePasswordCallbackHandler.class.getName());
+
+ StaticUsernamePasswordCallbackHandler.setUsername("victoria");
+ StaticUsernamePasswordCallbackHandler.setPassword("secret");
+ LoginTestUtil.setAuthDenied();
+
+ jndi.put("java:comp/mainClass", SecureMain.class.getName());
+ try {
+ Main.main(new String[0]);
+ fail("Expected main method to throw FailedLoginException");
+ } catch (FailedLoginException expected) {
+ }
+ }
+
+ public static class SecureMain {
+ public static void main(String[] args) {
+ Subject subject = Subject.getSubject(AccessController.getContext());
+
+ // verify subject
+ assertEquals("Should have one principal", 1, subject.getPrincipals().size());
+ assertEquals("Should have one user principal", 1, subject.getPrincipals(ClientIdentityPrincipal.class).size());
+ ClientIdentityPrincipal principal = subject.getPrincipals(ClientIdentityPrincipal.class).iterator().next();
+ assertEquals("victoria", principal.getName());
+ assertEquals("SecretIdentity", principal.getClientIdentity());
+ }
+ }
+
+ public void testNormalMain() throws Exception {
+ jndi.put("java:comp/mainClass", NormalMain.class.getName());
+ Main.main(new String[0]);
+ }
+
+ public static class NormalMain {
+ public static void main(String[] args) {
+ Subject subject = Subject.getSubject(AccessController.getContext());
+
+ assertNull("subject is not null", subject);
+ }
+ }
+
+
+ //
+ // Ignore these
+ //
+ public static class MockContextFactoryBuilder implements InitialContextFactoryBuilder {
+ public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment) throws NamingException {
+ return new MockContextFactory();
+ }
+ }
+
+ public static class MockContextFactory implements InitialContextFactory {
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+ return new MockContext();
+ }
+ }
+
+ public static class MockContext implements Context {
+ public Object lookup(String name) throws NamingException {
+ Object value = jndi.get(name);
+ if (value == null) {
+ throw new NameNotFoundException(name);
+ }
+ return value;
+ }
+
+ public Object lookup(Name name) throws NamingException {
+ return null;
+ }
+
+ public void bind(Name name, Object obj) throws NamingException {
+
+ }
+
+ public void bind(String name, Object obj) throws NamingException {
+
+ }
+
+ public void rebind(Name name, Object obj) throws NamingException {
+
+ }
+
+ public void rebind(String name, Object obj) throws NamingException {
+
+ }
+
+ public void unbind(Name name) throws NamingException {
+
+ }
+
+ public void unbind(String name) throws NamingException {
+
+ }
+
+ public void rename(Name oldName, Name newName) throws NamingException {
+
+ }
+
+ public void rename(String oldName, String newName) throws NamingException {
+
+ }
+
+ public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
+ return null;
+ }
+
+ public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
+ return null;
+ }
+
+ public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
+ return null;
+ }
+
+ public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
+ return null;
+ }
+
+ public void destroySubcontext(Name name) throws NamingException {
+
+ }
+
+ public void destroySubcontext(String name) throws NamingException {
+
+ }
+
+ public Context createSubcontext(Name name) throws NamingException {
+ return null;
+ }
+
+ public Context createSubcontext(String name) throws NamingException {
+ return null;
+ }
+
+ public Object lookupLink(Name name) throws NamingException {
+ return null;
+ }
+
+ public Object lookupLink(String name) throws NamingException {
+ return null;
+ }
+
+ public NameParser getNameParser(Name name) throws NamingException {
+ return null;
+ }
+
+ public NameParser getNameParser(String name) throws NamingException {
+ return null;
+ }
+
+ public Name composeName(Name name, Name prefix) throws NamingException {
+ return null;
+ }
+
+ public String composeName(String name, String prefix) throws NamingException {
+ return null;
+ }
+
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+ return null;
+ }
+
+ public Object removeFromEnvironment(String propName) throws NamingException {
+ return null;
+ }
+
+ public Hashtable<?, ?> getEnvironment() throws NamingException {
+ return null;
+ }
+
+ public void close() throws NamingException {
+
+ }
+
+ public String getNameInNamespace() throws NamingException {
+ return null;
+ }
+ }
+}