From 38ca708a4f28690dfd069a7e1a5da18d3e46d4b6 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 5 Mar 2002 03:19:18 +0000 Subject: [PATCH] Modified authentication process such that an authenticator thread is no longer maintained. Implementations can choose to create their own authentication thread if they wish or use some existing combination of the invoker and dobjmgr threads. Also added an invoker to the base server class. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1085 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/server/Authenticator.java | 64 ++++++++-- .../presents/server/DummyAuthenticator.java | 20 +-- .../presents/server/PresentsServer.java | 33 ++--- .../presents/server/net/AuthManager.java | 115 ------------------ .../server/net/AuthingConnection.java | 4 +- .../server/net/ConnectionManager.java | 32 ++--- .../whirled/server/WhirledServer.java | 10 +- 7 files changed, 104 insertions(+), 174 deletions(-) delete mode 100644 src/java/com/threerings/presents/server/net/AuthManager.java diff --git a/src/java/com/threerings/presents/server/Authenticator.java b/src/java/com/threerings/presents/server/Authenticator.java index a4a09827f..aedc7ffb9 100644 --- a/src/java/com/threerings/presents/server/Authenticator.java +++ b/src/java/com/threerings/presents/server/Authenticator.java @@ -1,26 +1,64 @@ // -// $Id: Authenticator.java,v 1.3 2001/10/11 04:07:53 mdb Exp $ +// $Id: Authenticator.java,v 1.4 2002/03/05 03:19:18 mdb Exp $ package com.threerings.presents.server.net; -import com.threerings.presents.net.AuthRequest; import com.threerings.presents.net.AuthResponse; +import com.threerings.presents.net.AuthResponseData; /** * The authenticator is a pluggable component of the authentication - * framework. It is provided with an auth request object and is expected - * to return an auth response object indicating whether or not the client - * is authenticated. authenticate() is invoked on the authmgr - * thread which means that it can access databases or other external - * (slow) information sources without concern for unduly blocking the - * normal operation of the server. Of course, authentication requests are - * processed serially, so they shouldn't take too long. + * framework. The base class handles the basic mechanics of authentication + * and a system would extend the base authenticator and add code that does + * the actual client authentication. */ -public interface Authenticator +public abstract class Authenticator { /** - * Requests that the authenticator process the supplied request and - * provide a response object indicating success or failure. + * Called by the connection manager to give us a reference to it for + * reporting authenticated connections. */ - public AuthResponse process (AuthRequest request); + public void setConnectionManager (ConnectionManager conmgr) + { + _conmgr = conmgr; + } + + /** + * Called by the connection management code when an authenticating + * connection has received its authentication request from the client. + * This method must return immediately as it is called on the + * connection manager thread. If it is possible to authenticate the + * connection immediately, it may do so, but more likely it will fire + * off a task on the {@link PresentsServer#invoker} to perform the + * authentication. When the authentication is complete, the + * authenticator implementation should call {@link + * #connectionWasAuthenticated}. + */ + public abstract void authenticateConnection (AuthingConnection conn); + + /** + * This is called by authenticator implementations when they have + * completed the authentication process. It will deliver the response + * to the user and let the connection manager know to report the + * authentication if it succeeded. + */ + protected void connectionWasAuthenticated ( + AuthingConnection conn, AuthResponse rsp) + { + // now ship the response back + conn.postMessage(rsp); + + // stuff a reference to the auth response into the connection so + // that we have access to it later in the authentication process + conn.setAuthResponse(rsp); + + // if the authentication request was granted, let the connection + // manager know that we just authed + if (AuthResponseData.SUCCESS.equals(rsp.getData().code)) { + _conmgr.connectionDidAuthenticate(conn); + } + } + + /** The connection manager with which we're working. */ + protected ConnectionManager _conmgr; } diff --git a/src/java/com/threerings/presents/server/DummyAuthenticator.java b/src/java/com/threerings/presents/server/DummyAuthenticator.java index ae22cb37f..d88880962 100644 --- a/src/java/com/threerings/presents/server/DummyAuthenticator.java +++ b/src/java/com/threerings/presents/server/DummyAuthenticator.java @@ -1,22 +1,28 @@ // -// $Id: DummyAuthenticator.java,v 1.4 2001/10/11 04:07:53 mdb Exp $ +// $Id: DummyAuthenticator.java,v 1.5 2002/03/05 03:19:18 mdb Exp $ package com.threerings.presents.server; import com.threerings.presents.Log; -import com.threerings.presents.net.*; +import com.threerings.presents.net.AuthResponse; +import com.threerings.presents.net.AuthResponseData; import com.threerings.presents.server.net.Authenticator; +import com.threerings.presents.server.net.AuthingConnection; -public class DummyAuthenticator implements Authenticator +/** + * A simple authenticator implementation that simply accepts all + * authentication requests. + */ +public class DummyAuthenticator extends Authenticator { /** - * We just accept all authentication requests. + * Accept all authentication requests. */ - public AuthResponse process (AuthRequest req) + public void authenticateConnection (AuthingConnection conn) { - Log.info("Accepting request: " + req); + Log.info("Accepting request: " + conn.getAuthRequest()); AuthResponseData rdata = new AuthResponseData(); rdata.code = AuthResponseData.SUCCESS; - return new AuthResponse(rdata); + connectionWasAuthenticated(conn, new AuthResponse(rdata)); } } diff --git a/src/java/com/threerings/presents/server/PresentsServer.java b/src/java/com/threerings/presents/server/PresentsServer.java index ad54572d4..51417023a 100644 --- a/src/java/com/threerings/presents/server/PresentsServer.java +++ b/src/java/com/threerings/presents/server/PresentsServer.java @@ -1,5 +1,5 @@ // -// $Id: PresentsServer.java,v 1.17 2002/02/09 07:49:41 mdb Exp $ +// $Id: PresentsServer.java,v 1.18 2002/03/05 03:19:18 mdb Exp $ package com.threerings.presents.server; @@ -7,8 +7,8 @@ import com.samskivert.util.Config; import com.threerings.presents.Log; import com.threerings.presents.dobj.DObjectManager; -import com.threerings.presents.server.net.AuthManager; import com.threerings.presents.server.net.ConnectionManager; +import com.threerings.presents.util.Invoker; /** * The presents server provides a central point of access to the various @@ -28,9 +28,6 @@ public class PresentsServer /** The server configuration. */ public static Config config; - /** The authentication manager. */ - public static AuthManager authmgr; - /** The manager of network connections. */ public static ConnectionManager conmgr; @@ -43,6 +40,11 @@ public class PresentsServer /** The invocation manager. */ public static InvocationManager invmgr; + /** This is used to invoke background tasks that should not be allowed + * to tie up the distributed object manager thread. This is generally + * used to talk to databases and other (relatively) slow entities. */ + public static Invoker invoker; + /** * Initializes all of the server services and prepares for operation. */ @@ -54,14 +56,20 @@ public class PresentsServer // bind the presents server config into the namespace config.bindProperties(CONFIG_KEY, CONFIG_PATH, true); - // create our authentication manager - authmgr = new AuthManager(new DummyAuthenticator()); - // create our connection manager - conmgr = new ConnectionManager(config, authmgr); - // create our client manager - clmgr = new ClientManager(conmgr); // create our distributed object manager omgr = new PresentsDObjectMgr(); + + // create and start up our invoker + invoker = new Invoker(omgr); + invoker.start(); + + // create our connection manager + conmgr = new ConnectionManager(config); + conmgr.setAuthenticator(new DummyAuthenticator()); + + // create our client manager + clmgr = new ClientManager(conmgr); + // create our invocation manager invmgr = new InvocationManager(omgr); @@ -123,8 +131,6 @@ public class PresentsServer */ public void run () { - // start up the auth manager - authmgr.start(); // start up the connection manager conmgr.start(); // invoke the dobjmgr event loop @@ -137,7 +143,6 @@ public class PresentsServer public static void shutdown () { // shut down our managers - authmgr.shutdown(); conmgr.shutdown(); omgr.shutdown(); } diff --git a/src/java/com/threerings/presents/server/net/AuthManager.java b/src/java/com/threerings/presents/server/net/AuthManager.java deleted file mode 100644 index 3cd75e099..000000000 --- a/src/java/com/threerings/presents/server/net/AuthManager.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// $Id: AuthManager.java,v 1.8 2001/12/04 07:32:10 mdb Exp $ - -package com.threerings.presents.server.net; - -import com.samskivert.util.LoopingThread; -import com.samskivert.util.Queue; - -import com.threerings.presents.Log; -import com.threerings.presents.net.AuthRequest; -import com.threerings.presents.net.AuthResponse; -import com.threerings.presents.net.AuthResponseData; - -/** - * The authentication manager takes care of the authentication process. - * Authentication happens on multiple threads. The conmgr thread parses - * the authentication request and passes it on to the authmgr thread. The - * authmgr thread invokes the (pluggable) authenticator to do the actual - * authentication. Then the response message is queued up to be delivered - * by the conmgr thread. - * - *

This structure prevents authentication to take place - * asynchronously, but in a controlled manner. Only one authentication - * will be processed at a time, but the dobj and conmgr threads will - * continue to operate independent of the authentication process. - */ -public class AuthManager extends LoopingThread -{ - /** - * Constructs an auth manager which will use the specified - * authenticator to authorize logon requests. - */ - public AuthManager (Authenticator author) - { - setAuthenticator(author); - } - - /** - * Specifies the authenticator that should be used by the auth manager - * to authenticate logon requests. - */ - public void setAuthenticator (Authenticator author) - { - _author = author; - } - - /** - * Puts an authenticating connection on the queue. The connection will - * be authenticated and an auth response delivered. - */ - public void postAuthingConnection (AuthingConnection aconn) - { - _authq.append(aconn); - } - - /** - * The connection manager introduces itself to the auth manager so - * that the auth manager can let it know when it has authorized - * connections. - */ - public void setConnectionManager (ConnectionManager conmgr) - { - _conmgr = conmgr; - } - - /** - * Process auth requests. - */ - protected void iterate () - { - // grab the next authing connection from the queue - Object item = _authq.get(); - - // if we're being kicked and requested to exit, we'll just post - // some bogus item on the queue to wake up the auth manager and - // get him the hell out of dodge - if (!(item instanceof AuthingConnection)) { - return; - } - - AuthingConnection aconn = (AuthingConnection)item; - try { - // instruct the authenticator to process the auth request - AuthResponse rsp = _author.process(aconn.getAuthRequest()); - - // now ship the response back - aconn.postMessage(rsp); - - // stuff a reference to the auth response into the connection - // so that we have access to it later in the authentication - // process - aconn.setAuthResponse(rsp); - - // if the authentication request was granted, let the - // connection manager know that we just authed - if (AuthResponseData.SUCCESS.equals(rsp.getData().code)) { - _conmgr.connectionDidAuthenticate(aconn); - } - - } catch (Exception e) { - Log.warning("Failure processing authreq [conn=" + aconn + "]."); - Log.logStackTrace(e); - } - } - - protected void kick () - { - // we post something bogus to the queue to wake up the authmgr - _authq.append(new Integer(0)); - } - - protected Authenticator _author; - protected ConnectionManager _conmgr; - protected Queue _authq = new Queue(); -} diff --git a/src/java/com/threerings/presents/server/net/AuthingConnection.java b/src/java/com/threerings/presents/server/net/AuthingConnection.java index c763c5600..f4a8c447a 100644 --- a/src/java/com/threerings/presents/server/net/AuthingConnection.java +++ b/src/java/com/threerings/presents/server/net/AuthingConnection.java @@ -1,5 +1,5 @@ // -// $Id: AuthingConnection.java,v 1.5 2001/12/03 20:14:51 mdb Exp $ +// $Id: AuthingConnection.java,v 1.6 2002/03/05 03:19:18 mdb Exp $ package com.threerings.presents.server.net; @@ -41,7 +41,7 @@ public class AuthingConnection _authreq = (AuthRequest)msg; // post ourselves for processing by the authmgr - _cmgr.getAuthManager().postAuthingConnection(this); + _cmgr.getAuthenticator().authenticateConnection(this); } catch (ClassCastException cce) { Log.warning("Received non-authreq message during " + diff --git a/src/java/com/threerings/presents/server/net/ConnectionManager.java b/src/java/com/threerings/presents/server/net/ConnectionManager.java index 3a05e0595..c4c8d2fd7 100644 --- a/src/java/com/threerings/presents/server/net/ConnectionManager.java +++ b/src/java/com/threerings/presents/server/net/ConnectionManager.java @@ -1,5 +1,5 @@ // -// $Id: ConnectionManager.java,v 1.14 2001/12/03 20:14:51 mdb Exp $ +// $Id: ConnectionManager.java,v 1.15 2002/03/05 03:19:18 mdb Exp $ package com.threerings.presents.server.net; @@ -34,19 +34,13 @@ public class ConnectionManager extends LoopingThread * * @param config A config object from which the connection manager * will fetch its configuration parameters. - * @param authmgr The authentication manager to use when - * authenticating client connections. */ - public ConnectionManager (Config config, AuthManager authmgr) + public ConnectionManager (Config config) throws IOException { + // the listen port is specified in our configuration _port = config.getValue(CM_PORT_KEY, Client.DEFAULT_SERVER_PORT); - // keep a handle on our authentication manager - _authmgr = authmgr; - // complete the introductions - _authmgr.setConnectionManager(this); - // we use this to wait for activity on our sockets _selset = new SelectSet(); @@ -67,12 +61,22 @@ public class ConnectionManager extends LoopingThread } /** - * Returns a reference to the auth manager being used to authenticate - * connections. + * Specifies the authenticator that should be used by the connection + * manager to authenticate logon requests. */ - public AuthManager getAuthManager () + public void setAuthenticator (Authenticator author) { - return _authmgr; + // say hello to our new authenticator + _author = author; + _author.setConnectionManager(this); + } + + /** + * Returns the entity that is being used to authenticate connections. + */ + public Authenticator getAuthenticator () + { + return _author; } /** @@ -310,7 +314,7 @@ public class ConnectionManager extends LoopingThread } protected int _port; - protected AuthManager _authmgr; + protected Authenticator _author; protected SelectSet _selset; protected NonblockingServerSocket _listener; diff --git a/src/java/com/threerings/whirled/server/WhirledServer.java b/src/java/com/threerings/whirled/server/WhirledServer.java index 05bcccc7d..d8dc6bab8 100644 --- a/src/java/com/threerings/whirled/server/WhirledServer.java +++ b/src/java/com/threerings/whirled/server/WhirledServer.java @@ -1,5 +1,5 @@ // -// $Id: WhirledServer.java,v 1.11 2001/12/16 05:39:16 mdb Exp $ +// $Id: WhirledServer.java,v 1.12 2002/03/05 03:19:18 mdb Exp $ package com.threerings.whirled.server; @@ -7,7 +7,6 @@ import com.samskivert.jdbc.ConnectionProvider; import com.samskivert.jdbc.StaticConnectionProvider; import com.samskivert.util.Config; -import com.threerings.presents.util.Invoker; import com.threerings.crowd.server.CrowdServer; import com.threerings.whirled.Log; @@ -29,9 +28,6 @@ public class WhirledServer extends CrowdServer /** The scene registry. */ public static SceneRegistry screg; - /** A thread on which we can do things like repository lookups. */ - public static Invoker invoker; - /** * Initializes all of the server services and prepares for operation. */ @@ -47,10 +43,6 @@ public class WhirledServer extends CrowdServer // configure the client to use our whirled client clmgr.setClientClass(WhirledClient.class); - // create and start up our invoker - invoker = new Invoker(); - invoker.start(); - // create our connection provider conprov = createConnectionProvider(config);