Anil Saldhana is the Lead Identity Management Architect at JBoss. He blogs at http://anil-identity.blogspot.com Anil has posted 16 posts at DZone. You can read more from them at their website. View Full User Profile

Security Features of JBoss AS 5.1 - Part 3 - XACML authorization for EJB Applications

06.19.2009
| 12920 views |
  • submit to reddit

Oasis XACML v2.0 is a robust open standard catering to access control. Starting JBoss Application Server v5.0, users have the opportunity to use XACML as container authorization mechanism for EJBs similar to JACC or the EJB role based access control. 

This article will focus on JBoss Application Server v5.1.0.

In this article, we will take a look at an EJB2 application (attached to this article) and use XACML as the authorization mechanism.

Assumptions

This article assumes that the reader is familiar with EJB Container security and the deployment descriptors such as ejb-jar.xml. This article is catered toward advanced users of JBoss AS.

 

Why is there a need for XACML in Java EE?

The Java EE specifications offer coarse grained security that is based on roles.  If an user wishes to apply fine grained access control to Java EE components such as the web or ejb applications, then he needs to look at non-standard ways of doing it. JACC (JSR-115) is an authorization specification that is mandated in the Java EE world, since v1.4 but it is a specification that is tied to the web and ejb standard deployment descriptors, to provide the authorization support.

 If the users wish to provide fine grained authorization in the containers, that may be tied to some context, then they will probably have to get away from container security and write their own via servlet filters or some type of server interceptors.

 Some examples of container authorization that can be tied to business context are:

  1. Allow access to this web resource to employees who are active and between the business hours of 9am-5pm on Mondays through Thursday and 9am -2pm on Fridays and no access on weekends.
  2. Do not allow access to this EJB application from this particular subnet.

 

Limitations of application of XACML in Java EE

  1. The feature is an extension of security provided by JavaEE. So in some ways, it is a non-standard behavior.
  2. There are no standard xacml attributes for EJBs. So there is a need for custom schema from the vendor.

 

Step 1: Let us take a look at the ejb-jar deployment descriptor.

 

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">

<enterprise-beans>
<session>
<description>A secured stateless session bean</description>
<ejb-name>StatelessSession</ejb-name>
<home>org.jboss.test.security.interfaces.StatelessSessionHome</home>
<remote>org.jboss.test.security.interfaces.StatelessSession</remote>
<ejb-class>org.jboss.test.security.ejb.StatelessSessionBean4</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>

<assembly-descriptor>
<security-role>
<role-name>CallerInfoFacadeRole</role-name>
</security-role>
<security-role>
<role-name>CallerInfoStatelessRole</role-name>
</security-role>
<security-role>
<role-name>CallerInfoStatefulRole</role-name>
</security-role>
<security-role>
<role-name>CallerInfoEntityRole</role-name>
</security-role>

<method-permission>
<role-name>CallerInfoStatelessRole</role-name>
<method>
<ejb-name>StatelessSession</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>

 

The jboss.xml will basically define the security domain to be used by this ejb application.

<?xml version="1.0"?>
<!DOCTYPE jboss PUBLIC
"-//JBoss//DTD JBOSS 4.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
<jboss>
<security-domain>java:/jaas/xacml-test</security-domain>
<enterprise-beans>
<session>
<ejb-name>StatelessSession</ejb-name>
<jndi-name>spec.StatelessSession</jndi-name>
</session>
</enterprise-beans>
</jboss>

 

Step 2: Define the security domain configuration in a xxx-jboss-beans.xml (In our case, we will call the file ejbxacml-jboss-beans.xml)

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

<deployment xmlns="urn:jboss:bean-deployer:2.0">

<application-policy xmlns="urn:jboss:security-beans:1.0" name="xacml-test">
<authentication>
<login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
flag = "required">
</authentication>

<authorization>
<policy-module code="org.jboss.security.authorization.modules.XACMLAuthorizationModule" flag="required" />
</authorization>
</application-policy>

</deployment>


Step 3
:  Define the JBossXACML configuration file

<ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0">
<ns:Policies>
<ns:Policy>
<ns:Location>META-INF/jboss-xacml-policy.xml</ns:Location>
</ns:Policy>
</ns:Policies>
<ns:Locators>
<ns:Locator Name="org.jboss.security.xacml.locators.JBossPolicySetLocator"/>
<ns:Locator Name="org.jboss.security.xacml.locators.JBossPolicyLocator"/>
</ns:Locators>
</ns:jbosspdp>

 

Step 4: Define a standard XACML policy file governing your ejb application.

 

<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os
access_control-xacml-2.0-policy-schema-os.xsd"
PolicyId="urn:oasis:names:tc:xacml:2.0:jboss-test:XV:policy"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">
<Description> Policy for Subject RBAC</Description>
<Target/>
<Rule RuleId="urn:oasis:names:tc:xacml:2.0:jboss-test:XVI:rule"
Effect="Permit">
<Description>
scott can create,remove and invoke echo method of StatelessSession EJB when
he has a role of ProjectUser
</Description>
<Target>
<Subjects>
<Subject>
<SubjectMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">scott</AttributeValue>
<SubjectAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</SubjectMatch>
<SubjectMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">ProjectUser</AttributeValue>
<SubjectAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</SubjectMatch>
</Subject>
</Subjects>
<Resources>
<Resource>
<ResourceMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">StatelessSession</AttributeValue>
<ResourceAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</ResourceMatch>
</Resource>
</Resources>
<Actions>
<Action>
<ActionMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">create</AttributeValue>
<ActionAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</ActionMatch>
</Action>
<Action>
<ActionMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">remove</AttributeValue>
<ActionAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</ActionMatch>
</Action>
<Action>
<ActionMatch
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">echo</AttributeValue>
<ActionAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</ActionMatch>
</Action>
</Actions>
</Target>
</Rule>
</Policy>

Generation of XACML policy files is a tough task in the absence of good xacml policy editors (which unfortunately is the current status in the open source world). Hopefully the future should be better with open source tools propping up for xacml policy editing.

 

Step 5: Package your ejb application

Mainly the xml configuration files go into META-INF of the ejb-jar

 

Step 6: Take a look at the test java code. It is straight ejb client code (of course, disguised as a JUnit test case). No sign of any xacml related code.

package org.jboss.test.security.test.authorization;

import java.rmi.RemoteException;

import javax.rmi.PortableRemoteObject;
import javax.security.auth.login.LoginContext;

import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestSuite;

import org.jboss.test.JBossTestCase;
import org.jboss.test.JBossTestSetup;
import org.jboss.test.security.interfaces.StatelessSession;
import org.jboss.test.security.interfaces.StatelessSessionHome;
import org.jboss.test.util.AppCallbackHandler;


public class XACMLEJBIntegrationUnitTestCase extends JBossTestCase
{

static String username = "scott";

static char[] password = "echoman".toCharArray();

LoginContext lc;

boolean loggedIn;

private static String login_config = "security/authorization/xacml-ejb/app-policy-service.xml";

public XACMLEJBIntegrationUnitTestCase(String name)
{
super(name);
}

public static Test suite() throws Exception
{
TestSuite suite = new TestSuite();
suite.addTest(new TestSuite(XACMLEJBIntegrationUnitTestCase.class));
// Create an initializer for the test suite
TestSetup wrapper = new JBossTestSetup(suite)
{
@Override
protected void setUp() throws Exception
{
super.setUp();
deploy("xacml-ejb.jar");
deploy(getResourceURL(login_config));
}

@Override
protected void tearDown() throws Exception
{
undeploy(getResourceURL(login_config));
undeploy("xacml-ejb.jar");
super.tearDown();
}
};
return wrapper;
}

/**
* Test that the echo method is accessible by an Echo role. Since the noop() method of the StatelessSession bean was
* not assigned any permissions it should be unchecked.
*/
public void testMethodAccess() throws Exception
{
log.debug("+++ testMethodAccess");
process();
}

private void process() throws Exception
{
login();
Object obj = getInitialContext().lookup("spec.StatelessSession");
obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
StatelessSessionHome home = (StatelessSessionHome) obj;
log.debug("Found StatelessSessionHome");
StatelessSession bean = home.create();
log.debug("Created spec.StatelessSession");
log.debug("Bean.echo('Hello') -> " + bean.echo("Hello"));

try
{
// This should not be allowed
bean.noop();
fail("Was able to call StatelessSession.noop");
}
catch (RemoteException e)
{
log.debug("StatelessSession.noop failed as expected");
}
bean.remove();
logout();
}

/**
* Login as user scott using the conf.name login config or 'spec-test' if conf.name is not defined.
*/
private void login() throws Exception
{
login(username, password);
}

private void login(String username, char[] password) throws Exception
{
if (loggedIn)
return;

lc = null;
String confName = System.getProperty("conf.name", "spec-test");
AppCallbackHandler handler = new AppCallbackHandler(username, password);
log.debug("Creating LoginContext(" + confName + ")");
lc = new LoginContext(confName, handler);
lc.login();
log.debug("Created LoginContext, subject=" + lc.getSubject());
loggedIn = true;
}

private void logout() throws Exception
{
if (loggedIn)
{
loggedIn = false;
lc.logout();
}
}
}

 

About the Author

Anil Saldhana is the lead security architect at JBoss. He blogs at http://anil-identity.blogspot.com

Legacy
Article Resources: 
Published at DZone with permission of its author, Anil Saldhana.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

sub online replied on Fri, 2009/06/26 - 2:36am

go for it.Play dumb. Don't play dumb. You know about that.Tiffany JewelleryHow do I say this? It's so hard to explain How do I say this? What do you mean? I'm feeling sorry for him. What do you mean?Have you seen that movie 'Friday the 13th'? It's so sick.links of londonLooking for trouble.Is it too late? Can we make it?I need it badly.links of londonAre you finished? Are you done with that!It's not my fault.How dare you stand me up.Leave it up to me.Don't you have a heart!

Grent Sill replied on Fri, 2010/04/02 - 1:40pm

Strange using this code with another UTF 16 all the characters are changed...

Miglior Hosting | Information Security Forum

Dan Vo replied on Thu, 2010/07/29 - 7:39pm

Hi Anil, I'm confused to say the least. My questions are
1. In the test code you deploy an extra file (app-policy-service.xml) which is not mentioned anywhere. What is its purpose? Is it any different than ejbxacml-jboss-beans.xml?
2. In the test code nothing explains how the login context config name "spec-test" is defined
3. It seems you have both a role based authorization (method-permission entry in ejb-jar.xml) and xacml based authorization (XACMLAuthorizationModule module under the application policy's authorization tag of ejbxacml-jboss-beans.xml). How would both of these work together?
More explanation is appreciated

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.