Author: david.lloyd(a)jboss.com
Date: 2010-02-28 17:59:17 -0500 (Sun, 28 Feb 2010)
New Revision: 5774
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleServerAuthenticationProvider.java
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
Log:
Add simple server authentication provider for standalone usages
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleServerAuthenticationProvider.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleServerAuthenticationProvider.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleServerAuthenticationProvider.java 2010-02-28
22:59:17 UTC (rev 5774)
@@ -0,0 +1,159 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.security;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+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.sasl.AuthenticationException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.RealmCallback;
+
+/**
+ * A server authentication handler which maintains a simple map of user names and
passwords.
+ */
+public final class SimpleServerAuthenticationProvider implements
ServerAuthenticationProvider {
+
+ private static final RemotingPermission ADD_USER_PERM = new
RemotingPermission("addServerUser");
+
+ private final Map<String, Map<String, Entry>> map = new
HashMap<String, Map<String, Entry>>();
+
+ /** {@inheritDoc} */
+ public CallbackHandler getCallbackHandler() {
+ return new CallbackHandler() {
+ public void handle(final Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
+ String userName = null;
+ String realmName = null;
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ final NameCallback nameCallback = (NameCallback) callback;
+ final String defaultName = nameCallback.getDefaultName();
+ userName = defaultName.toLowerCase().trim();
+ nameCallback.setName(userName);
+ } else if (callback instanceof RealmCallback) {
+ final RealmCallback realmCallback = (RealmCallback) callback;
+ final String defaultRealm = realmCallback.getDefaultText();
+ if (defaultRealm != null) {
+ realmName = defaultRealm.toLowerCase().trim();
+ realmCallback.setText(realmName);
+ }
+ } else if (callback instanceof PasswordCallback) {
+ final PasswordCallback passwordCallback = (PasswordCallback)
callback;
+ // retrieve the record based on user and realm (if any)
+ Entry entry = null;
+ if (realmName == null) {
+ // scan all realms
+ synchronized (map) {
+ for (Map<String, Entry> realmMap : map.values()) {
+ if (realmMap.containsKey(userName)) {
+ entry = realmMap.get(userName);
+ break;
+ }
+ }
+ }
+ } else {
+ synchronized (map) {
+ final Map<String, Entry> realmMap =
map.get(realmName);
+ if (realmMap != null) {
+ entry = realmMap.get(userName);
+ }
+ }
+ }
+ if (entry == null) {
+ throw new AuthenticationException("No matching user
found");
+ }
+ passwordCallback.setPassword(entry.getPassword());
+ } else if (callback instanceof AuthorizeCallback) {
+ final AuthorizeCallback authorizeCallback = (AuthorizeCallback)
callback;
+
authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
+ } else {
+ throw new UnsupportedCallbackException(callback, "Callback
not supported: " + callback);
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * Add a user to the authentication table.
+ *
+ * @param userName the user name
+ * @param userRealm the user realm
+ * @param password the password
+ */
+ public void addUser(String userName, String userRealm, char[] password) {
+ if (userName == null) {
+ throw new IllegalArgumentException("userName is null");
+ }
+ if (userRealm == null) {
+ throw new IllegalArgumentException("userRealm is null");
+ }
+ if (password == null) {
+ throw new IllegalArgumentException("password is null");
+ }
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(ADD_USER_PERM);
+ }
+ final String canonUserRealm = userRealm.toLowerCase().trim();
+ final String canonUserName = userName.toLowerCase().trim();
+ synchronized (map) {
+ Map<String, Entry> realmMap = map.get(canonUserRealm);
+ if (realmMap == null) {
+ realmMap = new HashMap<String, Entry>();
+ map.put(canonUserRealm, realmMap);
+ }
+ realmMap.put(canonUserName, new Entry(canonUserName, canonUserRealm,
password));
+ }
+ }
+
+ private static final class Entry {
+ private final String userName;
+ private final String userRealm;
+ private final char[] password;
+
+ private Entry(final String userName, final String userRealm, final char[]
password) {
+ this.userName = userName;
+ this.userRealm = userRealm;
+ this.password = password;
+ }
+
+ String getUserName() {
+ return userName;
+ }
+
+ String getUserRealm() {
+ return userRealm;
+ }
+
+ char[] getPassword() {
+ return password;
+ }
+ }
+}
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java 2010-02-28
22:05:37 UTC (rev 5773)
+++
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java 2010-02-28
22:59:17 UTC (rev 5774)
@@ -86,6 +86,7 @@
return new RequestListener<InvocationTestObject,
InvocationTestObject>() {
public void handleRequest(final
RequestContext<InvocationTestObject> objectRequestContext, final
InvocationTestObject request) throws RemoteExecutionException {
try {
+ log.info("Got request %s, sending reply %s",
request, replyObj);
objectRequestContext.sendReply(replyObj);
} catch (IOException e) {
throw new RemoteExecutionException(e);
@@ -182,6 +183,7 @@
public void handleRequest(final
RequestContext<InvocationTestObject> objectRequestContext, final ClientConnector
request) throws RemoteExecutionException {
try {
assertEquals(replyObj,
((ClientConnector<InvocationTestObject,
InvocationTestObject>)request).getFutureClient().get().invoke(requestObj));
+ log.info("Got request %s, sending reply %s",
request, replyObj);
objectRequestContext.sendReply(replyObj);
} catch (Throwable e) {
throw new RemoteExecutionException(e);
@@ -202,6 +204,7 @@
client.invoke(connection.createClientConnector(new
RequestListener<InvocationTestObject, InvocationTestObject>() {
public void handleRequest(final
RequestContext<InvocationTestObject> requestContext, final InvocationTestObject
request) throws RemoteExecutionException {
try {
+ log.info("Got request %s, sending reply
%s", request, replyObj);
requestContext.sendReply(replyObj);
} catch (IOException e) {
throw new RemoteExecutionException(e);
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java 2010-02-28
22:05:37 UTC (rev 5773)
+++
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java 2010-02-28
22:59:17 UTC (rev 5774)
@@ -29,7 +29,7 @@
import org.jboss.remoting3.CloseHandler;
import org.jboss.remoting3.Connection;
import org.jboss.remoting3.RemotingOptions;
-import org.jboss.remoting3.security.ServerAuthenticationProvider;
+import org.jboss.remoting3.security.SimpleServerAuthenticationProvider;
import org.jboss.remoting3.spi.NetworkServerProvider;
import org.jboss.remoting3.spi.ProtocolServiceType;
import org.jboss.xnio.AcceptingServer;
@@ -44,15 +44,6 @@
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
-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.sasl.AuthenticationException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
-
@Test(suiteName = "Remote tests")
public final class RemoteTestCase extends InvocationTestBase {
@@ -61,36 +52,9 @@
enter();
try {
super.setUp();
-
endpoint.addProtocolService(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER,
"test", new ServerAuthenticationProvider() {
- public CallbackHandler getCallbackHandler() {
- return new CallbackHandler() {
- public void handle(final Callback[] callbacks) throws
IOException, UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof NameCallback) {
- final NameCallback nameCallback = (NameCallback)
callback;
- final String defaultName =
nameCallback.getDefaultName();
- if (defaultName != null) {
- nameCallback.setName(defaultName);
- }
- if (!"user".equals(nameCallback.getName()))
{
- throw new AuthenticationException("Invalid
user name");
- }
- } else if (callback instanceof PasswordCallback) {
- final PasswordCallback passwordCallback =
(PasswordCallback) callback;
-
passwordCallback.setPassword("password".toCharArray());
- } else if (callback instanceof RealmCallback) {
- // allow
- } else if (callback instanceof AuthorizeCallback) {
- final AuthorizeCallback authorizeCallback =
(AuthorizeCallback) callback;
-
authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals(authorizeCallback.getAuthorizationID()));
- } else {
- throw new UnsupportedCallbackException(callback,
"Callback not supported: " + callback);
- }
- }
- }
- };
- }
- });
+ final SimpleServerAuthenticationProvider authenticationProvider = new
SimpleServerAuthenticationProvider();
+ authenticationProvider.addUser("user", "endpoint",
"password".toCharArray());
+
endpoint.addProtocolService(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER,
"test", authenticationProvider);
} finally {
exit();
}