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
This commit is contained in:
Michael Bayne
2002-03-05 03:19:18 +00:00
parent 7dc7545541
commit 38ca708a4f
7 changed files with 104 additions and 174 deletions
@@ -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. <code>authenticate()</code> 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 <em>too</em> 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;
}
@@ -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));
}
}
@@ -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();
}
@@ -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.
*
* <p> 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();
}
@@ -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 " +
@@ -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;
@@ -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);