Using JACC to determine a caller's roles

The following technique is supported by all JACC compatible containers given that they are configured with a typical Policy provider capable of returning a PermissionCollection encapsulating all the WebRoleRefPermission and/or EJBRoleRefPermission objects pertaining to a ProtectionDomain.

  • Within the scope of a called Servlet or EJB that is configured to run as its caller, invoke the "Container Subject Policy Context Handler" to obtain a Subject containing the principals of the caller. Note that the handler will return null if the caller identity has not been established.
    	private static final String SUBJECT_HANDLER_KEY =
    	Subject s = (Subject) PolicyContext.getContext(SUBJECT_HANDLER_KEY);
  • Extract the principals of the caller from the Subject, and use the 4 argument ProtectionDomain constructor to construct a ProtectionDOmain for the caller of the component. If the Subject is null, use a zero-length Principal array to construct the ProtectionDomain.
    	CodeSource cs = new CodeSource(null, ([]) null);
    	Principal principals[] = (s == null ? new Principal[0] : s.getPrincipals().toArray(new Principal[0]));
    	ProtectionDomain pd = new ProtectionDomain(cs, null, null, principals);
  • Get the Policy object of the JRE, and call policy.getPermissions() with the ProtectionDomain as argument. The returned PermissionCollection will include all the Permissions granted to the caller; including those (i.e., EJBRoleRefPermission(s) and WebRoleRefPermission(s)) indicating role memberships. Depending on the underlying Policy implementation, the returned collection may contain "unresolved" permissions which will need to be resolved in order to be detectable by the selection logic in the next step. Force resolution by calling implies on the collection with an argument permission of the desired type (i.e. a WebRoleRefPermission or an EJBRoleRefPermission).
    	Policy policy = Policy.getPolicy();
    	PermissionCollection pc = policy.getPermissions(pd);
            pc.implies(new WebRoleRefPermission(null, null));
  • Iterate over the permissions and select the WebRoleRefPermissions or EJBRoleRefPermissions granted to the caller. Each such permission indicates that the caller is a member of a role (identified by the actions of the permission) in the context of the named Servlet or EJB as (identified by the name of the permission). Select only those Permissions corresponding to the type of the component (Servlet or EJB) in which the roles of the caller are being determined. Return an array of String values containing the the set of all unique action values for which HttpServlet.isUserInRole(action) or EJBContext.isCallerInRole(action) returns true. The following sample demonstrates the role computation in the context of a named Servlet. The analogous computation is performed in the context of a named EJB, by substituting EJBRoleRefPermission for WebRoleRefPermission, and EJBContext.isCallerInRole for HttpServletRequest.isUSerInRole.
            HashSet roleSet = null;
    	HttpServletRequest request; //assign to current request
            Enumeration e = pc.elements();
            while (e.hasMoreElements()) {
                Permission p = e.nextElement();
                if (p instanceof WebRoleRefPermission) {
                    String roleRef = p.getActions();
                    if (roleSet == null) {
                        roleSet = new HashSet();
                    //confirm roleRef via isUserInRole to ensure proper scoping to Servlet Name
                    if (!roleSet.contains(roleRef) && request.isUserInRole(roleRef)) {
    	if (roleSet != null) {
                return roleSet.toArray(new String[0]);
            return new String[0];
    Note that the returned values will correspond to role reference values; which are values that may be used by the application to test role membership. These values may differ from the names of application roles if the application has defined security-role-ref elements. If no security-role-ref elements have been defined, the role reference values will correspond exactly to the names of the application roles.
  • When running with a SecurityManager enabled, the calling code must be granted permission to call the PolicyContext.getContext and the Policy.getPolicy methods. This can be facilitated by encapsulating these protected methods in a doPrivileged, and by loading this utility code within a CodeBase for which the necessary permissions can be conveniently granted. For Glassfish, this can be done by packaging the utility in its own jar and placing the jar in glassfish/lib.


    Thanks. Just what I needed.

    Posted by Remy Monsen on February 16, 2009 at 10:43 AM EST #

    Can it be applied to Weblogic server? Actually I am using Weblogic server and trying to implement the same, but not getting the handler.

    Posted by Tanmay Kumar Dhar on June 27, 2010 at 05:45 PM EDT #

    WLS is a Java EE compatible application server, so it must support the above technique, but I believe you must do some additional configuration to enable the use of JACC in WLS. see

    Posted by guest on July 07, 2010 at 03:12 AM EDT #

    This technique also assumes that the Subject policy context handler is left populated with data after the control returns the application code.

    I'm not certain this will be the case for all containers. I've seen situations where other pieces of JACC context information in WebSphere aren't kept around after the container invokes the configured JACC provider, so the Subject policy context handler may not return the expected data.

    Just an FYI :)

    Posted by Craig on July 30, 2010 at 11:26 AM EDT #

    Post a Comment:
    • HTML Syntax: NOT allowed



    « April 2014