2 Replies Latest reply on Feb 1, 2016 9:43 AM by Russell Todd

    WildFly can't find database table in form-based authentication

    Russell Todd Newbie

      Hi All,

       

      I've just started programming with Java EE and I'm trying to implement a simple web app that uses form-based user authentication with the JBoss database login module. When I run my web app and go to the home page it takes me to a login page. So far, so good. But when I submit the username and password the login fails with the following stack trace in server.log


      ...

      2016-01-28 14:22:37,028 TRACE [org.jboss.security] (default task-5) PBOX00236: Begin initialize method

      2016-01-28 14:22:37,028 DEBUG [org.jboss.security] (default task-5) PBOX00281: Password hashing activated, algorithm: SHA-256, encoding: base64, charset: null, callback: null, storeCallBack: null

      2016-01-28 14:22:37,028 TRACE [org.jboss.security] (default task-5) PBOX00262: Module options [dsJndiName: java:/PostgresHibrid, principalsQuery: select passwd from users where username=?, rolesQuery: select role, 'Roles' from userroles where username=?, suspendResume: true]

      2016-01-28 14:22:37,029 TRACE [org.jboss.security] (default task-5) PBOX00240: Begin login method

      2016-01-28 14:22:37,030 TRACE [org.jboss.security] (default task-5) PBOX00263: Executing query select passwd from users where username=? with username user0

      2016-01-28 14:22:37,037 TRACE [org.jboss.security] (default task-5) PBOX00244: Begin abort method, overall result: false

      2016-01-28 14:22:37,037 DEBUG [org.jboss.security] (default task-5) PBOX00206: Login failure: javax.security.auth.login.LoginException: PBOX00065: Error processing query

          at org.jboss.security.auth.spi.DatabaseServerLoginModule.getUsersPassword(DatabaseServerLoginModule.java:202)

          at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:265)

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

          at java.lang.reflect.Method.invoke(Method.java:498)

          at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)

          at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)

          at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)

          at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)

          at java.security.AccessController.doPrivileged(Native Method)

          at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)

          at javax.security.auth.login.LoginContext.login(LoginContext.java:587)

          at org.jboss.security.authentication.JBossCachedAuthenticationManager.defaultLogin(JBossCachedAuthenticationManager.java:406)

          at org.jboss.security.authentication.JBossCachedAuthenticationManager.proceedWithJaasLogin(JBossCachedAuthenticationManager.java:345)

          at org.jboss.security.authentication.JBossCachedAuthenticationManager.authenticate(JBossCachedAuthenticationManager.java:333)

          at org.jboss.security.authentication.JBossCachedAuthenticationManager.isValid(JBossCachedAuthenticationManager.java:146)

          at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:111)

          at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verify(JAASIdentityManagerImpl.java:82)

          at io.undertow.security.impl.FormAuthenticationMechanism.runFormAuth(FormAuthenticationMechanism.java:124)

          at io.undertow.security.impl.FormAuthenticationMechanism.authenticate(FormAuthenticationMechanism.java:96)

          at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:339)

          at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:356)

          at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:325)

          at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:138)

          at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:113)

          at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:106)

          at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)

          at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)

          at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

          at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)

          at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)

          at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)

          at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)

          at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)

          at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)

          at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)

          at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)

          at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

          at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)

          at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

          at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)

          at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282)

          at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261)

          at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80)

          at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172)

          at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)

          at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774)

          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

          at java.lang.Thread.run(Thread.java:745)

      Caused by: org.postgresql.util.PSQLException: ERROR: relation "users" does not exist

        Position: 20

          at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)

          at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)

          at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)

          at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:622)

          at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:472)

          at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:386)

          at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)

          at org.jboss.security.auth.spi.DatabaseServerLoginModule.getUsersPassword(DatabaseServerLoginModule.java:185)

          ... 50 more

       

      2016-01-28 14:22:37,038 TRACE [org.jboss.security] (default task-5) PBOX00201: End isValid, result = false

      2016-01-28 14:22:37,040 TRACE [org.jboss.security] (default task-5) PBOX00354: Setting security roles ThreadLocal: null   

      ...

       

      It looks like the application can't find the table of users in the database. Any ideas as to what's causing this?

       

      My configuration info follows. I'm using WildFly 9.0.2 Final and PostgreSQL 9.3. and I'm running on CentOS 6.

       

      Setting up database in PostgreSQL

       

      1) As user postgres

       

      postgres=# create user hibrid with password 'hibrid';

      postgres=# alter role hibrid with createdb;

      postgres=# \du

                                   List of roles

      Role name |                   Attributes                   | Member of

      -----------+------------------------------------------------+-----------

      hibrid    | Create DB                                      | {}

      postgres  | Superuser, Create role, Create DB, Replication | {}

       

      postgres=# create database hibrid owner hibrid;

      postgres=# \l

                                        List of databases

         Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges  

      -----------+----------+----------+-------------+-------------+-----------------------

      hibrid    | hibrid   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |


      2) As user hibrid


      hibrid=> \c hibrid

      hibrid=> CREATE TABLE users(username VARCHAR(255) PRIMARY KEY, passwd VARCHAR(255));

      hibrid=> CREATE TABLE userroles(username VARCHAR(255), role VARCHAR(32));

      hibrid=> \d

                List of relations

      Schema |   Name    | Type  | Owner 

      --------+-----------+-------+--------

      public | userroles | table | hibrid

      public | users     | table | hibrid

      (2 rows)

       

      hibrid=> INSERT INTO users (username, passwd) values ('user0', 'Eu9N7XpGSO2ujqTCad1XT9U4qGhfDFNvLz9+53qpSaM=');

      hibrid=> select * from users;

      username |                    passwd                   

      ----------+----------------------------------------------

      user0    | Eu9N7XpGSO2ujqTCad1XT9U4qGhfDFNvLz9+53qpSaM=

      (1 row)

       

      hibrid=> INSERT INTO userroles (username, role) values ('user0', 'ADMIN');

      hibrid=> select * from userroles;

      username | role 

      ----------+-------

      user0    | ADMIN

      (1 row)


      Installing PostgreSQL JDBC driver in WildFly

       

      1) Download the latest Postgres JDBC driver from https://jdbc.postgresql.org/download.html. We will assume the driver is downloaded to the directory /home/hibrid/bin and is named postgresql-9.4.1207.jar.

       

      2) Start the WildFly CLI and connect to running WildFly instance


      % ./jboss-cli.sh

      [... /] connect


      3) Install the module containing the JDBC driver.


      [... /] module add --name=org.postgres --resources=/home/hibrid/bin/postgresql-9.4.1207.jar --dependencies=javax.api,javax.transaction.api


      4) Install the JDBC Driver on the application server


      [... /] /subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver)

      {"outcome" => "success"}


      5) Datasource section of standalone-full.xml and standalone.xml now looks like this


      <subsystem xmlns="urn:jboss:domain:datasources:3.0">

          <datasources>

              <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">

                  <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>

                  <driver>h2</driver>

                  <security>

                      <user-name>sa</user-name>

                      <password>sa</password>

                  </security>

              </datasource>

              <datasource jndi-name="java:/PostgresHibrid" pool-name="PostgresHibrid" enabled="true">

                  <connection-url>jdbc:postgresql://localhost/postgres</connection-url>

                  <driver>postgres</driver>

                  <security>

                      <user-name>hibrid</user-name>

                      <password>hibrid</password>

                  </security>

              </datasource>

              <drivers>

                  <driver name="h2" module="com.h2database.h2">

                      <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>

                  </driver>

                  <driver name="postgres" module="org.postgres">

                      <driver-class>org.postgresql.Driver</driver-class>

                  </driver>

              </drivers>

          </datasources>

      </subsystem>


      WebApp web.xml file


      <?xml version="1.0" encoding="UTF-8"?>

      <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

          <context-param>

              <param-name>javax.faces.PROJECT_STAGE</param-name>

              <param-value>Development</param-value>

          </context-param>

          <servlet>

              <servlet-name>Faces Servlet</servlet-name>

              <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

              <load-on-startup>1</load-on-startup>

          </servlet>

          <servlet-mapping>

              <servlet-name>Faces Servlet</servlet-name>

              <url-pattern>/faces/*</url-pattern>

          </servlet-mapping>

          <session-config>

              <session-timeout>

                  30

              </session-timeout>

          </session-config>

          <welcome-file-list>

              <welcome-file>faces/index.xhtml</welcome-file>

          </welcome-file-list>

          <security-constraint>

              <web-resource-collection>

                  <web-resource-name>HtmlAuth</web-resource-name>

                  <description>application security constraints </description>

                  <url-pattern>/*</url-pattern>

                  <http-method>GET</http-method>

                  <http-method>POST</http-method>

                  <http-method>PUT</http-method>

                  <http-method>DELETE</http-method>

              </web-resource-collection>

              <auth-constraint>

                  <role-name>ADMIN</role-name>

              </auth-constraint>

          </security-constraint>

          <login-config>

              <auth-method>FORM</auth-method>

              <form-login-config>

                  <form-login-page>/login.xhtml</form-login-page>

                  <form-error-page>/error.xhtml</form-error-page>

              </form-login-config>

          </login-config>

          <security-role>

              <role-name>ADMIN</role-name>

          </security-role>

      </web-app>


      WebApp jboss-web.xml file


      <?xml version="1.0" encoding="UTF-8"?>

      <jboss-web>

          <security-domain>hibridDomain</security-domain>

      </jboss-web>


      Thanks for your help.