Security

Hawtio enables authentication out of the box in three supported runtimes/environments:

Because the authentication mechanisms may vary between these environments (for example there’s no JAAS support in Hawtio Quarkus) there may be a need to provide some configuration. User may also disable the authentication entirely.

Generic configuration properties

The following table lists the Security-related configuration properties for the Hawtio core system. These are not specific to any selected deployment method, but may have some special flavors in a given environment (like Keycloak configuration).

Table 1. Security-related configuration properties
Name Default Description

hawtio.auth
hawtio.authenticationEnabled

true

This option may be used to disable authentication if needed.

hawtio.authenticationThrottled

true

Whether to throttle authentication attempts to protect Hawtio from brute force attacks.

hawtio.noCredentials401

false

Whether to return HTTP status 401 when authentication is enabled, but no credentials have been provided. Returning 401 will cause the browser popup window to prompt for credentials. By default this option is false, returning HTTP status 403 instead (and browser will not show the credentials popup window).

hawtio.realm

hawtio

The security realm used for the authentication. This is the value sent with WWW-Authenticate: Basic realm="<realm>" response header, but also it is used as JAAS application configuration entry when JAAS authentication is performed.

hawtio.roles
hawtio.role (deprecated)

admin,manager,viewer

The user roles expected for the user being authenticated. Multiple roles can be separated by a comma. Set to * or an empty value to disable role checking. Hawtio doesn’t apply these roles to specific operations (or JMX MBeans / attributes / methods) - however these roles may be used by specific environment to implement full Role-Based Access Control (RBAC).

hawtio.userPrincipalClasses

A list partially detected from configured JAAS login modules, including io.hawt.web.auth.UserPrincipal.

Fully qualified class name(s) implementing java.security.Principal interface separated by comma. These classes will be known to Hawtio and recognized as user identity principals of an authenticated JAAS subject.

hawtio.rolePrincipalClasses

A list partially detected from configured JAAS login modules, including io.hawt.web.auth.RolePrincipal.

Fully qualified class name(s) implementing java.security.Principal interface separated by comma. These classes will be known to Hawtio and recognized as role principals of an authenticated JAAS subject.

hawtio.keycloakEnabled

false

Whether to enable or disable Keycloak integration. This is a native Keycloak integration which depends on Keycloak libraries availability and additional configuration. See more details in the Keycloak Integration chapter.
Keycloak Identity Provider can also be used with Generic OIDC support (see OpenID Connect Integration).

hawtio.keycloakClientConfig

classpath:keycloak.json

Keycloak configuration file used for the frontend. Can be specified as classpath: or file: URL or as a file location. It is mandatory if Keycloak integration is enabled. See more details in the Keycloak Integration chapter.

hawtio.oidcConfig

classpath:hawtio-oidc.properties or a location specific to a target container (like Tomcat or Artemis).

A location of OpenID Connection configuration file. This file can be used to configure generic OpenID Connect authentication using external Identity Provider like Keycloak without any additional libraries. Can be specified as classpath: or file: URL or as a file location. See more details in the OpenID Connect Integration chapter.

hawtio.authenticationContainerDiscoveryClasses

io.hawt.web.tomcat.TomcatAuthenticationContainerDiscovery

List of used io.hawt.web.auth.AuthenticationContainerDiscovery implementations separated by comma. By default only the built-in TomcatAuthenticationContainerDiscovery is used. Tomcat integration allows Hawtio to authenticate users declared in Tomcat’s tomcat-users.xml file. This built-in service may be disabled by specifying other (or none at all) discovery classes.

hawtio.tomcatUserFileLocation

conf/tomcat-users.xml

Specify an alternative location for the tomcat-users.xml file.

hawtio.authenticationContainerTomcatDigestAlgorithm

NONE

When using the Tomcat tomcat-users.xml file, passwords can be specified in hashed form. Use this to specify the digest algorithm; valid values are all algorithms accepted by java.security.MessageDigest.getInstance(algorithm). See more details in Tomcat Documentation.

RBAC Restrictor

For some runtimes that support Hawtio RBAC (role-based access control) [1], Hawtio provides a custom Jolokia restrictor implementation that provides an additional layer of protection over JMX operations based on the ACL (access control list) policy.

You cannot use Hawtio RBAC with Quarkus and Spring Boot yet. Enabling the RBAC restrictor on those runtimes only imposes additional load without any gains.

To activate the Hawtio RBAC restrictor, configure the Jolokia parameter restrictorClass via System property to use io.hawt.web.RBACRestrictor as follows:

jolokia.restrictorClass = io.hawt.system.RBACRestrictor

Production-ready configuration

When deploying Hawtio in a production environment, it is essential to implement proper security measures to protect against common web vulnerabilities. This section covers critical security configurations for protection from common security attacks.

There are two distinct, but related security aspects that need to be addressed:

  • the traditional client-server access protection, where the server authenticates and authorized the incoming request

  • the more sophisticated protection against request that look legitimate at the server side, but are issued without awareness of the client

The authentication and authorization (sometimes referred to as authn/authz) is generally enabled by Hawtio using hawtio.authenticationEnabled option and the details are configured in the deployment environment.
Spring Boot, Quarkus and WAR deployments have their own configuration (described further down below) and JAAS provides the security architecture used by Hawtio (Hawtio has dedicated support in Quarkus where JAAS is not used).

The more important and usually complex aspect is protection against CSRF so a session of an authenticated user can not be stolen by another site which attempts to perform hidden requests to Jolokia.

CSRF (Cross-Site Request Forgery) attacks can trick authenticated users into executing unwanted actions. Hawtio uses Jolokia for JMX operations, and proper CORS configuration is critical for CSRF protection.

Jolokia documentation explains this security aspect in more details. For quick summary here’s a short summary:

  • user is properly authenticated and authorized at http://example.com/hawtio page which usually (but not necessarily) involves a cookie being stored by the browser and associated with this site.

  • user is tricked into navigating to a malicious page from different domain (an origin when using web terms) which uses JavaScript and fetch() API (or hidden links or forms) to access Jolokia endpoint at http://example.com/hawtio

  • while there are many protection methods (like SameSite cookies) there are situation where the browser may attach the session cookie bound to http://example.com/hawtio to requests sent by the malicious page.
    Here’s where CORS comes into play.

CORS and other protection mechanism may be configured using Jolokia policy. Hawtio provides additional configuration. The following sections provide more details.

Securing Jolokia with Jolokia policy configuration

By default, Jolokia loads the jolokia-access.xml file located at the root of the application classpath. In Spring Boot or Quarkus applications, place jolokia-access.xml in the project’s src/main/resources directory to apply the policies.

Examples:

If you want to load jolokia-access.xml from a location other than the default one, such as an external file, define the jolokia.policyLocation system property:

jolokia.policyLocation = file:///path/to/jolokia-access.xml

Securing Jolokia CORS configuration

The most important configuration in a production environment is to set up Jolokia’s CORS restrictions.
By default, Hawtio examples configure Jolokia accept cross-origin access from local host. Hawtio WAR distribution can’t include a list of allowed origins, because it depends on the name and IP address of the host where Hawtio is deployed.

CORS may be confusing at first glance, because we have to be aware that this mechanism is not protecting the server. It’s about preventing the client (web application) from reading the response if the origin from which the request was sent is not allowed. The response is still delivered to the client but JavaScript code (or even web developer tools) can’t read it.

This is why Jolokia extends the term "CORS" to provide the missing protection - the request may actually be rejected with HTTP 403 if the Origin is not trusted.

Jolokia checks Origin HTTP header to perform the check. When using curl or other non-browser HTTP client, we can send any value for this header, but there’s no way to forge this header in JavaScript code running inside a browser, as this is a forbidden HTTP header.

Jolokia CORS configuration in a Policy file

Create or update the jolokia-access.xml file to restrict access to trusted origins only. This file should include strict CORS settings, which include:

  • a list of Origin header patterns for which Jolokia will return Access-Control-Allow-Origin header, allowing the client (which is the Hawtio web application) to read the response

  • strict-checking element present which tells Jolokia to use extended CORS - by rejecting requests from disallowed origins with HTTP 403 without processing the request

<restrict>
  ...
  <cors>
    <!-- Allow access only from trusted origins -->
    <!--
      List of Origin headers for which Jolokia will respond with Access-Control-Allow-Origin when handling
      CORS preflight requests and resource access requests.
    -->
    <allow-origin>http*://localhost:*</allow-origin>
    <allow-origin>http*://127.0.0.1:*</allow-origin>
    <allow-origin>https://*.your-site.com</allow-origin>

    <!-- Enable strict checking to enforce the proper origin check -->
    <!--
      With strict-checking the <allow-origin> values are used not only for CORS protocol (preflight requests),
      but also for rejecting requests entirely based on Origin (and here - also Referer) header.
    -->
    <strict-checking />
  </cors>
</restrict>
The <strict-checking /> setting is critical here. Without it, malicious requests to invoke MBean operations may still be executed even with origin restrictions in place. The attacker won’t see the response, but the request may lead to server-side actions being performed.
Advice for the production environment
  • Never use wildcard (*) for allow-origin in production environments

  • Specify exact protocols (http or https) and ports when possible

  • Use HTTPS-only origins for confidentiality and integrity

  • Regularly review and update the list of allowed origins

For details on <cors> element settings and explanation of CSRF, refer to the official Jolokia documentation.

Restricting access by IP addresses

jolokia-access.xml file may also be used to restrict access to Jolokia endpoint by providing an allow list if IP addresses and IP address ranges. This may be used to protect against accessing Jolokia from unknown hosts and networks whether or not the access is attempted from a web application or clients like curl.

Here’s an example showing IP4 and IP6 address and range restrictions:

<restrict>
  ...
  <remote>
    <host>127.0.0.1</host>
    <host>localhost</host>
    <host>[::1]</host>

    <host>192.168.0.0/16</host>
    <!-- IP6 addresses can be specified with or without brackets -->
    <host>[2001:db8::1]</host>
    <!-- IP6 "subnets" are properly handled by Jolokia (no brackets) -->
    <host>2001:db8::/32</host>
  </remote>
  ...
</restrict>

The allowed hosts are also checked for UDP Multicast discovery, so include proper addresses or ranges for this Jolokia feature as well.

RFC 3849 defines 2001:DB8::/32 IP6 addresses as reserved for examples and documentation.

Restricting HTTP methods

Jolokia provides support for HTTP GET requests, so it’s possible to quickly invoked it with curl:

$ curl -s -H'Origin: http://localhost:8080' http://localhost:8080/jolokia/read/java.lang:type=Memory/HeapMemoryUsage | jq .
{
  "request": {
    "mbean": "java.lang:type=Memory",
    "attribute": "HeapMemoryUsage",
    "type": "read"
  },
  "value": {
    "init": 536870912,
    "committed": 536870912,
    "max": 2147483648,
    "used": 195662408
  },
  "status": 200
}

Hawtio always uses POST requests only to access local or remote Jolokia agents, so it is recommended to reject (with HTTP 405 code) all other methods. It can be done in this fragment of jolokia-access.xml:

<restrict>
  ...
  <http>
    <method>post</method>
  </http>
  ...
</restrict>

It is still possible to use POST requests with curl:

$ curl -s -H'Origin: http://localhost:8080' -H'Content-Type: application/json' \
    -d '{"type":"read","mbean":"java.lang:type=Memory","attribute":"HeapMemoryUsage"}' \
    http://localhost:8080/jolokia

But it prevents from calling Jolokia without HTTP content (using URL only).

Forbidding access to certain MBans

JMX technology was designed from administration and monitoring point of view. This means that any application can register any MBean which exposes any information - including sensitive information.

When some MBeans should not be visible to Hawtio (through Jolokia), Jolokia may deny access to some MBeans (or some of their attributes) using a dedicated fragment of jolokia-access.xml. Here’s an example:

<restrict>
  ...
  <deny>
    <mbean>
      <!-- Exposes user/password of data source, so we forbid this one -->
      <name>com.mchange.v2.c3p0:type=PooledDataSource,*</name>
      <attribute>properties</attribute>
    </mbean>
    ...
  </deny>
  ...
</restrict>

Reviewing Proxy Servlet settings

When launched from the CLI, Hawtio features a "Connect" function that connects to remote Jolokia endpoints. This functionality is implemented via a proxy servlet running on Hawtio’s JVM runtime.

For security reasons, the proxy servlet only permits connections to local Jolokia endpoints by default. If you want to connect to a remote endpoint, you must explicitly specify the hostname to be allowed via the hawtio.proxyAllowlist system property.

If you are using Spring Boot or Quarkus to integrate the Hawtio console directly into your application, the proxy servlet is disabled by default via the hawtio-springboot or hawtio-quarkus components. If you have explicitly enabled the proxy servlet (hawtio.disableProxy = false), you must also review the configuration described here.

Proxy allowlist

When you need to connect to remote Jolokia endpoints, configure the allowlist via the hawtio.proxyAllowlist system property. This prevents malicious scripts from being injected through unauthorized remote connections (Cross-Site Scripting, XSS).

For example, to allow connections to specific servers:

hawtio.proxyAllowlist = myserver1, myserver2, myserver3

You can also use regular expressions for more flexible allowlist patterns by prefixing them with r::

hawtio.proxyAllowlist = r:.+[.]example[.]com, r:192[.]168[.]1[.].+
Always use the most restrictive allowlist possible. Only include hosts that absolutely need to be accessed remotely.

Disabling proxy

If you are absolutely certain that you will not be using the Connect feature for remote connections, the safest option is to disable the proxy servlet.

If you are using the Hawtio console with Spring Boot or Quarkus applications, the proxy servlet is already disabled by default.
hawtio.disableProxy = true

Built-in protection of Hawtio Proxy Servlet

Hawtio ProxyServlet was designed to allow cross-origin communication with remote Jolokia agents.

With existing CORS support, remote Jolokia agents actually can be used from Hawtio web application, but the remote connection support in Hawtio is handled through ProxyServlet.
Jolokia running in Hawtio may be used by other web applications (other Hawtio instances and non-Hawtio applications) as a remote Jolokia Agent though.

Hawtio ProxyServlet should never be accessed in a cross-origin fashion and should never be used to access non-Jolokia HTTP servers. To this end the following protection is active and can’t be disabled:

  • only POST requests are handled

  • only requests with Content-Type: application/json are handled

  • only the hosts specified in the allow list (see above) can be reached

Production security best practices

Beyond CSRF and XSS protection, consider implementing these security measures:

Use HTTPS/TLS

Always encrypt data in transit in production environments

Enable authentication

Never disable authentication (hawtio.authenticationEnabled = false) in production

Implement RBAC

For platforms where Hawtio supports RBAC, configure RBAC for fine-grained access control

Regular updates

Keep Hawtio and its dependencies up to date to patch security vulnerabilities

Quarkus

Hawtio can be secured with the authentication mechanisms Quarkus provides, as well as Keycloak.

if you want to disable Hawtio authentication for Quarkus, add the following configuration to application.properties:

application.properties
quarkus.hawtio.authenticationEnabled = false
Authentication in Hawtio deployed with Quarkus does not use JAAS and relies only on injected io.quarkus.security.identity.IdentityProviderManager interface.

Quarkus authentication mechanisms

Hawtio is just a Web application in terms of Quarkus, so the various mechanisms Quarkus provides can be used to authenticate Hawtio in the same way it authenticates a Web application.

Here we show how you can use the properties-based authentication with Hawtio for demonstrating purposes.

The properties-based authentication is not recommended to use in production. This mechanism is for development and testing purposes only.

To use the properties-based authentication with Hawtio, add the following dependency to pom.xml:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-elytron-security-properties-file</artifactId>
</dependency>

You can then define users to application.properties to enable the authentication. For example, defining a user hawtio with password s3cr3t! and role admin would look like the following:

application.properties
quarkus.security.users.embedded.enabled = true
quarkus.security.users.embedded.plain-text = true
quarkus.security.users.embedded.users.hawtio = s3cr3t!
quarkus.security.users.embedded.roles.hawtio = admin

Example

See quarkus example for a working example of the properties-based authentication.

Quarkus with Keycloak

See Keycloak Integration - Quarkus chapter which uses Quarkus OIDC support at server side and Keycloak specific JavaScript library to handle OpenID Connect authentication in the browser.

Spring Boot

While Hawtio on Quarkus completely replaces JAAS with Quarkus specific authentication mechanisms, Spring Boot and Spring Security integrates with JAAS, so Hawtio can use common mechanism to authenticate users with or without Spring Security using JAAS.

The integration is provided by a special JAAS SecurityContextLoginModule, which effectively translates Spring Security org.springframework.security.core.Authentication object into a JAAS javax.security.auth.Subject with associated list of javax.security.auth.Principals.
This integration is automatically configured by Hawtio when Spring Security configuration is detected.

if you want to disable Hawtio authentication for Spring Boot, add the following configuration to application.properties:

application.properties
hawtio.authenticationEnabled = false

Spring Security

To use Spring Security with Hawtio, add org.springframework.boot:spring-boot-starter-security to the dependencies in pom.xml:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security configuration in src/main/resources/application.properties should look something like the following:

spring.security.user.name = hawtio
spring.security.user.password = s3cr3t!
spring.security.user.roles = admin,viewer

A security config class has to be defined to set up how to secure the application with Spring Security:

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic()
            .and()
            .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
        return http.build();
    }
}

Example

See springboot-security example for a working example.

Connecting to a remote application with Spring Security

If you try to connect to a remote Spring Boot application with Spring Security enabled, make sure the Spring Security configuration allows access from the Hawtio console. Most likely, the default CSRF protection prohibits remote access to the Jolokia endpoint and thus causes authentication failures at the Hawtio console.

The easiest solution is to disable CSRF protection for the Jolokia endpoint at the remote application as follows.

Be aware that it will expose your application at risk of CSRF attacks.
import org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpoint;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        ...
        // Disable CSRF protection for the Jolokia endpoint
        http.csrf().ignoringRequestMatchers(EndpointRequest.to(JolokiaEndpoint.class));
        return http.build();
    }

}

To secure the Jolokia endpoint even without Spring Security’s CSRF protection, configure jolokia-access.xml with strict CORS settings. See Securing Jolokia CORS configuration for details.

Spring Boot with Keycloak

See Keycloak Integration - Spring Boot chapter which uses Spring Security OAuth2 support at server side and Keycloak specific JavaScript library to handle OpenID Connect authentication in the browser.

JakartaEE Web Containers

Hawtio can be deployed to any Servlet API compliant container. The deployment artifact is a Web Archive (WAR). Most of the configuration is already provided in Hawtio’s WEB-INF/war.xml, but this configuration may be changed with Generic configuration properties.

Hawtio authentication is enabled by default. If you want to disable Hawtio authentication, set the following system property:

hawtio.authenticationEnabled = false

The following sections show container specific configuration options. These options are not specified in Servlet API.

While the standard Servlet API authentication relies on configuring web.xml elements like <login-config>, Hawtio does not use this declarative security configuration. Hawtio uses custom io.hawt.web.auth.AuthenticationFilter which can be configured using system properties.

Jetty

Hawtio can integrate with Jetty JAAS mechanisms. However not all Jetty JAAS modules work out of the box.

Jetty JAAS modules work with Jetty security infrastructure and the important thing is that it requires your web application (WAR) to use <login-config> configuration.

Hawtio provides customized org.eclipse.jetty.security.jaas.spi.PropertyFileLoginModule which is available in io.hawt.jetty.security.jaas.PropertyFileLoginModule class that lifts the restriction of having a <login-config> configuration. Additionally Hawtio provides ready to use *.mod file which can be copied directly to $JETTY_BASE/modules. This file describes Jetty module with references to required Hawtio Jetty library:

[description]
Hawtio JAAS Login Module Configuration for Jetty

[tags]
security
hawtio

[depends]
jaas

[files]
maven://io.hawt/hawtio-jetty-security/<version>|lib/hawtio-jetty-security-<version>.jar

[lib]
lib/hawtio-jetty-security-<version>.jar

After adding $JETTY_BASE/modules/hawtio-jetty-security.mod file we can add this module (and jaas module) using:

$ cd $JETTY_BASE
$ java -jar $JETTY_HOME/start.jar --add-module=jaas,hawtio-jetty-security
INFO  : jaas            initialized in ${jetty.base}/start.d/jaas.ini
INFO  : hawtio-jetty-security initialized in ${jetty.base}/start.d/hawtio-jetty-security.ini
INFO  : copy ~/.m2/repository/io/hawt/hawtio-jetty-security/4.6.1/hawtio-jetty-security-<version>.jar to ${jetty.base}/lib/hawtio-jetty-security-<version>.jar
INFO  : Base directory was modified

To use authentication with Jetty, you first have to set up some users with credentials and roles. To do that navigate to $JETTY_BASE/etc/ folder and create etc/login.properties file containing something like this:

etc/login.properties
scott=tiger,user
admin=CRYPT:adpexzg3FUZAk,admin,user

You have added two users. The first one named scott with the password tiger. He has the role user assigned to it. The second user admin with password admin which is obfuscated (see Password Obfuscation in Jetty documentation for details). This one has the admin and user role assigned.

Now create the second file in the same $JETTY_BASE/etc/ directory named login.conf. This is the JAAS login configuration file.

etc/login.conf
hawtio {
  io.hawt.jetty.security.jaas.PropertyFileLoginModule required
  debug="true"
  file="${jetty.base}/etc/login.properties";
};

At last, you have to change the Hawtio configuration:

Table 2. Configuration properties for Jetty authentication
Property Value

hawtio.authenticationEnabled

true

hawtio.realm

hawtio

hawtio.roles

admin

hawtio.userPrincipalClasses

org.eclipse.jetty.security.UserPrincipal

hawtio.rolePrincipalClasses

org.eclipse.jetty.security.jaas.JAASRole

When Jetty jvm module is installed, we can specify Hawtio properties in $JETTY_BASE/start.d/jvm.ini:

--exec
-Dhawtio.authenticationEnabled=true
-Dhawtio.realm=hawtio
-Dhawtio.roles=admin
-Dhawtio.userPrincipalClasses=org.eclipse.jetty.security.UserPrincipal
-Dhawtio.rolePrincipalClasses=org.eclipse.jetty.security.jaas.JAASRole

Without jvm module the above options should be specified as system properties when running java -jar $JETTY_HOME/start.jar.

You have now enabled authentication for Hawtio. Only users with role admin are allowed to log in.

Apache Tomcat

Hawtio configuration properties can be passed to Tomcat using CATALINA_OPTS environment variable. This variable should contain system properties recognized by Hawtio.

By default, Hawtio authentication is enabled. You can disable authentication in Tomcat by adding this to bin/setenv.sh:

CATALINA_OPTS="$CATALINA_OPTS -Dhawtio.authenticationEnabled=false"

Hawtio will auto-detect that it is running in Tomcat. It will add dynamic JAAS login module that will be used to authenticate users declared in Tomcat’s conf/tomcat-users.xml file. All configuration options related to this file are supported by Hawtio. Additionally, when the file is modified, Hawtio will reload the user database.

The simplest content of conf/tomcat-users.xml may be:

<?xml version="1.0"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml" version="1.0">
  <user username="scott" password="tiger" roles="tomcat"/>
</tomcat-users>

The above definition includes single scott user with tiger password assigned with tomcat role.

However Hawtio also supports encoded/hashed password (see more details in Tomcat documentation on CredentialHandler). Tomcat itself may be configured like this:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  ...
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    ...
    <Engine name="Catalina" defaultHost="localhost">
      ...
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase">
          <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler" algorithm="SHA-384" />
        </Realm>
      </Realm>
      ...
    </Engine>
  </Service>
</Server>

This tells Tomcat that the passwords are hashed using SHA-384 message digest algorithm. With such configuration, conf/tomcat-users.xml may look like this:

<?xml version="1.0"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml" version="1.0">
  <user username="hawtio" password="<salt>$<iteration count>$<digest>" roles="admin,manager,..."/>
</tomcat-users>

Hawtio supports all password formats specified in the MessageDigestCredentialHandler documentation.

If you only want users of a special role to be able to login Hawtio, you can set the role name in the CATALINA_OPTS environment variable as shown:

CATALINA_OPTS="$CATALINA_OPTS -Dhawtio.roles=Administrator,Operator"

Now the user must be in the Administrator or Operator role to be able to login, which we can set up in the conf/tomcat-users.xml file:

<role rolename="manager"/>
<user username="scott" password="tiger" roles="Administrator"/>

Using different JAAS login modules

When deploying Hawtio in an environment where JAAS authentication is used, we can configure additional JAAS login modules that will participate in authentication process.

Knowledge of Java Authentication and Authorization Service is required to properly configure JAAS, as there are important aspects to be aware of when configuring multiple login modules.

Hawtio configures its own login modules (for example io.hawt.web.tomcat.TomcatUsersLoginModule) dynamically, but there’s also a JDK standard way of telling JAAS about the definition of login modules for named JAAS applications.
We can use the below option to point Hawtio (and JDK itself) to standard JAAS configuration file:

-Djava.security.auth.login.config=/path/to/login.config

This file is structured as documented in JDK like this:

<name used by application to refer to this entry> {
    <LoginModule> <flag> <LoginModule options>;
    <optional additional LoginModules, flags and options>;
};
<additional applications>

Here’s where the concept of Hawtio realm is important. The default realm (when not specified) used by Hawtio is hawtio, but it may be changed using:

-Dhawtio.realm=myrealm

This realm is directly used by JAAS to find a set of login modules and is interpreted as name used by application to refer to this entry.

For example we can have this login.config file (selected using -Djava.security.auth.login.config property):

myrealm {
    com.sun.security.auth.module.LdapLoginModule REQUIRED
    userProvider="ldap://localhost:389"
    authIdentity="uid={USERNAME},ou=users,dc=example,dc=com"
    useSSL=false
    debug=true;
};

Since Hawtio 4.6 we can have multiple login modules declared for hawtio realm (or any other realm defined with -Dhawtio.realm) in JAAS configuration file. Additionally Hawtio will dynamically add detected login modules to this list (for example by default when running in Tomcat, io.hawt.web.tomcat.TomcatUsersLoginModule will be added without explicitly declaring it in login.config file).

With pluggable nature of JAAS, it is possible for one Login Module to perform actual authentication (for example by looking up the user in LDAP server) and other modules to perform role/group lookup and mapping.

Multiple Login methods

This is a new feature introduced in Hawtio 4.6

When authentication is enabled, Hawtio console application (in the browser) detects configured authentication methods. There are two categories of authentication variants:

  • authentication using username and password credentials

  • authentication using a token issued by Identity Provider (like Keycloak).

When Hawtio is configured with multiple login modules of different categories, new login screen is presented to the user. For example:

multi login

When there’s only one authentication method that accepts username and password, standard login screen is shown.

When there’s only the OIDC/Keycloak authentication method, user is no longer automatically redirected to Identity Provider’s authentication screen, but instead this button is shown:

multi login oidc

Keycloak Integration

Hawtio can be integrated with Keycloak for SSO authentication. See Keycloak Integration. This method uses Keycloak specific libraries and configuration files.

Starting with Keycloak 25.0.0, Keycloak specific login modules are no longer available. Keycloak can be used with Hawtio using OpenID Connect Integration.

OpenID Connect Integration

For generic OIDC authentication see OpenID Connect Integration. This is also a recommended approach to integrate Hawtio with Keycloak.


1. Apache Karaf and Apache ActiveMQ Artemis provide Hawtio RBAC support.