DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Java
  4. Security Features of JBoss AS 5.1 - Part 3 - XACML authorization for EJB Applications

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

Anil Saldanha user avatar by
Anil Saldanha
·
Jun. 19, 09 · Interview
Like (0)
Save
Tweet
Share
15.97K Views

Join the DZone community and get the full member experience.

Join For Free

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

XACML application security authentication JBoss Java EE Open source

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 10 Best Practices for Web Application Testing
  • How To Build a Spring Boot GraalVM Image
  • Secure APIs: Best Practices and Measures
  • Apache Kafka Is NOT Real Real-Time Data Streaming!

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: