About Jakub Holy

Jakub is an experienced Java[EE] developer working for a lean & agile consultancy in Norway. He is interested in code quality, developer productivity, testing, and in how to make projects succeed.

JBoss AS 7: Custom Login Modules

JBoss AS 7 is neat but the documentation is still quite lacking (and error messages not as useful as they could be). This post summarizes how you can create your own JavaEE-compliant login module for authenticating users of your webapp deployed on JBoss AS. A working elementary username-password module provided.

Why to use Java EE standard authentication? Java EE security primer

A part of the Java EE specification is security for web and EE applications, which makes it possible both to specify declarative constraints in your web.xml (such as “role X is required to access resources at URLs “/protected/*”) and to control it programatically, i.e. verifying that the user has a particular role (see HttpServletRequest.isUserInRole).

It works as follows:

  1. You declare in your web.xml:
    1. Login configuration – primarily whether to use browser prompt (basic) or a custom login form and a name for the login realm
      • The custom form uses “magic” values for the post action and the fields, starting with j_, which are intercepted and processed by the server
    2. The roles used in your application (typically you’d something like “user” and perhaps “admin”)
    3. What roles are required for accessing particular URL patterns (default: none)
    4. Whether HTTPS is required for some parts of the application
  2. You tell your application server how to authenticate users for that login realm, usually by associating its name with one of the available login modules in the configuration (the modules ranging from simple file-based user list to LDAP and Kerberos support). Only rarely do you need to create your own login module, the topic of this post.

If this is new for you than I strongly recommend reading The Java EE 5 Tutorial – Examples: Securing Web Applications (Form-Based Authentication with a JSP Page incl. security constraint specification, Basic Authentication with JAX-WS, Securing an Enterprise Bean, Using the isCallerInRole and getCallerPrincipal Methods).

Why to bother?

  • Declarative security is nicely decoupled from the business code
  • It’s easy to propagate security information between a webapp and for example EJBs (where you can protect a complete bean or a particular method declaratively via xml or via annotations such as @RolesAllowed)
  • It’s easy to switch to a different authentication mechanism such as LDAP and it’s more likely that SSO will be supported

Custom login module implementation options

If one of the login modules (a.k.a. security domains) provided out of the box with JBoss, such as UsersRoles, Ldap, Database, Certificate, isn’t sufficient for you then you can adjust one of them or implement your own. You can:

  1. Extend one of the concrete modules, overriding one or some of its methods to ajdust to your needs – see f.ex. how to override the DatabaseServerLoginModule to specify your own encryption of the stored passwords. This should be your primary choice, of possible.
  2. Subclass UsernamePasswordLoginModule
  3. Implement javax.security.auth.spi.LoginModule if you need maximal flexibility and portability (this is a part of Java EE, namely JAAS, and is quite complex)

JBoss EAP 5 Security Guide Ch. 12.2. Custom Modules has an excellent description of the basic modules (AbstractServerLoginModule, UsernamePasswordLoginModule) and how to proceed when subclassing them or any other standard module, including description of the key methods to implement/override. You must read it. (The guide is still perfectly applicable to JBoss AS 7 in this regard.) The custom JndiUserAndPass module example, extending UsernamePasswordLoginModule, is also worth reading – it uses module options and JNDI lookup.

Example: Custom UsernamePasswordLoginModule subclass

See the source code of MySimpleUsernamePasswordLoginModule that extends JBoss’ UsernamePasswordLoginModule.

The abstract UsernamePasswordLoginModule (source code) works by comparing the password provided by the user for equality with the password returned from the method getUsersPassword, implemented by a subclass. You can use the method getUsername to obtain the user name of the user attempting login.

Implement abstract methods

getUsersPassword()

Implement getUsersPassword() to lookup the user’s password wherever you have it. If you do not store passwords in plain text then read how to customize the behavior via other methods below

getRoleSets()

Implement getRoleSets() (from AbstractServerLoginModule) to return at least one group named “Roles” and containing 0+ roles assigned to the user, see the implementation in the source code for this post. Usually you’d lookup the roles for the user somewhere (instead of returning hardcoded “user_role” role).

Optionally extend initialize(..) to get access to module options etc.

Usually you will also want to extend initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) (called for each authentication attempt),

Optionally override other methods to customize the behavior

If you do not store passwords in plain text (a wise choice!) and your hashing method isn’t supported out of the box then you can override createPasswordHash(String username, String password, String digestOption) to hash/encrypt the user-supplied password before comparison with the stored password.

Alternatively you could override validatePassword(String inputPassword, String expectedPassword) to do whatever conversion on the password before comparison or even do a different type of comparison than equality.

Custom login module deployment options

In JBoss AS you can

  1. Deploy your login module class in a JAR as a standalone module, independently of the webapp, under <JBoss AS 7>/modules/, together with a module.xml – described at JBossAS7SecurityCustomLoginModules
  2. Deploy your login module class as a part of your webapp (no module.xml required)
    1. In a JAR inside WEB-INF/lib/
    2. Directly under WEB-INF/classes

In each case you have to declare a corresponding security-domain it inside JBoss configuration (standalone/configuration/standalone.xml or domain/configuration/domain.xml):

<security-domain name='form-auth' cache-type='default'>
  <authentication>
    <login-module code='custom.MySimpleUsernamePasswordLoginModule' flag='required'>
      <!--module-option name='exampleProperty' value='exampleValue'/-->
    </login-module>
  </authentication>
</security-domain>

The code attribute should contain the fully qualified name of your login module class and the security-domain’s name must match the declaration in jboss-web.xml:

<?xml version='1.0' encoding='UTF-8'?>
<jboss-web>
  <security-domain>form-auth</security-domain>
  <disable-audit>true</disable-audit>
</jboss-web>

The code

Download the webapp jboss-custom-login containing the custom login module MySimpleUsernamePasswordLoginModule, follow the deployment instructions in the README.

Reference: Creating Custom Login Modules In JBoss AS 7 (and Earlier) from our JCG partner Jakub Holy at the The Holy Java blog.

Related Whitepaper:

Java Application Development on Linux

Linux is the fastest-growing Java development platform because it saves money and time by serving as a platform for both development and deployment. But developers face significant platform-specific challenges when managing and deploying Java applications in a controlled production environment.

This is the hands-on guide to the full Java application development lifecycle on Linux. It demonstrates the platform, tools, and application development by showing realistic, easy-to-follow examples. After a simple command-line application introduces basic tools, this program leads readers through business-logic object analysis, database design, Java servlet UIs, Java Server Pages (JSP) UIs, Swing GUIs, and Standard Widget Toolkit (SWT) GUIs. Scaling up to the enterprise level provides the opportunity to use both the JBoss Application Server and the Apache Geronimo Application Servers, and Enterprise JavaBeans (EJB).

Get it Now!  

One Response to "JBoss AS 7: Custom Login Modules"

  1. disqus_jBBiae90s7 says:

    Hello,

    sorry if it’s the wrong place to post this. if it’s a bother please refer me to where. I have already tried two forums but I’m short on time so I’m hoping ou can help me !

    The below foler (pic) is named jawda.war . my boss asked me to have it deployed under jboss 7… it’s not a war file or anything ! when I zip it I get the following message

    13:25:47,014 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads – 2) JBAS015051: Deployment content /opt/jboss-as/standalone/deployments/jawda.war appears to be incomplete and is not progressing toward completion. This content cannot be auto-deployed.

    I’m not a developer or anything, they only askd me to deploy it .. So I suppose it was working in Jboss 4 ( i think)
    plzase help

Leave a Reply


× 9 = eighty one



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books