DatabaseServerLoginModule - Bad Password
___martin___ Sep 8, 2004 10:26 AMHello List/Forum!
I've got a little problem using JBoss 3.2.3 with JAAS/DatabaseServerLoginModule. A sample swing-application (standalone; not web) should authenticate a user against the JBoss app-server; thus the client uses the ClientLoginModule whereas the JBoss-app-server uses the DatabaseServerLoginModule to authenticate the client.
In the "Basic JBoss Authentication and Access Control"(http://minnigerode.org/dave/BasicJBossAAC.html) tutorial it is mentioned, that the DatabaseServerLoginModule requires a SHA hash of the clear text password; does this mean I've to save the SHA hash in the database or to pass a SHA hash in the callbackhandler?
The login-name for a user is its primary-key in the db-table (see below for the table definition).
Without JAAS the sample runs fine but as soon as I add security to the program I get these log-messages:
2004-09-08 14:54:26,901 TRACE [org.jboss.system.Registry] lookup 1703819317=jboss.j2ee:jndiName=CustomerSHomeRemote,service=EJB
2004-09-08 14:54:26,901 TRACE [org.jboss.ejb.plugins.LogInterceptor] Start method=create
2004-09-08 14:54:26,901 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Current transaction in MI is null
2004-09-08 14:54:26,901 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] TX_REQUIRED for create
2004-09-08 14:54:26,901 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Thread came in with tx null
2004-09-08 14:54:26,902 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] Starting new tx TransactionImpl:XidImpl [FormatId=257, GlobalId=linux//3, BranchQual=]
2004-09-08 14:54:26,902 TRACE [org.jboss.ejb.plugins.StatefulSessionInstancePool] Get instance org.jboss.ejb.plugins.StatefulSessionInstancePool@dbb83a#0#class com.ejbemarketplace.customer.CustomerSBean
2004-09-08 14:54:26,903 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] getAppConfigurationEntry(ejbemarketplacepolicy), authInfo=AppConfigurationEntry[]:
[0]
LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule
ControlFlag: LoginModuleControlFlag: required
Options:name=rolesQuery, value=select role, role from customerejb where ucid=?
name=principalsQuery, value=select passwd from customerejb where ucid=?
name=unauthenticatedIdentity, value=Unknown
name=password-stacking, value=useFirstPass
name=dsJndiName, value=java:/PostgresDS
2004-09-08 14:54:26,903 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] initialize
2004-09-08 14:54:26,903 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Saw unauthenticatedIdentity=Unknown
2004-09-08 14:54:26,903 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] DatabaseServerLoginModule, dsJndiName=java:/PostgresDS
2004-09-08 14:54:26,903 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] principalsQuery=select passwd from customerejb where ucid=?
2004-09-08 14:54:26,904 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] rolesQuery=select role, role from customerejb where ucid=?
2004-09-08 14:54:26,904 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] login
2004-09-08 14:54:26,906 DEBUG [org.jboss.security.auth.spi.DatabaseServerLoginModule] Bad password for username=2
2004-09-08 14:54:26,907 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] abort
2004-09-08 14:54:26,907 DEBUG [org.jboss.security.plugins.JaasSecurityManager.ejbemarketplacepolicy] Login failure
javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:154)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:675)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
at javax.security.auth.login.LoginContext.login(LoginContext.java:534)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:487)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:442)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:244)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:219)
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:160)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:81)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invokeHome(CachedConnectionInterceptor.java:214)
at org.jboss.ejb.plugins.StatefulSessionInstanceInterceptor.invokeHome(StatefulSessionInstanceInterceptor.java:126)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:88)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
at org.jboss.ejb.plugins.TxInterceptorCMT.invokeHome(TxInterceptorCMT.java:98)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:120)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
at org.jboss.ejb.StatefulSessionContainer.internalInvokeHome(StatefulSessionContainer.java:404)
at org.jboss.ejb.Container.invoke(Container.java:720)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:367)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:536)
2004-09-08 14:54:26,931 ERROR [org.jboss.ejb.plugins.SecurityInterceptor] Authentication exception, principal=2
2004-09-08 14:54:26,932 TRACE [org.jboss.ejb.plugins.StatefulSessionInstancePool] Discard instance:org.jboss.ejb.plugins.StatefulSessionInstancePool@dbb83a#org.jboss.ejb.StatefulSessionEnterpriseContext@1c634b9#null#false#class com.ejbemarketplace.customer.CustomerSBean
2004-09-08 14:54:26,933 TRACE [org.jboss.ejb.plugins.TxInterceptorCMT] TxInterceptorCMT: In finally
2004-09-08 14:54:26,934 ERROR [org.jboss.ejb.plugins.LogInterceptor] EJBException, causedBy:
java.lang.SecurityException: Authentication exception, principal=2
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:164)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:81)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invokeHome(CachedConnectionInterceptor.java:214)
at org.jboss.ejb.plugins.StatefulSessionInstanceInterceptor.invokeHome(StatefulSessionInstanceInterceptor.java:126)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:88)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
at org.jboss.ejb.plugins.TxInterceptorCMT.invokeHome(TxInterceptorCMT.java:98)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:120)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
at org.jboss.ejb.StatefulSessionContainer.internalInvokeHome(StatefulSessionContainer.java:404)
at org.jboss.ejb.Container.invoke(Container.java:720)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:367)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:536)
2004-09-08 14:54:26,938 TRACE [org.jboss.ejb.plugins.LogInterceptor] End method=create
The table(postgresdb; works fine without JAAS) that holds the customer's data looks like this:
Table "public.customerejb"
Column | Type | Modifiers
-------------+--------------------------+-----------
ucid | integer | not null
lname | text |
fname | text |
dobirth | timestamp with time zone |
passwd | text |
role | text |
account | integer |
homeaddress | integer |
Indexes: pk_customerejb primary key btree (ucid)
I've manually inserted one record (INSERT INTO customerejb VALUES(2, 'test', 'test', '01-APR-1970', 'a', 'User', 2, 2)).
login-config.xml:
<application-policy name = "ejbemarketplacepolicy"> <authentication> <!-- <login-module code = "org.jboss.security.auth.spi.ClientLoginModule" flag = "required"/> --> <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> <!-- <module-option name = "dsJndiName">java:/PostgresDS</module-option> --> <!-- <module-option name = "dsJndiName">PostgreSQL</module-option> --> <module-option name = "dsJndiName">java:/PostgresDS</module-option> <module-option name = "password-stacking">useFirstPass</module-option> <module-option name = "unauthenticatedIdentity">Unknown</module-option> <module-option name = "principalsQuery"> select passwd from customerejb where ucid=? </module-option> <module-option name= "rolesQuery"> select role, role from customerejb where ucid=? </module-option> </login-module> </authentication> </application-policy>
deployment-descriptor(ejb-jar.xml) of the SessionBean (it's just a snipplet, because the whole deployment descriptor has about 600 loc):
<?xml version="1.0"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> : : <session> <ejb-name>CustomerSEJB</ejb-name> <home>com.ejbemarketplace.customer.CustomerSHomeRemote</home> <remote>com.ejbemarketplace.customer.CustomerSRemote</remote> <ejb-class>com.ejbemarketplace.customer.CustomerSBean</ejb-class> <session-type>Stateful</session-type> <transaction-type>Container</transaction-type> <ejb-local-ref> <ejb-ref-name>CustomerHomeLocal</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <local-home>com.ejbemarketplace.customer.CustomerHomeLocal</local-home> <local>com.ejbemarketplace.customer.CustomerLocal</local> <ejb-link>CustomerEJB</ejb-link> </ejb-local-ref> <ejb-local-ref> <ejb-ref-name>AddressHomeLocal</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <local-home>com.ejbemarketplace.address.AddressHomeLocal</local-home> <local>com.ejbemarketplace.address.AddressLocal</local> <ejb-link>AddressEJB</ejb-link> </ejb-local-ref> <ejb-local-ref> <ejb-ref-name>AccountHomeLocal</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <local-home>com.ejbemarketplace.account.AccountHomeLocal</local-home> <local>com.ejbemarketplace.account.AccountLocal</local> <ejb-link>AccountEJB</ejb-link> </ejb-local-ref> </session> : : <assembly-descriptor> <security-role> <description> This role represents a user that has access to the e-bean's methods </description> <role-name>User</role-name> </security-role> <security-role> <description> This role represents a new customer </description> <role-name>Unknown</role-name> </security-role> <method-permission> <role-name>Unknown</role-name> <method> <ejb-name>CustomerSEJB</ejb-name> <method-name>create</method-name> </method> </method-permission> : : </assembly-descriptor> </ejb-jar>
To jboss.xml I've added these two lines:
<security-domain>java:/jaas/ejbemarketplacepolicy</security-domain> <unauthenticated-principal>Unknown</unauthenticated-principal>
Code-snipplets of the client are given below:
Client:
private void jIFAuthenticateOKButtonActionPerformed(java.awt.event.ActionEvent evt) { eMarketCallbackHandler emch = new eMarketCallbackHandler( jFormattedTextField3.getText(), jPasswordField1.getPassword().toString() ); try { loginContext = new LoginContext("auth", emch); loginContext.login(); Context jndiContext = new InitialContext(); Object obj = jndiContext.lookup("CustomerSHomeRemote"); CustomerSHomeRemote home = (CustomerSHomeRemote) PortableRemoteObject.narrow(obj, CustomerSHomeRemote.class); CustomerSRemote customer = home.create(); } catch (javax.security.auth.login.LoginException le) { System.out.println("MDIApplication: authenticateUser(String, String) le - " + // le.getMessage()); } catch (javax.naming.NamingException ne) { System.out.println("MDIApplication: authenticateUser(String, String) ne - " + // ne.getMessage()); } catch (CreateException ce) { System.out.println("MDIApplication: authenticateUser(String, String) ce - " + // ce.getMessage()); } catch (RemoteException re) { System.out.println("MDIApplication: authenticateUser(String, String) re - " + // re.getMessage()); }
The "loginContext" variable is defined globally in the swing application. eMarketCallbackHandler looks like this:
public class eMarketCallbackHandler implements javax.security.auth.callback.CallbackHandler { private String username; private char[] password; public eMarketCallbackHandler(String username, char[] password) { this.username = username; this.password = password; } public eMarketCallbackHandler(String username, String password) { this.username = username; this.password = password.toCharArray(); } public void handle(Callback[] callback) throws java.io.IOException, UnsupportedCallbackException { System.out.println("eMarketCallbackHandler: handle(Callback[]) started"); for (int i = 0; i < callback.length; i++) { if (callback instanceof NameCallback) { NameCallback nc = (NameCallback) callback; nc.setName(username); } else if (callback instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) callback; pc.setPassword(password); } else { throw new UnsupportedCallbackException(callback, "Unrecognized Callback"); } } System.out.println("eMarketCallbackHandler: handle(Callback[]) ended"); } }
Two config-files are used by the swing-client:
auth.conf:
auth { org.jboss.security.ClientLoginModule required; };
ejbemarketplace.policy:
grant { permission java.security.AllPermission; };
thanks in advance for any help/hints/.....
cu,
martin