Moved some of the standard work done by Authenticators into the base class.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4291 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2006-07-25 19:02:48 +00:00
parent 878129f75d
commit 426edf6ad7
4 changed files with 153 additions and 51 deletions
@@ -21,6 +21,10 @@
package com.threerings.presents.peer.server;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.Invoker;
import com.threerings.presents.data.AuthCodes;
import com.threerings.presents.net.AuthRequest;
@@ -49,22 +53,13 @@ public class PeerAuthenticator extends Authenticator
_delegate = delegate;
}
@Override // documentation inherited
@Override
public void authenticateConnection (AuthingConnection conn)
{
// if this is a peer server, we check their credentials specially
AuthRequest req = conn.getAuthRequest();
if (req.getCredentials() instanceof PeerCreds) {
AuthResponse rsp = new AuthResponse(new AuthResponseData());
PeerCreds pcreds = (PeerCreds)req.getCredentials();
if (_peermgr.isAuthenticPeer(pcreds)) {
rsp.getData().code = AuthResponseData.SUCCESS;
} else {
log.warning("Received invalid peer auth request? " +
"[creds=" + pcreds + "].");
rsp.getData().code = AuthCodes.SERVER_ERROR;
}
connectionWasAuthenticated(conn, rsp);
super.authenticateConnection(conn);
} else {
// otherwise pass the request on to our delegate
@@ -72,6 +67,34 @@ public class PeerAuthenticator extends Authenticator
}
}
@Override
protected Invoker getInvoker ()
{
// The processing of peer authentication happens inline,
// but other authentication will use the _delegate which will
// probably use an Invoker.
return null;
}
// from abstract Authenticator
protected void processAuthentication (
AuthingConnection conn, AuthResponse rsp)
throws PersistenceException
{
// here, we are ONLY authenticating peers
AuthRequest req = conn.getAuthRequest();
PeerCreds pcreds = (PeerCreds) req.getCredentials();
if (_peermgr.isAuthenticPeer(pcreds)) {
rsp.getData().code = AuthResponseData.SUCCESS;
} else {
log.warning("Received invalid peer auth request? " +
"[creds=" + pcreds + "].");
rsp.getData().code = AuthCodes.SERVER_ERROR;
}
}
protected PeerManager _peermgr;
protected Authenticator _delegate;
}
@@ -21,12 +21,23 @@
package com.threerings.presents.server;
import java.util.logging.Level;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.Invoker;
import com.threerings.presents.data.AuthCodes;
import com.threerings.presents.net.AuthRequest;
import com.threerings.presents.net.AuthResponse;
import com.threerings.presents.net.AuthResponseData;
import com.threerings.presents.server.net.AuthingConnection;
import com.threerings.presents.server.net.ConnectionManager;
import static com.threerings.presents.Log.log;
/**
* The authenticator is a pluggable component of the authentication
* framework. The base class handles the basic mechanics of authentication
@@ -47,28 +58,27 @@ public abstract class Authenticator
/**
* 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 (
final AuthingConnection conn, final AuthResponse rsp)
public void authenticateConnection (final AuthingConnection conn)
{
// make double plus extra sure we're on the omgr thread
PresentsServer.omgr.postRunnable(new Runnable() {
public void run () {
final AuthRequest req = conn.getAuthRequest();
final AuthResponseData rdata = createResponseData();
final AuthResponse rsp = new AuthResponse(rdata);
Invoker.Unit unit = new Invoker.Unit("auth:" + req.getCredentials()) {
public boolean invoke() {
try {
processAuthentication(conn, rsp);
} catch (Exception e) { // Persistence or Runtime
log.log(Level.WARNING, "Error authenticating user " +
"[areq=" + req + "].", e);
rdata.code = AuthCodes.SERVER_ERROR;
}
return true;
}
public void handleResult () {
// stuff a reference to the auth response into the
// connection so that we have access to it later in the
// authentication process
@@ -79,13 +89,62 @@ public abstract class Authenticator
// if the authentication request was granted, let the
// connection manager know that we just authed
if (AuthResponseData.SUCCESS.equals(rsp.getData().code)) {
if (AuthResponseData.SUCCESS.equals(rdata.code)) {
_conmgr.connectionDidAuthenticate(conn);
}
}
});
};
Invoker invoker = getInvoker();
if (invoker != null) {
invoker.postUnit(unit);
} else {
// just process it here
try {
unit.invoke();
unit.handleResult();
} catch (Exception e) {
log.log(Level.WARNING, "Error authenticating user " +
"[areq=" + req + "].", e);
}
}
}
/**
* Return the invoker on which to process the authentication, or null
* if the authentication should occur on the calling thread. The default
* implementation returns PresentsServer.invoker.
*/
protected Invoker getInvoker ()
{
return PresentsServer.invoker;
}
/**
* Create a new AuthResponseData instance to use for authenticating
* a connection.
*/
protected AuthResponseData createResponseData ()
{
return new AuthResponseData();
}
/**
* Process the authentication for the specified connection.
* This method may do database operations if and only if getInvoker()
* returns non-null. The method may return after it has stuffed a valid
* response code in rsp.getData().code.
*
* @param conn The client connection.
* @param rsp The response to the client, which will already contain
* an AuthResponseData created by createResponseDatA().
*/
protected abstract void processAuthentication (
AuthingConnection conn, AuthResponse rsp)
throws PersistenceException;
/** The connection manager with which we're working. */
protected ConnectionManager _conmgr;
}
@@ -21,25 +21,34 @@
package com.threerings.presents.server;
import com.threerings.presents.Log;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.Invoker;
import com.threerings.presents.net.AuthResponse;
import com.threerings.presents.net.AuthResponseData;
import com.threerings.presents.server.net.AuthingConnection;
import static com.threerings.presents.Log.log;
/**
* A simple authenticator implementation that simply accepts all
* authentication requests.
*/
public class DummyAuthenticator extends Authenticator
{
/**
* Accept all authentication requests.
*/
public void authenticateConnection (AuthingConnection conn)
@Override
protected Invoker getInvoker ()
{
Log.info("Accepting request: " + conn.getAuthRequest());
AuthResponseData rdata = new AuthResponseData();
rdata.code = AuthResponseData.SUCCESS;
connectionWasAuthenticated(conn, new AuthResponse(rdata));
return null; // not needed
}
// from abstract Authenticator
protected void processAuthentication (
AuthingConnection conn, AuthResponse rsp)
throws PersistenceException
{
log.info("Accepting request: " + conn.getAuthRequest());
rsp.getData().code = AuthResponseData.SUCCESS;
}
}
@@ -3,14 +3,20 @@
package com.threerings.presents.server;
import java.util.logging.Level;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.Invoker;
import com.samskivert.util.StringUtil;
import com.threerings.util.MessageBundle;
import com.threerings.presents.Log;
import com.threerings.presents.net.AuthResponse;
import com.threerings.presents.net.AuthResponseData;
import com.threerings.presents.server.net.AuthingConnection;
import static com.threerings.presents.Log.log;
/**
* A simple server that does nothing more than spit out a canned error
* response to everyone who logs in.
@@ -51,8 +57,7 @@ public class Rejector extends PresentsServer
server.init();
server.run();
} catch (Exception e) {
Log.warning("Unable to initialize server.");
Log.logStackTrace(e);
log.log(Level.WARNING, "Unable to initialize server.", e);
}
}
@@ -62,13 +67,19 @@ public class Rejector extends PresentsServer
*/
protected class RejectingAuthenticator extends Authenticator
{
/** Reject all authentication requests. */
public void authenticateConnection (AuthingConnection conn)
@Override
protected Invoker getInvoker ()
{
Log.info("Rejecting request: " + conn.getAuthRequest());
AuthResponseData rdata = new AuthResponseData();
rdata.code = _errmsg;
connectionWasAuthenticated(conn, new AuthResponse(rdata));
return null;
}
// from abstract Authenticator
protected void processAuthentication (
AuthingConnection conn, AuthResponse rsp)
throws PersistenceException
{
log.info("Rejecting request: " + conn.getAuthRequest());
rsp.getData().code = _errmsg;
}
}