Titel-Logo
Projektstudien
TraceLogger
Basics of Cryptography
Custom JBossAS Login
SOAP Webservice
Role Based Access Control
Introduction
Technologies
Project Structure
Recovery Points
A Walk through the App (I)
A Walk through the App (II)
Installation and Test
PostgreSQL
MySQL
WildFly
Running the Testclient
Webfrontend
Download
Abstract

The RBAC-demo has been tested on Linux Ubuntu 14.04 with PostgreSQL 9.4 (and MySQL 5.5) and on Windows Vista with MySQL 5.6. In the next sections, I shall describe the installation on Windows systems with MySQL and on Linux Ubuntu with PostgreSQL. I cannot spare you from the installation details of one of the mentioned databases. However, I have provided a fully configured WildFly Application server within the Download section. That is to say the configuration instructions belonging to WildFly are mostly optional. If you want to install on Windows, skip the next section and go directly to the paragraph concerning the MySQL installation.

PostgreSQL
  • PostgreSQL APT repository. First we have to enable the PostgreSQL APT repository by adding an appropriate entry within the directory /etc/apt/sources.list.d:
    $ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
    In case of Ubuntu 14.04 (Codename: Trusty Tahr) the above command will create the line

    deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main

    within the file /etc/apt/sources.list.d/pgdg.list. We need to import the public key of the repository too:
    $ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
    Finally we have to trigger the resynchronization of the package sources:
    $ sudo apt-get update
  • Installation of PostgreSQL 9.4. At the time of writing PostgreSQL 9.4 hadn't been published to the official Ubuntu 14.04 package sources. Hence without the previous preparations the next command would probably fail:
    $ sudo apt-get install postgresql-9.4
    Of course you may omit the version number if you don't care about a certain PostgreSQL version. The installation process includes the creation (and start) of a database cluster named main within /var/lib/postgresql/<version>.
  • Manual start and stop a PostgreSQL cluster. Replace auto by manual within the file /etc/postgresql/<version>/<clustername>/start.conf. In our case that would be the file /etc/postgresql/9.4/main/start.conf. Start, stop (or request status info about) the cluster with
    $ sudo pg_ctlcluster 9.4 main [start|stop|status]
  • Setting the admin password. Invoke the PostgreSQL interactive terminal for the postgres-database as dba:
    $ sudo -u postgres psql --dbname=postgres --username=postgres
    [sudo] password for <user>: 
    psql (9.4.1)
    Type "help" for help.
    
    postgres=#
    Set the password with the psql meta-command \password:
    postgres=# \password
    Enter new password:
  • Create the database schema and user account. This must be done by the postgres-(super)user.
    postgres=# CREATE DATABASE rbac_test ENCODING 'UTF8';
    CREATE DATABASE
    postgres=# CREATE USER rbac WITH PASSWORD 'changeit';
    CREATE ROLE
    postgres=# GRANT ALL PRIVILEGES ON DATABASE rbac_test TO rbac;
    GRANT
    postgres=# \quit
  • Create the database tables. First download the RBAC distribution from the Download section and unzip it into a directory of your choice. Next change to the sql/postgresql directory of the RBAC distribution and invoke the setup-script by typing:
    RBAC/sql/postgresql $ ./setup-postgresql.sh
    Note that I'm using a .pgpass file for the user credentials of the recently created database account 'rbac'. If you have changed its password you need to change it within RBAC/sql/postgresql/.pgpass as well. The setup-script gives additional feedback within RBAC/sql/postgresql/out.txt.

You may skip the next section and continue with the instructions for the provisioned WildFly Application Server: WildFly

[Top]

MySQL

Download the suitable ZIP archive from MySQL Community Server. Unzip the archive into C:\ and rename the MySQL distribution to C:\mysql.

  • Test the installation. Open the MS-DOS prompt and change to the C:\mysql\bin directory. Now start the server:
    C:\mysql\bin>mysqld --console
    ...
    2015-04-20 14:38:55 4500 [Note] mysqld: ready for connections.
    Version: '5.6.24'  socket: ''  port: 3306  MySQL Community Server (GPL)
    Next open a second MS-DOS prompt and test the installation by
    C:\mysql\bin>mysqlshow --user=root
    +--------------------+
    |     Databases      |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    +--------------------+
    
    C:\mysql\bin>
  • Secure the root account. Login as root by
    C:\mysql\bin>mysql --user=root
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.6.24 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    This works because by default MySQL doesn't call for a password when connecting from localhost. Update the grant table as follows:
    mysql> UPDATE mysql.user SET password=PASSWORD('changeit') WHERE user='root';
    Query OK, 3 rows affected (0.00 sec)
    Rows matched: 3  Changed: 3  Warnings: 0
    
    mysql> FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql>
  • Create the database schema and user account. This must be done by the MySQL root. The RBAC web application will use the credentials of the to be created 'rbac' account. If you change its password you must configure it within a MySQL option file and within the WildFly standalone-full.xml configuration file later on too.
    mysql> CREATE DATABASE IF NOT EXISTS rbac_test;
    Query OK, 1 row affected (0.02 sec)
    
    mysql> CREATE USER 'rbac'@'localhost' IDENTIFIED BY 'changeit';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> GRANT ALL ON rbac_test.* TO 'rbac'@'localhost';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> GRANT FILE ON *.* TO 'rbac'@'localhost';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> exit
    Bye
    
    C:\mysql\bin>
  • Create the database tables. First download the RBAC distribution from the Download section and unzip it into a directory of your choice. Again open a MS-DOS prompt and navigate to the sql/mysql directory of the RBAC distribution. Note that I'm using an option file for the password and user options of the several MySQL commands needed for the creation of the database tables. You would have to edit the file mysql-rbac.cnf if you changed the password of the 'rbac' user account in the previous step. Now call the setup-mysql.bat MS-DOS batch file which in turn runs the create-rbac-tables.sql and setup-rbac-tables.sql SQL scripts. The latter one presets the tables with the basic scenario.
    RBAC\sql\mysql>setup-mysql.bat > out.txt
    The redirection gives you a readable printout of the useradmin view in tabular format.
  • (Shutdown the database.) The database needs to be running when evaluating the RBAC-demo, of course. But you need to be able to shutdown MySQL after the testing. Prepare a configuration file for the credentials of the MySQL root as shown below:
    [client]
    user=root
    password=changeit
    Now open a MS-DOS prompt and type:
    C:\mysql\bin\mysqladmin --defaults-extra-file=<PATH_TO_CONFIGFILE> shutdown

[Top]

WildFly

In order to avoid the configuration of the WildFly server (JDBC driver, datasource, SSL setup, security domain and deployment) I have provided a fully configured WildFly application server instance within the Download section as shortcut for the impatient. This server instance is even already deployed with the RBAC-demo application. Download the provisioned server into a directory of your choice. The chosen database must be up and running.

[Windows]

You need to register a valid path to a JDK1.7+ into <JBOSS_HOME>\bin\setup-java-home.bat. If you have changed the password of the 'rbac' MySQL account you must adapt the corresponding datasource definition within the <JBOSS_HOME>\standalone\configuration\standalone-full-mysql.xml configuration file of the application server as well. Next, open a MS-DOS prompt and change to <JBOSS_HOME>\bin. Now you may start the server by entering

wildfly-8.2.0.Final\bin>start-server.bat
...
17:21:20,786 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.0.Final "Tweek" started in 30842ms ...

You may proceed with the next section.

[Linux]

You need to register a valid path to a JDK1.7+ into <JBOSS_HOME>/bin/setup-java-home.sh. If you have changed the password of the 'rbac' PostgreSQL account you must adapt the corresponding datasource definition within the <JBOSS_HOME>/standalone/configuration/standalone-full-postgresql.xml configuration file of the application server as well. Next, open a terminal and change to <JBOSS_HOME>/bin. Now you may start the server by entering

wildfly-8.2.0.Final/bin$ ./start-server-with-postgresql.sh
...
12:40:37,434 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.0.Final "Tweek" started in 31666ms ...

You may proceed with the next section.

Now I will explain the configuration of a pure WildFly 8.2 Application Server in detail.

  • Start the server. Open a terminal and change to <JBOSS_HOME>/bin. Now start the server by typing
    wildfly-8.2.0.Final/bin$ ./standalone.sh --server-config=standalone-full.xml
    A <JDK1.7+>/bin/java needs to be on the PATH or prepare a JAVA_HOME environment variable.
  • Add a Management user. Open another terminal, change again to <JBOSS_HOME>/bin and type
    wildfly-8.2.0.Final/bin$ ./add-user.sh
    Follow the advices and keep the presettings. This new user is not "going to be used for one AS process to connect to another AS process", hence type 'no' for the last question. You can use this account to log into the management console of the server:
    http://localhost:9990/console/App.html
    However, we will use the CLI (command line interpreter) for the configurations.
  • Connect to the server. Reuse the open terminal and type
    ./jboss-cli.sh --connect
    [standalone@localhost:9990 /]
    This connects you to the local running server instance.
  • JDBC driver and Datasource. You'll have to specify a file path to an JAR containing the driver.
    [standalone@localhost:9990 /] deploy <PATH_TO_JDBC_DRIVER>
    [standalone@localhost:9990 /]
    The next command gives you the list of the deployed JDBC drivers. We need this list because of the name of the driver as given by the server instance:
    [standalone@localhost:9990 /] /subsystem=datasources/:installed-drivers-list
    {
        "outcome" => "success",
        "result" => [
            {
                "driver-name" => "mysql-connector-java-5.1.34-bin.jar_com.mysql.jdbc.Driver_5_1",
                "deployment-name" => "mysql-connector-java-5.1.34-bin.jar_com.mysql.jdbc.Driver_5_1",
                "driver-module-name" => undefined,
                "module-slot" => undefined,
                "driver-datasource-class-name" => undefined,
                "driver-xa-datasource-class-name" => undefined,
                "driver-class-name" => "com.mysql.jdbc.Driver",
                "driver-major-version" => 5,
                "driver-minor-version" => 1,
                "jdbc-compliant" => false
            },
            {
                "driver-name" => "postgresql-9.4-1201.jdbc41.jar",
                "deployment-name" => "postgresql-9.4-1201.jdbc41.jar",
                "driver-module-name" => undefined,
                "module-slot" => undefined,
                "driver-datasource-class-name" => undefined,
                "driver-xa-datasource-class-name" => undefined,
                "driver-class-name" => "org.postgresql.Driver",
                "driver-major-version" => 9,
                "driver-minor-version" => 4,
                "jdbc-compliant" => false
            },
            {
                "driver-name" => "h2",
                "deployment-name" => undefined,
                "driver-module-name" => "com.h2database.h2",
                "module-slot" => "main",
                "driver-datasource-class-name" => "",
                "driver-xa-datasource-class-name" => "org.h2.jdbcx.JdbcDataSource",
                "driver-class-name" => "org.h2.Driver",
                "driver-major-version" => 1,
                "driver-minor-version" => 3,
                "jdbc-compliant" => true
            },
            {
                "driver-name" => "mysql-connector-java-5.1.34-bin.jar_com.mysql.fabric.jdbc.FabricMySQLDriver_5_1",
                "deployment-name" => "mysql-connector-java-5.1.34-bin.jar_com.mysql.fabric.jdbc.FabricMySQLDriver_5_1",
                "driver-module-name" => undefined,
                "module-slot" => undefined,
                "driver-datasource-class-name" => undefined,
                "driver-xa-datasource-class-name" => undefined,
                "driver-class-name" => "com.mysql.fabric.jdbc.FabricMySQLDriver",
                "driver-major-version" => 5,
                "driver-minor-version" => 1,
                "jdbc-compliant" => false
            }
        ]
    }
    [standalone@localhost:9990 /]
    In case of the MySQL JDBC JAR: there are actual two drivers contained. We need the one without the 'Fabric':
    [standalone@localhost:9990 /] data-source add --name=dms_prototype --connection-url=jdbc:mysql://localhost:3306/rbac_test --jndi-name=java:/jdbc/DocumentBaseDS --driver-name=mysql-connector-java-5.1.34-bin.jar_com.mysql.jdbc.Driver_5_1 --user-name=rbac --password=changeit --max-pool-size=15 --min-pool-size=5
    [standalone@localhost:9990 /]
    Review your datasource configuration with
    [standalone@localhost:9990 /] /subsystem=datasources/data-source=dms_prototype/:read-resource
    {
        "outcome" => "success",
        "result" => {
            "allocation-retry" => undefined,
            "allocation-retry-wait-millis" => undefined,
            "allow-multiple-users" => false,
            "background-validation" => undefined,
            "background-validation-millis" => undefined,
            "blocking-timeout-wait-millis" => undefined,
            "capacity-decrementer-class" => undefined,
            "capacity-decrementer-properties" => undefined,
            "capacity-incrementer-class" => undefined,
            "capacity-incrementer-properties" => undefined,
            "check-valid-connection-sql" => undefined,
            "connection-listener-class" => undefined,
            "connection-listener-property" => undefined,
            "connection-properties" => undefined,
            "connection-url" => "jdbc:mysql://localhost:3306/rbac_test",
            "datasource-class" => undefined,
            "driver-class" => undefined,
            "driver-name" => "mysql-connector-java-5.1.34-bin.jar_com.mysql.jdbc.Driver_5_1",
            "enabled" => true,
            "exception-sorter-class-name" => undefined,
            "exception-sorter-properties" => undefined,
            "flush-strategy" => undefined,
            "idle-timeout-minutes" => undefined,
            "initial-pool-size" => undefined,
            "jndi-name" => "java:/jdbc/DocumentBaseDS",
            "jta" => true,
            "max-pool-size" => 15,
            "min-pool-size" => 5,
            "new-connection-sql" => undefined,
            "password" => "changeit",
            "pool-prefill" => undefined,
            "pool-use-strict-min" => undefined,
            "prepared-statements-cache-size" => undefined,
            "query-timeout" => undefined,
            "reauth-plugin-class-name" => undefined,
            "reauth-plugin-properties" => undefined,
            "security-domain" => undefined,
            "set-tx-query-timeout" => false,
            "share-prepared-statements" => false,
            "spy" => false,
            "stale-connection-checker-class-name" => undefined,
            "stale-connection-checker-properties" => undefined,
            "track-statements" => "NOWARN",
            "transaction-isolation" => undefined,
            "url-delimiter" => undefined,
            "url-selector-strategy-class-name" => undefined,
            "use-ccm" => true,
            "use-fast-fail" => false,
            "use-java-context" => true,
            "use-try-lock" => undefined,
            "user-name" => "rbac",
            "valid-connection-checker-class-name" => undefined,
            "valid-connection-checker-properties" => undefined,
            "validate-on-match" => false,
            "statistics" => {
                "jdbc" => undefined,
                "pool" => undefined
            }
        }
    }
    [standalone@localhost:9990 /]
    The datasource can be enabled, if necessary, by typing
    [standalone@localhost:9990 /] /subsystem=datasources/data-source=dms_prototype/:enable
    [standalone@localhost:9990 /]
  • SSL setup. First we need to create a key pair. Open another terminal and change to <JBOSS_HOME>/standalone/configuration, then type:
    wildfly-8.2.0.Final/standalone/configuration$ export JAVA_HOME=/opt/java/jdk1.8.0_45
    wildfly-8.2.0.Final/standalone/configuration$ ${JAVA_HOME}/bin/keytool -genkeypair -alias server -keyalg RSA -keystore server.keystore -validity 365 -storepass changeit -dname "cn=myserver" -keypass changeit
    Done, switch back to the JBOSS CLI. We need to create a security realm with a server identity:
    [standalone@localhost:9990 /] /core-service=management/security-realm=MySecurityRealm/:add(map-groups-to-roles=true)
    {"outcome" => "success"}
    [standalone@localhost:9990 /]
    Review the just made configuration:
    [standalone@localhost:9990 /] /core-service=management/security-realm=MySecurityRealm/:read-resource(recursive=true)
    {
        "outcome" => "success",
        "result" => {
            "map-groups-to-roles" => true,
            "authentication" => undefined,
            "authorization" => undefined,
            "plug-in" => undefined,
            "server-identity" => undefined
        }
    }
    [standalone@localhost:9990 /]
    The server identity still has to be defined. The next command uses the recently created keystore:
    [standalone@localhost:9990 /] /core-service=management/security-realm=MySecurityRealm/server-identity=ssl:add(keystore-path=server.keystore, keystore-relative-to=jboss.server.config.dir, keystore-password=changeit, alias=server)
    {
        "outcome" => "success",
        "response-headers" => {
            "operation-requires-reload" => true,
            "process-state" => "reload-required"
        }
    }
    [standalone@localhost:9990 /] reload
    [standalone@localhost:9990 /]
    Again, review the just made configuration:
    [standalone@localhost:9990 /] /core-service=management/security-realm=MySecurityRealm/:read-resource(recursive=true)
    {
        "outcome" => "success",
        "result" => {
            "map-groups-to-roles" => true,
            "authentication" => undefined,
            "authorization" => undefined,
            "plug-in" => undefined,
            "server-identity" => {"ssl" => {
                "alias" => "server",
                "enabled-cipher-suites" => undefined,
                "enabled-protocols" => [
                    "TLSv1",
                    "TLSv1.1",
                    "TLSv1.2"
                ],
                "key-password" => undefined,
                "keystore-password" => "changeit",
                "keystore-path" => "server.keystore",
                "keystore-provider" => "JKS",
                "keystore-relative-to" => "jboss.server.config.dir",
                "protocol" => "TLS"
            }}
        }
    }
    [standalone@localhost:9990 /]
    Next we create a HTTP listener by referencing our security realm:
    [standalone@localhost:9990 /] /subsystem=undertow/server=default-server/https-listener=ssl-listener-1/:add(socket-binding=https,security-realm=MySecurityRealm)
    {"outcome" => "success"}
    [standalone@localhost:9990 /]
    Again, review the just made configuration:
    [standalone@localhost:9990 /] /subsystem=undertow/server=default-server/https-listener=ssl-listener-1/:read-resource(recursive=false)
    {
        "outcome" => "success",
        "result" => {
            "allow-encoded-slash" => false,
            "allow-equals-in-cookie-value" => false,
            "always-set-keep-alive" => true,
            "buffer-pipelined-data" => true,
            "buffer-pool" => "default",
            "decode-url" => true,
            "enabled" => true,
            "enabled-cipher-suites" => undefined,
            "enabled-protocols" => undefined,
            "max-buffered-request-size" => 16384,
            "max-cookies" => 200,
            "max-header-size" => 51200,
            "max-headers" => 200,
            "max-parameters" => 1000,
            "max-post-size" => 10485760L,
            "no-request-timeout" => -1,
            "read-timeout" => undefined,
            "receive-buffer" => undefined,
            "record-request-start-time" => false,
            "request-parse-timeout" => -1,
            "resolve-peer-address" => false,
            "security-realm" => "MySecurityRealm",
            "send-buffer" => undefined,
            "socket-binding" => "https",
            "tcp-backlog" => undefined,
            "tcp-keep-alive" => undefined,
            "url-charset" => "UTF-8",
            "verify-client" => "NOT_REQUESTED",
            "worker" => "default",
            "write-timeout" => undefined
        }
    }
    [standalone@localhost:9990 /]
  • Security Domain. We need such a domain to protect the application. Type
    [standalone@localhost:9990 /] /subsystem=security/security-domain=MyFormAuthentication/:add
    {"outcome" => "success"}
    [standalone@localhost:9990 /]
    Now we have to specify the desired login module and its options. Like the configuration of the datasource this depends on the particular database. The 'principalsQuery' and 'rolesQuery' module options are different for PostgreSQL:
    [standalone@localhost:9990 /] /subsystem=security/security-domain=MyFormAuthentication/authentication=classic:add(login-modules=[{"code"=>"de.christofreichardt.jboss.login.SaltedPasswordLoginModule", "flag"=>"required", "module-options"=>["dsJndiName"=>"java:/jdbc/DocumentBaseDS","principalsQuery"=>"SELECT DISTINCT password, salt FROM useradmin WHERE snapshot = (SELECT MAX(id) FROM snapshot) AND disabled = 'N' AND failures < trials AND BINARY user = ?", "rolesQuery"=>"SELECT groupname FROM useradmin WHERE snapshot = (SELECT MAX(id) FROM snapshot) AND BINARY user = ?", "useFirstPass"=>"false"]}])
    {
        "outcome" => "success",
        "response-headers" => {
            "operation-requires-reload" => true,
            "process-state" => "reload-required"
        }
    }
    [standalone@localhost:9990 /] reload
    [standalone@localhost:9990 /]
  • Deployment. You'll need to enter the path to the RBAC distribution:
    [standalone@localhost:9990 /] deploy -f <PATH_TO_RBAC_DISTRIBUTION>/RBAC/RBAC-web/target/RBAC-web-0.0.1-SNAPSHOT.war
    [standalone@localhost:9990 /]
    That's it. Everything needed is configured.
  • (Shutdown the Application Server) Of course the server needs to be running when executing the test client.
    wildfly-8.2.0.Final/bin$ ./jboss-cli.sh -c --command=shutdown

[Top]

Running the Testclient

[Windows]

First you need to adapt the RBAC\RBAC-test\start.bat script by entering a valid path to a JDK1.7+. Now open a MS-DOS prompt and change to the RBAC\RBAC-test directory. The remote test client reuses the mentioned setup-rbac-tables.sql script for the setup of the basic scenario by forking a new mysql client process (see mysql — The MySQL Command-Line Tool) and redirecting its standard input to the content of the script. This is very convenient but unfortunately very slow on Windows. The running time on my Linux system for the execution of the tests is many times faster. An analysis of the RBAC\RBAC-test\log\IntegrationTest.log shows that the majority of the time is consumed by the setup process whereas the actual execution of the tests needs only a fraction of that time. Hence the setup of the database scenarios for real world projects might better make use of a JDBC connection.

RBAC\RBAC-test>start.bat
...
result.getRunCount() = 8
result.getFailureCount() = 0
result.getRunTime() = 47830ms

TraceLogger[IntegrationTest]: Stream error state = ok. Closing ...

[Linux]

First you need to adapt the RBAC/RBAC-test/start.sh script by entering a valid path to a JDK1.7+. Second you need to edit the test.properties file (the default value is mysql):

de.christofreichardt.documentbase.integrationtest.db=postgresql

Now open a terminal and change to the RBAC/RBAC-test directory. The remote test client reuses the mentioned setup-rbac-tables.sql script for the setup of the basic scenario by forking a new psql client process (see psql -- PostgreSQL interactive terminal)

RBAC/RBAC-test$ ./start.sh
...
result.getRunCount() = 8
result.getFailureCount() = 0
result.getRunTime() = 8245ms

TraceLogger[IntegrationTest]: Stream error state = ok. Closing ...
There is not much difference between using mysql or psql on my Linux system. Hence the reason for the performance degradation must lie elsewhere.

[Top]

Webfrontend

The webfrontend can be invoked by entering

http://localhost:8080/DocumentBase-web/start.jsf

within the address bar of a browser. The plaintext password of the 'supertester' account is 'Hokuspokus' as provided by the basic setup. Only accounts which fulfill the 'appadmin' role can access the application. Note that the provisioned server uses a self-signed certificate and hence the browsers will complain about an untrusted connection since they cannot trace the certification path to a well known certificate authority (CA).

[Top]

Valid XHTML 1.0 Strict