Friday, March 09, 2007

Securing Middle tier Objects with Acegi Security Framework

Previously, I posted an example on implementing Security using Acegi Security Framework for applications using Spring framework. This post will describe an example on how to secure Middle-tier objects using Acegi, with Role-based authorization. Here is how to implement the example.
  1. Create the example project as shown in "Spring security with Acegi Security Framework". This will be the starting point.
  2. Create the Secure Object: The secure object here is SecureDAO, which is a dummy object that has the common create, read, update, delete methods.
    package test;

    public class SecureDAO {
    public String create() {
    return "create";
    }

    public String read() {
    return "read";
    }

    public String update() {
    return "update";
    }

    public String delete() {
    return "delete";
    }
    }
    SecureDAO.java
  3. Create the Test Servlet: The servlet is used to invoke the secure DAO object.
    package servlets;

    import java.io.IOException;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;

    import test.SecureDAO;

    public class TestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    public TestServlet() {
    super();
    }

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String method = request.getParameter("method");

    WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());

    SecureDAO obj = (SecureDAO) context.getBean("secureDAO");
    String result = "";
    if (method.equals("create")) {
    result = obj.create();
    }
    if (method.equals("read")) {
    result = obj.read();
    }

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

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

    response.getWriter().println(result);

    }
    }
    TestServlet.java
  4. Update the authenticatedusers.jsp file to invoke the TestSerlvet, as shown below
    <%@ page import="org.acegisecurity.context.SecurityContextHolder"%>
    <h1>Welcome: <%=SecurityContextHolder.getContext().getAuthentication().getName()%></h1>
    <p><a href="../">Home</a>
    <form action="/SpringSecurity/TestServlet"><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>
    <p><a href="../j_acegi_logout">Logout</a>
    authenticatedusers.jsp

  5. Update the applicationContext.xml file to include the security definitions by adding the following bean definitions as shown below
    <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
    <property name="authenticationManager">
    <ref bean="authenticationManager" />
    </property>
    <property name="accessDecisionManager">
    <bean class="org.acegisecurity.vote.AffirmativeBased">
    <property name="allowIfAllAbstainDecisions" value="false" />
    <property name="decisionVoters">
    <list>
    <bean class="org.acegisecurity.vote.RoleVoter" />
    <bean class="org.acegisecurity.vote.AuthenticatedVoter" />
    </list>
    </property>
    </bean>
    </property>
    <property name="objectDefinitionSource">
    <value>
    test.SecureDAO.*=IS_AUTHENTICATED_REMEMBERED
    test.SecureDAO.delete=ROLE_ADMIN
    </value>
    </property>
    </bean>


    <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="interceptorNames">
    <list>
    <value>methodSecurityInterceptor</value>
    </list>
    </property>
    <property name="beanNames">
    <list>
    <value>secureDAO</value>
    </list>
    </property>
    </bean>

    <bean id="secureDAO" class="test.SecureDAO" />
    Note
    • The MethodSecurityInterceptor is used to define the mapping between the Methods and the roles that are allowed to invoke these methods.
    • The BeanNameAutoProxyCreator is used to create a proxy for the secureDAO object, so that an authorization check may be applied to every invocation on the object.
  6. Add the cglib JAR file available in the Spring download as a dependency to your project. This is used for creating the Proxy.

4 comments:

  1. great article,
    hope you write more even greater article.

    ReplyDelete
  2. in authenticatedusers.jsp
    instead of
    action="/SpringSecurity/TestServlet"

    it should be
    action="../SpringSecurity/TestServlet"

    Thanks
    -narendra

    ReplyDelete
  3. Guys,

    I can't access "test.SecureDAO" on my application maybe I'm using the wrong structure, where I need to put SecureDAO:

    MyProject
    |-WEB-INF
    | |-applicationContext.xml
    | |-web.xml
    |-test
    | |-SecureDAO.java
    |-servlet
    |-TestServlet.java

    ReplyDelete
  4. you should definitely include your project along with such examples or atleast the war file.

    ReplyDelete

Popular Posts