OTP Integration with JBoss Application Server

WARNING:  This is an article in progress.  Do not attempt in production.

Acknowledgements

This feature is Bill Burke's idea.  All glory to him.

 


Steps to Follow:

  1. Assume you have a JBoss Application Server v5 and beyond.
  2. Pick the two jars from PicketBox release (after 3.0.0.CR2)  (  jboss-security-spi.jar  [https://repository.jboss.org/nexus/content/groups/public-jboss/org/picketbox/jboss-security-spi/]   and jbosssx.jar [ https://repository.jboss.org/nexus/content/groups/public-jboss/org/picketbox/jbosssx/ ]
  3. Rename the jboss-security-spi.jar and jbosssx.jar in JBAS5+ to *.bak  (Just add a .bak prefix)
  4. Move the two downloaded jars from step 2 into where these .bak files are.
  5. Follow the Web Application Authentication Set up below.
  6. Follow the TOTP mobile app Set up below.
  7. Try logging in to your web application at http://localhost:8080/webapp  (Eg:  http://localhost:8080/jmx-console/)
  8. Now enter both your password and your TOTP token (generated by the mobile app) in the respective boxes.
  9. You should be logged in.

 

Web Application Set up

You will need FORM based authentication.  (Strongly recommend using https)

 

I am going to take the example of jmx-console.war

 

The web.xml will look as follows:

 

<?xml version="1.0"?>
<web-app version="2.5"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   
   <description>The standard web descriptor for the html adaptor</description>
   <!--
    <filter>
      <filter-name>JmxOpsAccessControlFilter</filter-name>
      <filter-class>org.jboss.jmx.adaptor.html.JMXOpsAccessControlFilter</filter-class>
      <init-param>
        <param-name>updateAttributes</param-name>
        <param-value>UpdateAttributeRole</param-value>
        <description>Comma-delimited Roles that define the JMX Operation denoting updation of Attributes</description>
      </init-param>
      <init-param>
        <param-name>invokeOp</param-name>
        <param-value>InvokeOpRole</param-value>
        <description>Comma-delimited Roles that define the JMX Operation denoting Invocation of Operations</description>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>JmxOpsAccessControlFilter</filter-name>
      <servlet-name>HtmlAdaptor</servlet-name>
   </filter-mapping>
   -->
   <servlet>
      <servlet-name>HtmlAdaptor</servlet-name>
      <servlet-class>org.jboss.jmx.adaptor.html.HtmlAdaptorServlet</servlet-class>
   </servlet>
   <servlet>
      <servlet-name>ClusteredConsoleServlet</servlet-name>
      <servlet-class>org.jboss.jmx.adaptor.html.ClusteredConsoleServlet</servlet-class>
      <init-param>
         <description>The JGroups protocol stack config</description>
         <param-name>jgProps</param-name>
         <param-value>UDP(ip_mcast=true;ip_ttl=16;loopback=false;mcast_addr=${jboss.partition.udpGroup:228.1.2.3};mcast_port=${jboss.jmxconsolepartition.mcast_port:46666}):
org.jboss.jmx.adaptor.control.FindView
         </param-value>
      </init-param>
   </servlet>
   <servlet>
      <servlet-name>DisplayMBeans</servlet-name>
      <jsp-file>/displayMBeans.jsp</jsp-file>
   </servlet>
   <servlet>
      <servlet-name>InspectMBean</servlet-name>
      <jsp-file>/inspectMBean.jsp</jsp-file>
   </servlet>
   <servlet>
      <servlet-name>DisplayOpResult</servlet-name>
      <jsp-file>/displayOpResult.jsp</jsp-file>
   </servlet>
   <servlet>
      <servlet-name>ClusterView</servlet-name>
      <jsp-file>/cluster/clusterView.jsp</jsp-file>
   </servlet>
   <servlet>
      <servlet-name>ProfileServiceDebugServlet</servlet-name>
      <servlet-class>org.jboss.profileservice.web.DebugServlet</servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>HtmlAdaptor</servlet-name>
      <url-pattern>/HtmlAdaptor</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>ClusteredConsoleServlet</servlet-name>
      <url-pattern>/cluster/ClusteredConsole</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>DisplayMBeans</servlet-name>
      <url-pattern>/DisplayMBeans</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>InspectMBean</servlet-name>
      <url-pattern>/InspectMBean</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>DisplayOpResult</servlet-name>
      <url-pattern>/DisplayOpResult</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>ProfileServiceDebugServlet</servlet-name>
      <url-pattern>/ProfileServiceDebugServlet</url-pattern>
   </servlet-mapping>

   <!-- Display a generic error page when HTTP Status 500 exceptions
        occur. --> 
   <error-page>
      <error-code>500</error-code>
      <location>/genericError.jsp</location>
   </error-page> 

   <!-- A security constraint that restricts access to the HTML JMX console
   to users with the role JBossAdmin. Edit the roles to what you want and
   uncomment the WEB-INF/jboss-web.xml/security-domain element to enable
   secured access to the HTML JMX console.
   -->
   <security-constraint>
     <web-resource-collection>
       <web-resource-name>HtmlAdaptor</web-resource-name>
       <description>An example security config that only allows users with the
         role JBossAdmin to access the HTML JMX console web application
       </description>
       <url-pattern>/*</url-pattern>
       <http-method>GET</http-method>
       <http-method>POST</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>JBossAdmin</role-name>
     </auth-constraint>
   </security-constraint>

   <login-config>
      <auth-method>FORM</auth-method>
      <realm-name>JBoss JMX Console</realm-name>
      <form-login-config>
        <!-- only useful for FORM -->
        <form-login-page>/login-page.html</form-login-page>
        <form-error-page>/error-page.html</form-error-page>
      </form-login-config>
   </login-config>

   <security-role>
      <role-name>JBossAdmin</role-name>
   </security-role>
</web-app>

     

     

    Your WEB-INF/jboss-web.xml should look:

     

    <!DOCTYPE jboss-web PUBLIC
       "-//JBoss//DTD Web Application 5.0//EN"
       "http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">
       
    <jboss-web>
       <!-- Uncomment the security-domain to enable security. You will
          need to edit the htmladaptor login configuration to setup the
          login modules used to authentication users.
       -->
          <security-domain>otp</security-domain>
    </jboss-web>
    

     

    You will need a login-page.html in the jmx-console.war directory.

     

     

    <HTML>                                                               
    <TITLE>Login</TITLE>                                                 
    <BODY>                                                               
    <FORM METHOD=POST ACTION=j_security_check>                      
    <CENTER>                                                             
    <TABLE BORDER=0>                                                     
    <TR><TD COLSPAN=2>                                                   
    <P ALIGN=center>                                                     
    Welcome!  Please enter your Name<br>                                 
     and Password to log in.                                             
    </TD></TR>                                                           
                                                                         
    <TR><TD>                                                             
    <P ALIGN=right><B>Name:</B>                                          
    </TD>                                                                
    <TD>                                                                 
    <P><INPUT TYPE=TEXT NAME="j_username" VALUE="" SIZE=15>                    
    </TD></TR>                                                           
                                                                         
    <TR><TD>                                                             
    <P ALIGN=RIGHT><B>Password:</B>                                      
    </TD>                                                                
    <TD>                                                                 
    <P><INPUT TYPE=PASSWORD NAME="j_password" VALUE="" SIZE=15>              
    </TD></TR>                                                           
                                                                         
    <TR><TD>                                                             
    <P ALIGN=RIGHT><B>Token:</B>                                      
    </TD>                                                                
    <TD>                                                                 
    <P><INPUT TYPE=PASSWORD NAME="totp" VALUE="" SIZE=15>              
    </TD></TR>                                                           
    <TR><TD COLSPAN=2>                                                   
    <CENTER>                                                             
    <INPUT TYPE=submit VALUE="  OK   ">                                  
    </CENTER>                                                            
    </TD></TR>
    </TABLE>
    </FORM>                                                              
    </BODY></HTML>    
    

     

    You will need an error-page.html in the jmx-console.war directory.

     

     

    <HTML>                                                               
    <TITLE>Login Denied</TITLE>                                                 
    <BODY>                                                               
    Sorry, your login was denied.  
    Please hit the Back button to try again.
    </BODY></HTML>
    

     

     

    Now in your conf directory, in the login-config.xml, at the end, add the following block:

     

      <application-policy name="otp">
        <authentication>
          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
            flag="required">
            <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
            <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
          </login-module>
          <login-module code="org.jboss.security.auth.spi.otp.JBossTimeBasedOTPLoginModule" />
        </authentication>
      </application-policy>
    

     

    TOTP Mobile App Set Up

     

    I got the TOTP iPhone app from the App Store.

    http://code.google.com/p/oathtoken/

     

    • I clicked the "+" button. 
    • Then in the token name, added "JBOSS". 
    • Clicked "Time Based". 
    • Generate Random Key  (The key that was generated was transferred to the otp-users.properties file on the server side).

     

    Android:  I tested the free apps.  None of them did what we want. Oh well!  I will write one soon.

    JBoss Application Server Setup

     

    In the conf directory, I created a file "otp-users.properties".  This file is where the user name and the shared secret is stored. The shared secret should be the same as the one in the TOTP mobile client.

     

    My otp-users.properties looks as:

     

    admin=35cae61d6d51a7b3af
    

     

     

    Configuration Options for Login Module

    • algorithm:  either "HmacSHA1", "HmacSHA256" or "HmacSHA512"   [Default: "HmacSHA1"]
    • numOfDigits:  Number of digits in the TOTP.  Default is 6.
    • additionalRoles: any additional roles that you want to add into the authenticated subject (on success). For multiple roles,  separate with a comma

    This login module requires the presence of "otp-users.properties" on the class path with the format:  username=key

    Configurable Options:

     

    • algorithm:  either "HmacSHA1", "HmacSHA256" or "HmacSHA512"   [Default: "HmacSHA1"]
    • numOfDigits:  Number of digits in the TOTP.  Default is 6.
    • additionalRoles: any additional roles that you want to add into the authenticated subject (on success). For multiple roles,  separate with a comma

    This login module requires the presence of "otp-users.properties" on the class path with the format:  username=key

     

    GOTCHAS

    • Remember the parameter for the token in the login page has to be "totp".
    • The secret key on the handheld application and the otp-users.properties have to be the same.  This is an out-of-band synchronization that can be done via a phone call with system admin.