Cached JAAS Login Credentials Problem
wcone Oct 14, 2010 6:31 PMI'm running JBoss 5.1.0.GA. I have a Swing client app that is authenticating and making calls on some EJB3 stateless session beans. The client app is performing a JAAS login using LoginContext configured for the org.jboss.security.ClientLoginModule. The SLSB is configured to use a security domain that authenticates with a DatabaseServerLoginModule.
I have no problem logging in. However, if I login as USER1, then logout, then login as USER2, the server authenticates me as USER1 for both logins. It seems to be caching the login credentials, somewhere. After some reading on the Wiki, I made sure my DatabaseServerLoginModule is not configured for password-stacking=useFirstPass. I also found the Wiki page on caching login credentials. I'd rather not completely disable caching, but I saw the section on flushing specific credentials, so I thought that would solve my problem. I wrote some code to programmatically remove the specified user from the cache using the JaasSecurityManager MBean. That code works: it removes the principal from the domain's cached list. However, removing the principal from there doesn't solve the problem, so that must not be the only place the credentials are being cached.
At the moment, I'm at a loss. Anyone seen this before or have some tips on what I should look for?
{quote:title=Client App's auth.conf}
swing-client { org.jboss.security.ClientLoginModule required; };
{quote}
The Client App's Login Approach
{code:java}
LoginContext lc = new LoginContext("swing-client", this);
lc.login();
try {
MyBeanRemote bean = (MyBeanRemote) new InitialContext().lookup("MyApp/MyBean/remote");
String hello = bean.sayHello();
JOptionPane.showMessageDialog(this, hello);
bean.invalidate(); // flushes the server's credential cache
} finally {
lc.logout();
}
{code}
aplus-
client {
The CallbackHandler.handle() Approach
{code:java}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
LoginDialog loginDialog = new LoginDialog(this, true);
loginDialog.setVisible(true);
if (loginDialog.isOkPressed()) {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback)
((NameCallback)callback).setName(loginDialog.getUserName());
else if (callback instanceof PasswordCallback)
((PasswordCallback)callback).setPassword(loginDialog.getPassword());
else
throw new UnsupportedCallbackException(callback, "Unsupported callback");
}
} else {
loginCanceled();
}
}
{code}
The Server's application policy from the login-conf.xml file
{code:xml}
<application-policy name="myapp-domain"> <authentication> <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"> <module-option name="unauthenticatedIdentity">guest</module-option> <module-option name="dsJndiName">java:/myappds</module-option> <module-option name="principalsQuery">select user_pass from myapp_user where user_name = ?</module-option> <module-option name="rolesQuery">select role_name, 'Roles' from myapp_user_role where user_name = ?</module-option> <module-option name="hashAlgorithm">SHA-1</module-option> <module-option name="hashEncoding">base64</module-option> </login-module> </authentication> </application-policy>
{code}
The Server's SLSB Approach:
{code:java}
@Stateless
@SecurityDomain("myapp-domain")
public class MyBean implements MyBeanLocal, MyBeanRemote {
public String sayHello() {
String user = context.getCallerPrincipal().getName();
return String.format("Hello, %s", user);
}
public void invalidate() {
Principal user = context.getCallerPrincipal(); String userName = null; try { String domain = "myapp-domain"; userName = user.getName(); ObjectName jaasMgr = new ObjectName("jboss.security:service=JaasSecurityManager"); Object[] params = {domain, user}; String[] signature = {"java.lang.String", Principal.class.getName()}; MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0); server.invoke(jaasMgr, "flushAuthenticationCache", params, signature); } catch (Exception e) { String msg = String.format("Server error flushing %s from the authentication cache", userName); throw new EJBException(msg, e); }
}
@Resource
private SessionContext context;
}
{code}