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

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

    rustlet

      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.

        • 1. Re: WildFly can't find database table in form-based authentication
          wdfink

          I did not tried your approach.

          But you might use JDBC spy logging to see what happen, this might give you a hint what is going wrong..

           

          Add the attribute "spy=true" for your datasource and add the category to your logging configuration. You'll see all JDBC commands for the DS.

           

          <logger category="jboss.jdbc.spy">
            <level name="TRACE"/>
          </logger>

          • 2. Re: WildFly can't find database table in form-based authentication
            rustlet

            Thanks for your reply. I received a response to this question on Stackoverflow and as it turns out my connection URL is supposed to be set to


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

             

            A careless oversight on my part.

             

            Thanks for the tip on JDBC spy logging. I wasn't aware of that and it will probably come in handy in the future.