Version 8

    This article is a one stop resource for web security in JBoss Application Server.  Even though the configuration may change between major versions of JBoss Application Server, the features should be available starting JBoss AS 5 and beyond.

    What is provided by Java EE in terms of Web Security?

    The main security constructs in Web Security come from the web.xml security configurations until Java EE5.  These are reasonably documented in a use case manner at

    http://java.dzone.com/articles/understanding-web-security

     

    Servlet Security in Servlet 3 and Java EE 6

    Starting Java EE6, with the introduction of the Servlet 3 specification, you have some security annotations that allow you to configure your servlets with security information.

     

    An example is:

     

    package org.jboss.as.test.spec.servlet3;
    
    import java.io.IOException;
    import java.io.Writer;
    
    import javax.annotation.security.DeclareRoles;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.HttpConstraint;
    import javax.servlet.annotation.ServletSecurity;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * A simple servlet that just writes back a string
     *
     * @author Anil Saldhana
     */
    @WebServlet(name = "SecuredServlet", urlPatterns = { "/secured/" }, loadOnStartup = 1)
    @ServletSecurity(@HttpConstraint(rolesAllowed = { "gooduser" }))
    @DeclareRoles("gooduser")
    public class SecuredServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Writer writer = resp.getWriter();
            writer.write("GOOD");
        }
    }
    

     

    As you can see, there are some annotations such as @ServletSecurity and @DeclareRoles that can be used to avoid the web.xml security constraint settings.

     

    Even though you have been able to specify the annotations, we cannot avoid web.xml. The reason is that we need to specify the login config.

     

    <?xml version="1.0"?>
    <web-app 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_3_0.xsd"
        version="3.0">
    
      <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>WebSecurityBasic</realm-name>
      </login-config>
    
    </web-app>
    
    

     

    What do we need jboss-web.xml for?

     

    Remember the Java EE specifications provide the flexibility of adding vendor specific deployment descriptors to fill in the missing gaps.

     

    You will need a jboss-web.xml to specify the

    • security domain name

     

    The security domain name is very important that it defines a set of:

    • Authentication Login Modules.
    • Authorization Policy Modules.
    • Audit Providers.
    • Mapping Providers.
      • Principal Mapping providers.
      • Role Mapping Providers.
      • Attribute Mapping Providers.

     

     

    In JBoss AS7.1, the jboss-web.xml allows the following flags:

    • use-jboss-authorization
    • disable-audit

     

    Please refer to the sections on authorization and audit.

     

    Servlet Programmatic Security

    Servlet 3 provides facilities to perform login() and logout() programmatically.  Here is an example:

     

     

    package org.jboss.as.test.spec.servlet3;
    
    import java.io.IOException;
    import java.security.Principal;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * A simple servlet that tries to do a programmatic login
     *
     * @author Marcus Moyses
     */
    @WebServlet(name = "LoginServlet", urlPatterns = { "/login/" }, loadOnStartup = 1)
    public class LoginServlet extends HttpServlet {
    
        private static final long serialVersionUID = 5442257117956926577L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String username = (String) req.getParameter("username");
            String password = (String) req.getParameter("password");
            req.login(username, password);
            Principal principal = req.getUserPrincipal();
            if (principal == null)
                throw new ServletException("getUserPrincipal returned null");
            String remoteUser = req.getRemoteUser();
            if (remoteUser == null)
                throw new ServletException("getRemoteUser returned null");
            String authType = req.getAuthType();
            if (authType == null || !authType.equals("LOGIN"))
                throw new ServletException("getAuthType returned null or wrong type");
            if (!req.isUserInRole("gooduser")) {
                resp.sendError(403);
            }
            req.logout();
            principal = req.getUserPrincipal();
            if (principal != null)
                throw new ServletException("getUserPrincipal didn't return null after logout");
            remoteUser = req.getRemoteUser();
            if (remoteUser != null)
                throw new ServletException("getRemoteUser didn't return null after logout");
            authType = req.getAuthType();
            if (authType != null)
                throw new ServletException("getAuthType didn't return null after logout");
            if (req.isUserInRole("gooduser") || req.isUserInRole("superuser"))
                throw new ServletException("User shouldn't be in any roles after logout");
        }
    }
    

     

    Authorization

     

    Java EE has always defined coarse grained role based access control.  In the web application world. the Java EE specifications have two types of authorization:

    1. Servlet Spec behavior on web.xml security constraints.
    2. JACC (JSR 115) behavior on web.xml security constraints.

     

    Now if the user would like to utilize fine grained access control such as those provided by the Oasis XACML specification, then this is a non-spec behavior.  The same applies to custom authorization. 

     

    JBoss AS has the feature to configure authorization policy modules to provide XACML or any custom authorization needs. By default, the web container applies the spec behavior.  If the user wants to configure JACC, then he can do so at the security domain level.

    http://docs.jboss.org/jbosssecurity/docs/6.0/security_guide/html/Authorization_Stacks.html

     

    http://java.dzone.com/articles/security-features-jboss-510-2

    http://java.dzone.com/articles/fine-grained-web-authorization

     

     

    In JBoss AS 7.1 and beyond, for the web authorization, the JBoss Authorization Modules are not called until you specify the <use-jboss-authorization/> flag in jboss-web.xml

     

    Audit

    Auditing security events happening with web security is not a spec behavior. This is just a value added feature available in JBoss Application Server.

     

    A general article on this is http://java.dzone.com/articles/security-auditing-jboss

     

    In JBoss Application Server v7.1 and beyond, please refer to:

    http://community.jboss.org/wiki/JBossAS7SecurityAuditing

     

    In JBoss AS7.1, auditing is enabled by default in the web container.  If you do not want to audit, you will have to use <disable-audit/> in jboss-web.xml of your web application.

     

     

    References

    http://java.dzone.com/articles/security-jboss-enterprise

    http://java.dzone.com/users/janilsal