Jboss Admin Tutorial: Security on JBoss

16. Security on JBoss

16.1. Securing Applications

  • Filtering clients by source IP addresses
  • Requiring authentication and authorization
  • Data transport integrity and confidentiality (SSL)

We will explore each one of these in turn

16.2. Filtering Clients by Source

  • Limit access to web applications by client IP or hostname
  • Configured through Tomcat Valves

    • Different levels: <Engine> (global), <Host> (per virtual host), <Context> (per web application)

      <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.*,127.*" />
      <Valve className="org.apache.catalina.valves.RemoteHostValve" deny="spamhost.com" />
  • Configured through a Servlet Filter

    • Simple implementation is provided by JBoss but servlet filters are Java EE AS-independent
  • To limit client access through Tomcat, add a desired <Valve> in <Engine> or <Host> elements within ${jboss.server.home.url}/deploy/jbossweb.sar/server.xml file
  • Limiting per web application can be still done through Tomcat by creating a <Context> file ${jboss.server.home.url}/deploy/<app>.war/WEB-INF/context.xml:

      <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.*.*" />
  • To limit client access in a application-server-neutral way, configure a servlet filter in WEB-INF/web.xml file as follows:

    <web-app ...>

    A simple implementation of this filter can be found at http://community.jboss.org/wiki/LimitAccessToCertainClients

16.3. Authentication & Authorization

Security is a fundamental part of any enterprise application. You need to be able to restrict who is allowed to access your applications and control what operations application users may perform.

  • JAAS - Java Authentication and Authorization Service (pure Java)
  • Pluggable Authentication Module framework: JNDI, UNIX, Windows, Kerberos, Keystore
  • Support for single sing-on
  • Role-based access control
  • Separates business logic from A&A
  • Declarative (XML-based)

    • Described in deployment descriptors instead of being hard-coded
    • Isolate security from business-level code
  • For example, consider a bank account application. The security requirements, roles, and permissions will vary depending on how is the bank account accessed:

    • via the internet (username + password), via an ATM (card + pin), or at a branch (Photo ID + signature).
    • We benefit by separating the business logic of how bank accounts behave from how bank accounts are accessed.
  • Securing a Java EE application is based on the specification of the application security requirements via the standard Java EE deployment descriptors.

    • EJBs and web components in an enterprise application by using the ejb-jar.xml and web.xml deployment descriptors.

16.4. Requiring A&A

  • Adding security-constraint in web.xml:

    <web-app ...>
              <web-resource-name>All Resources</web-resource-name>
              <description>Protect all content</description>
  • Element <security-constraint> declares the web resources to be protected and the role required to access those resources.
  • Element <web-resource-name> is required, and it simply assigns a name to the declared <web-resource-collection>.
  • Element <description> is optional, and it provides textual description of the declared <web-resource-collection>.
  • Element <url-pattern> is optional (although, without it the <web-resource-collection> is ignored), and it declares to which URL patterns this security constraint applies. URL patterns can be catch-all ("/*") or they can be repeated to list specific resources. For example:

  • The preceding slash (/) character makes the URLs absolute within the web application only.
  • In addition to URL patterns, it is also possible to limit the security constraint to HTTP methods using the <http-method> element as follows:

  • If the <http-method> element is omitted, the default behavior is to apply the security constraint to all HTTP methods.
  • The <auth-constraint> element indicates the user roles that should be permitted access to this resource collection. The <role-name> used here must either correspond to the <role-name> of one of the <security-role> elements defined for this web application (more on this soon), or be the specially reserved role-name "*" that is a compact syntax for indicating all roles in the web application. If no roles are defined, no user is allowed access to the portion of the web application described by the containing security-constraint. JBoss AS matches role names case sensitively when determining access.
  • Adding login configuration:

    <web-app ...>
            <realm-name>My Secure Application</realm-name>

Element <login-config> configures the login method for the secured resource.

In this case we just use HTTP BASIC authentication, but other options for JBoss are: DIGEST, FORM, and CLIENT-CERT. We will cover some of these later.

  • Declaring security roles:

    <web-app ...>
        <description>All members of MyRole</description>
  • If multiple roles are desired, declare them as follows:

    <web-app ...>
        <web-resource-collection> ... </web-resource-collection>
      <login-config> ... </login-config>

16.5. Plain-Text Login Module

  • Already enabled by default
  • WEB-INF/classes/users.properties:

  • WEB-INF/classes/roles.properties:

  • Provided by org.jboss.security.auth.spi.UsersRolesLoginModule configured in file ${jboss.server.config.url}/login-config.xml:

      <application-policy name="other">
          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required" />

The properties files users.properties and roles.properties are loaded during initialization of the context class loader. This means that these files can be placed into any Java EE deployment archive (e.g. WAR), the JBoss configuration directory, or any directory on the JBoss server or system classpath. Placing these files in the ${jboss.server.home.url}/deploy/<app>/WEB-INF/classes directory makes them unique to that specific web application. Moving them to ${jboss.server.config.url} directory makes them "global" to the entire JBoss AS instance.

  • To change the names of these files, expand the <login-module> as follows:

    <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
      <module-option name="usersProperties">myUsers.properties</module-option>
      <module-option name="rolesProperties">myRoles.properties</module-option>

16.6. Database Login Module

  • Fetches login info from a RDBMS
  • Works with existing DB schemas
  • Uses pooled database connections
  • Scales well as the user population grows
  • Does not require server or application restarts on info change

Database Login Module depends on our ability to set up (and link to) a JBoss-managed DataSource (database connection pool).

16.6.1. MySQL Schema/DB Setup

term#> mysql/bin/mysql -u root -p
mysql> CREATE DATABASE Authority;
mysql> USE Authority;
mysql> CREATE TABLE Roles (Username VARCHAR(32) NOT NULL,Rolename VARCHAR(32) NOT NULL,PRIMARY KEY (Username, Rolename));
mysql> GRANT SELECT ON Authority.* TO authority@localhost IDENTIFIED BY "authsecret";

It is important that the password field be at least 32 characters in order to accommodate MD5-digest-based passwords (more on this later).

You do not have to create a separate database, nor do you need separate tables, but we assume that we are starting from scratch. The default JBoss AS schema for User/Role information is as follows:

  • Table Principals(PrincipalID text, Password text)
  • Table Roles(PrincipalID text, Role text, RoleGroup text)

You also do not need a auth-specific read-only database user, but we create one because it is a good practice.

Populate the database. For example:

INSERT INTO Users VALUES ("john", "secret");
INSERT INTO Roles VALUES ("john", "MyRole");
INSERT INTO Users VALUES ("bob", "abc123");
INSERT INTO Roles VALUES ("bob", "MyRole");
INSERT INTO Roles VALUES ("bob", "Manager");
INSERT INTO Users VALUES ("mike", "passwd");
INSERT INTO Roles VALUES ("mike", "Manager");
INSERT INTO Roles VALUES ("mike", "Admin");

16.6.2. Authority Database Resource

  • Create deploy/authority-ds.xml:


Define a database connection pool (resource) that will provide connectivity to the Authority database.

16.6.3. Configure DB Login Module

  • Add to conf/login-config.xml:

    <application-policy name="MyPolicy">
        <login-module flag="required" code="org.jboss.security.auth.spi.DatabaseServerLoginModule">
          <module-option name="dsJndiName">java:/AuthorityDB</module-option>
          <module-option name="principalsQuery">SELECT Password FROM Users WHERE Username=?</module-option>
          <module-option name="rolesQuery">SELECT Rolename, "Roles" FROM Roles WHERE Username=?</module-option>
  • Application policy name declares a new policy. We will reference this name in each [web] application that wishes to use it.
  • The required flag means that the login module is required to succeed.

    • If it succeeds or fails, authentication still continues to proceed down the LoginModule list
    • Other options are: requisite, sufficient, and optional
  • Module option dsJndiName:

    • Defines the JNDI name of the RDBMS DataSource that defines logical users and roles tables
    • Defaults to java:/DefaultDS
  • Module option principalsQuery:

    • Defines a prepared SQL statement that queries the password of a given username
    • Defaults to select Password from Principals where PrincipalID=?
  • Module option rolesQuery:

    • Defines a prepared SQL statement that queries role names (and groups) of a given username
    • The default group name is Roles (hard-coded). Defaults to select Role, RoleGroup from Roles where PrincipalID=?

16.6.4. Link to Security Domain

  • Add to WEB-INF/jboss-web.xml:

  • Default security domain is other, which authenticates against the properties files
  • Security domains declared in conf/login-config.xml are relative to java:/jaas/ JNDI context

16.6.5. Securing Passwords

  • Configure hashed passwords in conf/login-config.xml:

    <login-module ...>
      <module-option name="hashAlgorithm">MD5</module-option>
      <module-option name="hashEncoding">hex</module-option>
  • Change users.properties:


16.7. FORM-based Login

  • Session-based

    • Allows Logout - session.invalidate()
    • Automatically expires when the session expires
    • More efficient and secure - single authentication
  • Fully customizable

    • Control the layout of the login page
    • Control the layout of the error page
    • Provide links to "user registration" or "recover password" actions
  • Support for FORM-based login is part of the Java EE specification, and like the rest of JAAS-based security, it is independent of the application server
  • With the FORM-based login, the server forces the users to login via an HTML form when it detects the user’s session is not authenticated

    • This is accomplished by forwarding the users' requests to the login page
    • In case of authentication failures, users are sent to the login error page

16.7.1. Login.jsp Form Page

  • JBoss handler: j_security_check for params j_username and j_password

      <head><title>Login Form</title></head>
        <h1>Login Form</h1>
        <form action="j_security_check" method="post">
          <input type="text" name="j_username"/><br/>
          <input type="password" name="j_password"/><br/>
          <input type="submit" value="Login" />
  • To support non-cookie-based-session-tracking, change j_security_check to

    <%= response.encodeURL("j_security_check") %>

    which will add JSESSIONID to the request URL if needed.

16.7.2. LoginError.jsp Page

  • Displays the error message if the authentication fails

      <head><title>Login Error</title></head>
        <h1>Authentication Error</h1>
        <p style="color: red">
          Invalid username and/or password.
        <p><a href="Login.jsp">Try again?</a></p>

This page is only shown if user enters invalid username and/or password. Authorization errors (user not in required role) are handled separately.

16.7.3. Update Login Configuration

  • Update <login-config> in web.xml:


16.7.4. Authorization Failure

  • Authorization failures are expressed by HTTP 403 status codes
  • Use <error-page> element to configure HTTP 403 handler in web.xml:


16.8. Configuring JBoss AS for SSL

  • Create (or import) SSL certificates using keytool Java command-line utility
  • Configure SSL connector in Tomcat
  • Require SSL per application/context using <user-data-constraint>

Adding support for SSL (Secure Socket Layer) is only useful if JBoss AS acts as a stand-alone web server. If JBoss AS is fronted by another web server, like Apache HTTPD, then the security of the communication channel becomes the responsibility of that web server. In that case, JBoss AS communicates with the web server over an unsecured channel (plain-text), but the web server still informs JBoss about the security protocol it has negotiated with the end client.

16.9. Creating SSL Certificates

  • Only JKS or PKCS12 formats are supported
  • Use JDK’s keytool command-line tool
  • Keystore password and certificate password have to be the same (default is "changeit")
  • Certificate alias is "tomcat"
  • Use RSA algorithm for broader support
  • Use JBoss-specific keystore file
  • Use site hostname for cert’s common name

For example, run the following from within ${jboss.server.home.url} directory:

keytool -genkey -keystore conf/ssl.ks  -storepass secret
        -alias tomcat -keyalg RSA -keypass secret
What is your first and last name?
  [Unknown]:  localhost
What is the name of your organizational unit?
  [Unknown]:  IT
What is the name of your organization?
  [Unknown]:  Secure Org
What is the name of your City or Locality?
  [Unknown]:  San Francisco
What is the name of your State or Province?
  [Unknown]:  CA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=localhost, OU=IT, O=Secure Org, L=San Francisco, ST=CA, C=US correct?
  [no]:  yes

Refer to http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html for more info.

16.10. Configure SSL Connector

  • Add (uncomment) in ${jboss.server.home.dir}/deploy/jbossweb.sar/server.xml file:

    <Connector protocol="HTTP/1.1" SSLEnabled="true"
           port="8443" address="${jboss.bind.address}"
           scheme="https" secure="true" clientAuth="false"
           keystorePass="rmi+ssl" sslProtocol = "TLS" />

If you change the port to 443 (or any other port number), make sure that you also set redirectPort="443" in both the non-SSL HTTP and AJP connector elements.

See http://tomcat.apache.org/tomcat-6.0-doc/config/http.html for additional <Connector> options.

16.11. Testing SSL Configuration

When starting up JBoss AS, the console should print the following lines:

14:41:01,002 INFO  [Http11Protocol] Initializing Coyote HTTP/1.1 on http-
14:41:02,195 INFO  [Http11Protocol] Initializing Coyote HTTP/1.1 on http-

When you point your browser to http://localhost:8443/status you will get a browser warning telling you that the SSL certificate has not been signed by a certification authority that you trust. This is expected, since we signed our own certificate. Skipping the warning should show the SSL-protected page (pad-lock).

16.12. Requiring SSL in Apps

  • Add within a <security-constraint> element (in WEB-INF/web.xml file):

      <description>Require SSL</description>
  • Upon making a request over a non-SSL connection, the browser is automatically redirected to the redirectPort as defined in the <Connector> element

The element <transport-guarantee> can be NONE, INTEGRAL, or CONFIDENTIAL. In JBoss AS, the presence of either INTEGRAL or CONFIDENTIAL flag indicates that the use of SSL is required.

16.13. Lab: Application Security

  • Filter out clients coming from remote interfaces on

    • One of the virtual hosts
    • One of the deployed applications
  • Protect an application with A&A

    • Plain text
    • Database
    • Secure Passwords
  • Add support for SSL

    • Require SSL in one or more of the applications

To filter clients by their source IP see Section 16.2, “Filtering Clients by Source”

  • For a virtual host, add <Valve> to <Host> in Tomcat’s server.xml
  • For a web application, add <Valve> to <Context> in application’s WEB-INF/context.xml file

To implement authentication and authorization (Section 16.3, “Authentication & Authorization”):

To add support for SSL (Section 16.8, “Configuring JBoss AS for SSL”):

16.14. Securing JMS destinations

  • By default in JBoss, every message sent can be accessed by all consumers connected to the destination.
  • To restrict this, we must plug JBM users into JBossSX.

JBM_USER and JBM_ROLE tables have been created by the JMSUserManager component when we have set up the persistence to use MySQL.

First, declare a new security domain in the conf/login-config.xml file in your server configuration set folder:

  <application-policy name="JMSRealm">
      <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
         <module-option name="dsJndiName">java:/MySqlDS</module-option>

                 <module-option name="principalsQuery">
                   SELECT passwd FROM jbm_user WHERE user_id=?

                 <module-option name="rolesQuery">
                   SELECT role_id, 'Roles' FROM jbm_role WHERE user_id=?

Then, add the security domain you just created to the configuration of JBM security store that you can find in the deploy/messaging/messaging-jboss-beans.xml:

<bean name="SecurityStore" class="org.jboss.jms.server.jbosssx.JBossASSecurityMetadataStore">
  <property name="securityDomain">JMSRealm</property> <!-- 1 -->


This is where you need to specify which security domain to use

Create now a secured Topic:

<mbean code="org.jboss.jms.server.destination.TopicService"
  <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>

  <!-- 1 -->
  <attribute name="SecurityConfig">
          <role name="publisher" read="true" write="true"/>


This is where you say that you want your consumers to have the publisher role. The read property allows the consumer to read messages from the destination. The write property allows the consumer to send messages to the destination.

The publisher role has been automatically added by the persistence service at table creation. One user that has the publisher role is also created (user_id: dynsub , passwd: dynsub)

Finally, If a developer want to use the secured connection for this Topic:

connection = cf.createConnection("dynsub","dynsub");

16.15. Securing JBoss AS

  • Running JBoss AS with low privileges
  • File system security
  • Securing console applications/tools

    • Restricting remote shutdown
    • Protecting twiddle tool
  • Securing other JBoss AS services
  • Running with Java Security Manager
  • Running behind a firewall

We will examine each of these in turn.

16.16. JBoss AS System User

  • Do not run JBoss AS as root / Administrator

    • Deployed applications and services run with the same privileges as the JBoss AS itself
    • Create a low-privileged JBoss system user
  • JBoss, being a Java app, cannot switch its effective user id after starting

    • Running without root privileges forces you to use ports >=1024 (default) on a Unix/Linux system
    • Front JBoss AS with a web server (like Apache HTTPD) or setup firewall-based port forwarding for access over default HTTP(S) ports: 80, 443

Creating low-privileged users for system services is a common practice on Unix/Linux environments. On Windows, JBoss AS would typically be configured to run with a default System account. Also, Windows does not have a concept of privileged ports like Unix/Linux systems.

16.17. File System Security

  • JBoss user must have at least read access to all files and directories under ${jboss.home_url}
  • JBoss user must have write access to data/, log/, tmp/, and work/ directories under ${jboss.server.home.url} (under default configuration set)
  • Depending on the deployed apps' requirements, JBoss user may need write access to parts of ${jboss.server.home.url}/deploy dir

Other users should in particular have no access to ${jboss.server.config.url} and ${jboss.server.home.url}/deploy directories as these often contain sensitive information like database or SSL-certificate passwords.

Although supported by NTFS, file system security is often not employed to secure system services like JBoss AS under Windows.

16.18. Securing JMX Invoker

  • Used by the twiddle tool and the remote shutdown - by default unsecured
  • Simples solution is to remove it

    • No remote shutdown (send TERM signal)
    • No programmatic remote management
  • Secure it by adding an authentication interceptor to the Invoker MBean

    • Just needs to be uncommented

In deploy/jmx-invoker-adaptor-server.sar/META-INF/jboss-service.xml (JBoss 3.2.x) or deploy/jmx-invoker-service.xml (JBoss 4.x and JBoss 5.x) under ${jboss.server.home.url}, uncomment the following:

<!-- Uncomment to require authenticated users
    <interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securityDomain="java:/jaas/jmx-console"/>

By default, the security domain java:/jaas/jmx-console authenticates against file default/conf/props/jmx-console-users.properties This file is in <user>=<password> format. Roles are not important.

To specify the username and password for twiddle or shutdown scripts, use -u <user> -p <password> command-line switches.

16.19. Securing JBoss Applications

  • Both jmx-console and web-console are standard web applications

    • Remove if not needed?
    • Filter by IP
    • Use declarative security to require A&A
    • Require SSL
  • Declarative security already present, just needs to be uncommented

Requiring authentication and authorization for jmx-console:

  • Uncomment <security-constraint> in web.xml and <security-domain> in jboss-web.xml under ${jboss.server.home.url}/deploy/jmx-console.war/WEB-INF/
  • Set or change the admin password in ${jboss.server.config.url}/props/jmx-console-users.properties

Requiring authentication and authorization for web-console:

  • Uncomment <security-constraint> in web.xml and <security-domain> in jboss-web.xml under

    • ${jboss.server.home.url}/deploy/management/web-console.war/WEB-INF (JBoss version<4.0.2) OR
    • ${jboss.server.home.url}/deploy/management/console-mgr.sar/web-console.war/WEB-INF/ (JBoss version>=4.0.2)
  • Update ${jboss.server.config.url}/login-config.xml such that <application-policy name="web-console"> loads usersProperties from props/web-console-users.properties and rolesProperties from props/web-console-roles.properties
  • Add a user that belong to JBossAdmin role in the two properties files

Restart JBoss for the changes to take effect.

16.20. Securing Hypersonic DB

  • Remove it

    • Undeploy ${jboss.server.home.url}/deploy/hsqldb-ds.xml
    • Provide DefaultDS for services that depend on it (like JMS MQ)
  • Keep it but disable remote access to it

    • Disable jboss:service=Hypersonic Mbean in hsqldb-ds.xml

To disable remote access to Hypersonic DB:

  • Edit ${jboss.server.home.url}/deploy/hsqldb-ds.xml
  • Comment out <mbean name="jboss:service=Hypersonic">
  • Change <connection-url> in <local-tx-datasource> from localhost:1701 to a local resource like jdbc:hsqldb:${jboss.server.data.dir}/hypersonic/localDB
  • Comment out the <depends> element in <local-tx-datasource> referring to jboss:service=Hypersonic

16.21. Java Security Manager

  • Run JBoss AS in a secure sand box controlled by a security policy (file)
  • Control access to resources such as JVM, system settings, file system, and network communication (inbound and outbound)
  • Secure as long as all code is pure Java
  • Disabled by default
  • Hard to configure
  • Slight runtime overhead

To enable, edit $JBOSS_HOME/bin/run.conf and add to JAVA_OPTS: * -Djava.security.manager and * -Djava.security.policy=<policy-file>

Enabling the security manager is easy. The hard part is to come up with a suitable security policy. To enable all permissions, start with security.policy:

grant {
  permission java.security.AllPermission;

To figure out which permissions you need, you can debug the security manager. Run java -Djava.security.debug=help to see a list of debugging options. Using -Djava.security.debug=all in JAVA_OPTS is the most verbose (probably too verbose), whereas setting java.security.debug to access,failure may be sufficient to determine a suitable security policy.

16.22. Running Behind a Firewall

  • Decide which services need to be visible from the outside world

    • HTTP, HTTPS (unless running behind a web server such as Apache HTTPD)
    • Naming Service: RMI, Registry?
    • SNMP?
    • JRMP Invoker?
  • Protect all other services

    • JMS MQ
    • HA and clustering services in all configuration

Listening ports in default configuration:

  • 1098 TCP NamingService RMI
  • 1099 TCP Naming Service Registry
  • 4444 TCP JRMP Invoker RMI
  • 4445 TCP Pooled Invoker Server
  • 8009 TCP Tomcat AJP
  • 8080 TCP Tomcat HTTP
  • 8083 TCP Web Service
  • 8093 TCP JMS MQ UIL Server

Additional listening ports in all configuration:

  • 1100 TCP HA Naming Service
  • 1101 TCP HA Naming Service RMI
  • 1102 UDP HA Naming Service AutoDiscovery
  • 1161 UDP Snmp Agent Service
  • 1162 UDP Trapd Service
  • 3528 TCP IIOP Invoker
  • 4447 TCP JRMPInvoker HA
  • 45566 UDP Cluster Partition

16.23. Lab: JBoss Security

  • Secure JMX Invoker

    • Test Twiddle and Shutdown
  • Secure JMX Console

    • Require A&A
    • Require SSL
  • Secure Web Console

    • Require local access only