You are on page 1of 24

Java, JAAS and JBoss Security

Michael Clark <michael at metaparadigm dot com>

Nov 17, 2006 1


Presentation Overview
Introduction
Application Level Security
Java Security
Java Authentication and Authorization Services
J2EE Security
Implementing JAAS with JBoss/Tomcat
EJB method security with JBoss/Tomcat

Nov 17, 2006 2


Introduction
Basic Security principles
Authentication / Non-repudiation
Integrity / Access / Authorization
Confidentiality / Encryption
Areas of Security
Network Security
– Firewalls, VPN, SSL, Intrusion detection, ...
OS/Server Security
– File permissions/ACLs, PAM, LDAP, Kerberos, ...
Application Security
– ?

Nov 17, 2006 3


Application Level Security
Common requirements
Same basic needs for (AA) Authentication/Authorization
Need to integrate with common AA mechanisms such as
LDAP authentication and role based authorization
Separation of Concerns
Separate security policy from application code
– need a way to specify policy outside of the code
Scope / Complexity
Enterprise Applications are implemented:
– in many different ways, in many different languages, have
complex authorization schemes, exposure at many levels
 bugs, SQL injection, missed authority checks, ...

Nov 17, 2006 4


Application Level Security (cont.)
More complex requirements
Method level security
– An authentic user is authorized to access this business
function. For example:
 A staff member in Accounts Payable is authorized to use the
cheque printing function
Object level security
– An authentic user is authorized to perform this business
function on this particular object. For example:
 A customer is authorized to make an on-line transaction only
from their own account and only for the particular products
they are authorized to use

Nov 17, 2006 5


Application Level Security (cont.)
Common errors
Only check authentication on first page, but this can be
bypassed by a hacker to access a protected function
Missing authorization check in business logic.
– Bank account transfer screen displays accounts the
customer is authorized to make transfers on but the
transfer business logic doesn't check this when making
the transfer
– Mistake in assuming that what is visible is what the user is
authorized to act on. We need to put authorization in the
back business logic first
Missing Validation allowing data injection
– SQL injection, File path injection

Nov 17, 2006 6


Java Security
Sandbox model
Run untrusted code with restricted permissions
Control access to restricted resources
– Class loading, Thread creation, exitVM, ...
 java.io.RuntimePermission
– File system path, read or write access control
 java.io.FilePermission
– Network access, address ranges and ports
 java.net.SocketPermission
Type safety
– can't get references to other objects / memory

Nov 17, 2006 7


Java Security (cont.)
Security Manager
Default implementation provided (can be replaced)
Enforces security policy / access control
Not enabled by default when running outside browser
Need to specify flags to the JVM to enable
java ­Djava.security.manager \
     ­Djava.security.policy=myauth.polocy \
     com.example.MyClass

Security Policy
Contains policy permissions
http://java.sun.com/j2se/1.5.0/docs/guide/security/index.html

Nov 17, 2006 8


Java Security (cont.)
Security Policy Example
grant {
   permission java.lang.RuntimePermission "getClassLoader";
   permission java.lang.RuntimePermission "createClassLoader";
   permission java.io.FilePermission "/usr/lib/j2sdk1.5­sun/jre/lib/­", "read";
};

grant codebase "file:/opt/jboss­3.2.7/­" {
   permission java.security.AllPermission;
};

grant codebase "file:/opt/myapp/­" {
   permission java.lang.RuntimePermission "org.jboss.security.SecurityAssociation.getPrincipalInfo";
   permission java.lang.RuntimePermission "org.jboss.security.SecurityAssociation.setPrincipalInfo";
   permission java.util.PropertyPermission "*", "read";
   permission java.net.SocketPermission "*", "resolve,connect";
   permission java.lang.RuntimePermission "createClassLoader";
   permission java.lang.RuntimePermission "getClassLoader";
...
   permission java.io.FilePermission "/opt/myapp/data/­", "read,write";
   permission java.io.FilePermission "/opt/jboss­3.2.7/lib/­", "read";
   permission java.io.FilePermission "/opt/jboss­3.2.7/server/default/lib/­", "read";
};

Nov 17, 2006 9


JAAS
JAAS
JAAS (Java Authentication and Authorization Service)
Modeled on Sun's PAM (Pluggable Authentication Modules)
Builds on top of Java Security / Access Control
Provides a pluggable mechanism to authenticate users
– Through the use of LoginModule(s)
Provides for authorization of users
– Control access to restricted actions
grant Principal org.jboss.security.SimplePrinciple "mclark" {
        permission java.io.FilePermission "foo.txt", "read";
};

http://java.sun.com/j2se/1.5.0/docs/guide/security/jaas/JAASRefGuide.html

Nov 17, 2006 10


J2EE Security
Builds on JAAS
JAAS provides the authentication and authorization
Method-level Access Control
Specified in EJB Assembly Descriptors tags in: ejb­jar.xml
Can be used to secure SessionBeans, EntityBeans,
MessageQueues
Ensures access to all RMI/IIOP calls to the middle-tier are
authenticated and the user/principle has the required role

Nov 17, 2006 11


JBoss/Tomcat JAAS Example
Requires the following:
JBoss JAAS Login module configuration
– Specific to a Security Domain
– eg. DatabaseLoginModule or LDAPLoginModule
– you can write a Custom LoginModule if desired
Users and Roles defined in a database or LDAP directory
EJB Application configuration
– ejb­jar.xml Assembly Descriptors
– jboss.xml Security Domain configuration
Front tier servlet filter to perform JAAS login
– The traditional servlet login method can also be used

Nov 17, 2006 12


JBoss LoginModule configuration
JBoss Database Login Module config example
{jboss­home}/server/default/conf/login­config.xml

  <application­policy name = "my­app">
      <authentication>
          <login­module code="org.jboss.security.auth.spi.ProxyLoginModule" flag="required">
              <module­option name="moduleName">
                  org.jboss.security.auth.spi.DatabaseServerLoginModule
              </module­option>
              <module­option name="dsJndiName">java:/MyDataSource</module­option>
              <module­option name="principalsQuery">
                  select password from myapp_user
                  where email_address = ?
              </module­option>
              <module­option name="rolesQuery">
                  select role_name, role_group
                  from myapp_user, myapp_user_role
                  where myapp_user.user_id = myapp_user_role.user_id
                  and myapp_user.email_address = ?
              </module­option>
      </login­module>
     </authentication>
    </application­policy>

Nov 17, 2006 13


JBoss LoginModule configuration (cont.)
JBoss LDAP Login Module config example
{jboss­home}/server/default/conf/login­config.xml

    <application­policy name = "my­app">
        <authentication>
            <login­module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required">
                <module­option name="java.naming.factory.initial"> 
                    com.sun.jndi.ldap.LdapCtxFactory
                </module­option>
                <module­option name="java.naming.provider.url">
                   ldap://ldap.mydomain.com.sg:389
                </module­option>
                <module­option name="java.naming.security.authentication">
                    simple
                </module­option>
                <module­option name="principalDNPrefix">uid=</module­option>                    
                <module­option name="principalDNSuffix">,ou=people,dc=mydomain,dc=com,dc=sg</module­option>
                <module­option name="roleAttributeIsDN">false</module­option>
                <module­option name="searchTimeLimit">5000</module­option>
                <module­option name="searchScope">ONELEVEL_SCOPE</module­option>
            </login­module>
        </authentication>
    </application­policy>

Nov 17, 2006 14


Sample User Database
MySQL Example Database DDL
/* user table */
create table myapp_user (
user_id bigint not null auto_increment,
full_name varchar(60) not null,
email_address varchar(60) not null,
password varchar(20) null,
created datetime not null,
updated datetime not null,
deleted datetime null,
primary key (user_id)
);

/* role */
create table myapp_user_role (
user_role_id bigint not null auto_increment,
user_id bigint not null,
role_name varchar(60) not null,
role_group varchar(60) not null,
primary key (user_role_id),
foreign key (user_id) references myapp_user (user_id)
);

Nov 17, 2006 15


Sample User Data
MySQL Example Data DML
insert into myapp_user (user_id, full_name, email_address, password, created, updated)
values (1, 'anonymous', 'anonymous', 'anonymous', utc_date, utc_date);

insert into myapp_user (user_id, full_name, email_address, password, created, updated)
values (2, 'admin', 'admin', 'changeme', utc_date, utc_date);

insert into myapp_user (user_id, full_name, email_address, password, created, updated)
values (2, 'Scott', 'scott@example.com', 'tiger', utc_date, utc_date);

insert into jobs_user_role (user_role_id, user_id, role_name, role_group)
values (1, 1, 'anonymous', 'Roles');

insert into jobs_user_role (user_role_id, user_id, role_name, role_group)
values (2, 2, 'admin', 'Roles');

insert into jobs_user_role (user_role_id, user_id, role_name, role_group)
values (3, 3, 'member', 'Roles');

Nov 17, 2006 16


EJB Application Configuration
ejb­jar.xml fragment
   <assembly­descriptor>
      <method­permission>
         <role­name>anonymous</role­name>
         <method><ejb­name>MemberEJB/ejb­name><method­name>create</method­name></method>
         <method><ejb­name>MemberEJB</ejb­name><method­name>registerUser</method­name></method>
         <method><ejb­name>MemberEJB</ejb­name><method­name>forgotPassword</method­name></method>
      </method­permission>
      <method­permission>
         <role­name>member</role­name>
         <method><ejb­name>MemberEJB</ejb­name><method­name>create</method­name></method>
         <method><ejb­name>MemberEJB</ejb­name><method­name>login</method­name></method>
         <method><ejb­name>MemberEJB</ejb­name><method­name>getResource</method­name></method>
      </method­permission>
      <method­permission>
         <role­name>admin</role­name>
         <method><ejb­name>MemberController</ejb­name><method­name>*</method­name></method>
      </method­permission>
   </assembly­descriptor>

Nov 17, 2006 17


EJB Application Configuration (cont.)
jboss.xml fragment

<?xml version="1.0" encoding="UTF­8"?>

<jboss>

  <security­domain>java:/jaas/my­app</security­domain>

  <unauthenticated­principal>anonymous</unauthenticated­principal>

  ...

</jboss>

Nov 17, 2006 18


Example JAAS Login Servlet Filter
import java.io.IOException;
import javax.servlet.*
import javax.servlet.http.*;
import javax.security.auth.login.*;
import javax.security.auth.callback.*;
import java.util.logging.Logger;

public class JAASLoginFilter implements Filter
{
    private final static Logger log =
        Logger.getLogger(JAASLoginFilter.class.getName());

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException
    {
        login(request);
        chain.doFilter(request, response);
        logout(request);
    }

    ...

    public void init(FilterConfig filterConfig) {}
    public void destroy() {}
}

Nov 17, 2006 19


Example JAAS Login Servlet Filter (cont.)
    static class LoginCallback implements CallbackHandler
    {
        private String username;
        private String password;

        protected LoginCallback(String username, String password)
        {
            this.username = username;
            this.password = password;
        }

        public void handle(Callback[] callbacks)
        {
            for(int i=0; i < callbacks.length; i++) {
                if(callbacks[i] instanceof NameCallback) {
                    NameCallback nameCallback =
                        (NameCallback)callbacks[i];
                    nameCallback.setName(username);
                } else if(callbacks[i] instanceof PasswordCallback) {
                    PasswordCallback passwordCallback =
                        (PasswordCallback)callbacks[i];
                    passwordCallback.setPassword(password.toCharArray());
                }
            }
        }
    }

Nov 17, 2006 20


Example JAAS Login Servlet Filter (cont.)
    public static void login(ServletRequest request)
    {
        // Don't do anything if there is no session
        if(!(request instanceof HttpServletRequest)) return;
        HttpSession session = ((HttpServletRequest)request).getSession(false);
        if(session == null) return;

        // Get username and password from the session
        String username = (String)session.getAttribute("username");
        String password  = (String)session.getAttribute("password");

        // Don't login if the username or password isn't set
        if(username == null || password == null) return;

        // Login
        CallbackHandler handler = new LoginCallback(username, password);
        LoginContext lc = null;
        try {
            lc = new LoginContext("client­login", handler);
            lc.login();
            request.setAttribute("jaas­login­context", lc);
            request.setAttribute("jaas­username", username);
        } catch (LoginException e) {
            log.warning("error logging in, username=" + username + " : " + e.getMessage());
        }
    }

Nov 17, 2006 21


Example JAAS Login Servlet Filter (cont.)
    public static void logout(ServletRequest request)
    {
        LoginContext lc = (LoginContext)
            request.getAttribute("jaas­login­context");
        String username = (String)
            request.getAttribute("jaas­username");
        if(lc == null || username == null) return;

        // Logout
        try {
            lc.logout();
        } catch (LoginException e) {
            log.warning("error logging out, username=" + username + " : " + e.getMessage());
        }
    }

Nov 17, 2006 22


Additional Resources
JAAS
http://java.sun.com/products/jaas/
JBoss Security
http://www.jboss.org/developers/projects/jboss/security
Acegi Security for Spring
http://www.acegisecurity.org/

Nov 17, 2006 23


Thank You
Michael Clark <michael at metaparadigm dot com>

Nov 17, 2006 24

You might also like