Monday, May 07, 2007

Securing EJB 3.0 Beans

The Java EE 5 Security services are provided by the container and can be implemented using declarative or programmatic techniques. In addition to declarative and programmatic ways to implement security (in J2EE), Java EE 5 supports the use of metadata annotations for security. This post will describe how to secure EJB 3.0 beans. The post consists of a simple EJB, with a web client. In order to run the example, follow these steps.
Create Users in Glassfish
  1. Go to Configuration->Security->Realms->file in the Glassfish admin console.
  2. In the file realm, click on manage users.
  3. Add new users by clicking on add there.

The EJB Component
  1. Start with a Simple Java project in Eclipse.
  2. Remote Interface
    package ejb;

    import javax.ejb.Remote;

    @Remote
    public interface DABean {
    public String create();

    public String read();

    public String update();

    public String delete();
    }
    ejb/DABean.java
  3. The Bean:
    package ejb;

    import javax.annotation.security.DeclareRoles;
    import javax.annotation.security.RolesAllowed;
    import javax.ejb.Stateless;

    @Stateless (mappedName = "ejb/secureEJB")
    @DeclareRoles({"emp","guest"})

    public class SecureEJB implements DABean {

    @RolesAllowed({"emp","guest"})
    public String create() {
    return "create";
    }

    @RolesAllowed({"emp","guest"})
    public String read() {
    return "read";
    }

    @RolesAllowed("emp")
    public String update() {
    return "update";
    }

    @RolesAllowed("emp")
    public String delete() {
    return "delete";
    }

    }
    ejb/SecureEJB.java
    • The declaredRoles and RolesAllowed annotations take a string array as a parameter.
  4. Deployment descriptor:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
    <sun-ejb-jar>
    <security-role-mapping>
    <role-name>guest</role-name>
    <group-name>guest</group-name>
    </security-role-mapping>

    <security-role-mapping>
    <role-name>emp</role-name>
    <group-name>employee</group-name>
    </security-role-mapping>

    <enterprise-beans>
    <unique-id>0</unique-id>
    <ejb>
    <ejb-name>SecureEJB</ejb-name>
    <jndi-name>ejb/secureEJB</jndi-name>
    <gen-classes />
    </ejb>
    </enterprise-beans>
    </sun-ejb-jar>
    META-INF/sun-ejb-jar.xml

The Web Client
For a little bit more detail explanation on the Web Application, see the previous post Securing Java EE 5 Web Applications
  1. The EJB Client Jar file: When you deploy the EJB application in Glassfish, it creates a corresponding EJB Client jar file for the EJB component, which can be used in the clients. The file will created in the following directory.
    GLASSFISH_HOME\domains\DOMAIN_NAME/generated\xml/j2ee-modules/APPLICATION_NAME
  2. Selection page
    <html>
    <body>
    <h1>Home Page</h1>
    Anyone can view this page.

    <form action="securityServlet"><select name="method">
    <option value="create">create</option>
    <option value="read">read</option>
    <option value="update">update</option>
    <option value="delete">delete</option>
    </select> <input type="submit" name="submit" /></form>
    </body>
    </html>
    index.jsp
  3. Servlet
    package servlets;

    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.annotation.security.DeclareRoles;
    import javax.ejb.EJB;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import ejb.DABean;

    @DeclareRoles("emp")
    public class SecurityServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    @EJB(name = "timerBean", mappedName = "corbaname:iiop:localhost:3700#ejb/secureEJB")
    private DABean daBean;

    public SecurityServlet() {
    super();
    }

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    String method = request.getParameter("method");
    try {
    String result = "";
    if (method.equals("create")) {
    result = daBean.create();
    }
    if (method.equals("read")) {
    result = daBean.read();
    }

    if (method.equals("update")) {
    result = daBean.update();
    }

    if (method.equals("delete")) {
    result = daBean.delete();
    }

    out.println(request.getUserPrincipal() + " is an Authorized User");
    } catch (Exception e) {
    e.printStackTrace();
    out.println(request.getUserPrincipal() + " is not an Authorized to see this page.");
    }
    }
    }
    SecurityServlet.java
  4. Deployment descriptor
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5" 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">
    <display-name>Java5Security</display-name>

    <servlet>
    <description></description>
    <display-name>SecurityServlet</display-name>
    <servlet-name>SecurityServlet</servlet-name>
    <servlet-class>servlets.SecurityServlet</servlet-class>
    <security-role-ref>
    <role-name>emp</role-name>
    <role-link>emp</role-link>
    </security-role-ref>
    </servlet>
    <servlet-mapping>
    <servlet-name>SecurityServlet</servlet-name>
    <url-pattern>/securityServlet</url-pattern>
    </servlet-mapping>


    <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>file</realm-name>
    <form-login-config>
    <form-login-page>/login.jsp</form-login-page>
    <form-error-page>/error.jsp</form-error-page>
    </form-login-config>
    </login-config>

    <security-constraint>
    <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <url-pattern>/*</url-pattern>
    <http-method>PUT</http-method>
    <http-method>DELETE</http-method>
    <http-method>GET</http-method>
    <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>guest</role-name>
    <role-name>emp</role-name>
    </auth-constraint>
    </security-constraint>

    <security-constraint>
    <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <url-pattern>/secure/*</url-pattern>
    <http-method>PUT</http-method>
    <http-method>DELETE</http-method>
    <http-method>GET</http-method>
    <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>emp</role-name>
    </auth-constraint>
    </security-constraint>
    <!-- Security roles referenced by this web application -->
    <security-role>
    <role-name>guest</role-name>
    </security-role>
    <security-role>
    <role-name>emp</role-name>
    </security-role>

    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    </web-app>
    web.xml
  5. Glassfish Deployment descriptor
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 Servlet 2.4//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_4-1.dtd">
    <sun-web-app>
    <context-root>/Java5Security</context-root>
    <security-role-mapping>
    <role-name>guest</role-name>
    <group-name>guest</group-name>
    </security-role-mapping>
    <security-role-mapping>
    <role-name>emp</role-name>
    <group-name>employee</group-name>

    </security-role-mapping>
    </sun-web-app>
    sun-web.xml
Environment: This example was run on Glassfish V2 Build 41 (Glassfish V2 Beta 2).

4 comments:

  1. in my application i am using a stand alone client.i want to access an ejb method by a specific role.and the role is mapped in sun-ejb-jar.xml.im using file realm.but the method is accessed by any role.please help

    ReplyDelete
  2. HEllo there,

    Using eclipse, trying to get your example to work.
    In Glassfish and adding users, you do not say which users to add !?

    Could you provide a dump on how your structure looks like, where the index.jsp file and all the other files should be ?

    regards, i

    ReplyDelete
  3. hi abhi,
    i am currently using ejb 3.0 on jboss, now i want to learn ejb 3.0 on websphere. So, can you help in this?

    ReplyDelete
  4. I want to do this thing not with a web client but with a Swing client in an EJB Client Container downloaded via Web Start.

    Now my Problem is how to assign my Security Realm to the EJB Module. Did not find any hint in all google Hits until now. Must this be done in sun-ejb-jar.xml and how?

    ReplyDelete

Popular Posts