The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Glassfish - Role Based Access Control (Part 1)

Posted by tchangu on June 11, 2006 at 9:55 PM PDT
Recently I have been exploring the various security features in Glassfish AS. In this blog entry, I hope to share some of my initial findings related to role based access control.

The following simple problem highlights the need for different roles. Lets say, user 'X' can perform transactions as well as view non-transactional parts of the application. However user 'A' can only view access the non-transactional parts of the application. For this simple case we have one servlet that is transactional that only few users (like X) could access while others (like A) are limited a general servlet. In order to accomplish this we go through a series of six simple steps and they are as follows:

STEP 1: The first step is to create two servlets. One is transactional in nature while the other is limited to general purpose view only type of access.

STEP 2: The next step is to define the role in the servlet. This can be accomplished using the DeclareRoles annotation type with role name as element.
@DeclareRoles("Transactional")
public class TransactionalServlet extends HttpServlet {
	// doGet/doPost
}

@DeclareRoles("General")
public class GeneralServlet extends HttpServlet {
    // doGet/doPost
}
STEP 3: Next, specify in web.xml, declaratively aspects related to security. First define the authentication method.
    <!-- LOGIN CONFIGURATION-->
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>SecureWebFileRealm</realm-name>
        <form-login-config>
            <form-login-page>/pages/logon.jsp</form-login-page>
            <form-error-page>/pages/logonError.jsp</form-error-page>
        </form-login-config>
    </login-config>
There are couple of points in the above snippet that needs to be explained. First - this particular case uses form based authentication. Second is the use of realm-name. This need to match up with the name of realm that is configured in Glassfish AS using Glassfish admin console. In this particular case, we are using a file realm named SecureWebFileRealm. Realm.jpg

STEP 4: Next, in web.xml specify security constraint that defines the mechanism to protect the web content. This is accomplished by using the security-constraint element of web.xml
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>RoleBasedAccessControl</web-resource-name>
            <url-pattern>/trans/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>PUT</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>Transactional</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>RoleBasedAccessControl</web-resource-name>
            <url-pattern>/gen/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>PUT</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>General</role-name>
        </auth-constraint>
    </security-constraint>
Here the authorization constraint is specified such that the role Transactional can access URL pattern /trans/* and the role General can access URL pattern /gen/*. Technically we could have specified the role name as * for the URL pattern /gen/*, which would allow any role to access this URL pattern.

STEP 5: Next, the security role mapping needs to be specified in sun-web.xml. While using Netbeans as IDE, there is an aspect that one need to be aware of. If the role name were specified in web.xml using the security-role element and appropriately linked using security-role-ref element then Netbeans is smart enough to figure out the security role mapping.
    <servlet>
        <servlet-name>Transact</servlet-name>
        <servlet-class>com.test.web.TransactionalServlet</servlet-class>
        <security-role-ref>
            <role-name>Transactional</role-name>
            <role-link>Transactional</role-link>
        </security-role-ref>
    </servlet>
 ....
     <security-role>
         <role-name>Transactional</role-name>
    </security-role>
Inorder to complete the mapping one needs to create the Master List of Groups by clicking the Add Group button on the following screen. Groups.jpg

Of course, the Group name should be the ones that were used while creating users using the Glassfish Admin console. GroupsCreate.jpg

Once this is done, the next step is to do Role Assignments!!!! RoleMapping.jpg

After this assignment, The following XML entries are added to sun-web.xml
  <security-role-mapping>
    <role-name>Transactional</role-name>
    <group-name>TransGroup</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>General</role-name>
    <group-name>General</group-name>
  </security-role-mapping>
However if one were to use Annotation like we had defined earlier, the sun-web.xml doesn't seem to reflect the Security Role Mapping. In fact, if one were to add the security role mapping explicitly by editing the file using a text editor, then one could run into the danger of overwriting the security-role-mapping.

STEP 6: Done! Accessing the URL (http://localhost:8080/testing/trans/Transact) will prompt for login (redirected to login.jsp specified in web.xml) Logon.jpg
Logging in as user test1 that belongs to groups - TransactGroup and General - results in Transactional page. However logging in as test2 that belongs only to the group - General - results in a HTTP 403 (Not Authorized) which is subsequently redirected to a NotAuthorized page (HTTP 403 is mapped to this page in web.xml)

Logging in as user - test1 which belongs to group - General, TransactGroup
TransactionalPage.jpg
Logging in as user - test2 which belongs to group - General
TransactionalPage2.jpg

Enjoy!
Related Topics >> J2EE      
Comments
Comments are listed in date ascending order (oldest first)