This article describes my tests with ejb and JBoss7.
For my test a have ear (TestEar) with one ejb module (TestEjb) and one bean (TestBean).
TestEar.ear +---TestEjb.ejb +--mates.test.TestBean.class mates.test.TestBeanRemote.class
As security I use RealmUsersRoles with
x-users.properties
testX=test1234
x-roles.properties
testX=bean
And now standalone.xml
and I changed ApplicationRealm
<security-realm name="ApplicationRealm"> <authentication> <jaas name="bean-sec-domain"/> </authentication> </security-realm>
and security domain
<security-domain name="bean-sec-domain" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="defaultUsersProperties" value="file:/${jboss.server.config.dir}/x-users.properties"/> <module-option name="defaultRolesProperties" value="file:/${jboss.server.config.dir}/x-roles.properties"/> <module-option name="usersProperties" value="file:/${jboss.server.config.dir}/x-users.properties"/> <module-option name="rolesProperties" value="file:/${jboss.server.config.dir}/x-roles.properties"/> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain>
And now lets look at bean.
@Stateless @DeclareRoles("bean") public class TestBean implements TestBeanRemote { @Resource private EJBContext context; @Override @RolesAllowed("bean") public String getName () { return getNameFree(); } @Override public String getNameFree () { String aName = ""; if (context.getCallerPrincipal() != null) { aName = context.getCallerPrincipal().getName(); } return "name " + aName + " " + context.isCallerInRole("bean"); } }
Let's secure EJB
add jboss-app.xml to TestEar.ear\META-INF. I use security domain other to ensure that i secure all beans.
<?xml version="1.0" encoding="UTF-8"?> <p:jboss-app xmlns:p="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee ../../xsd/jboss-app_7_0.xsd "> <security-domain>other</security-domain> </p:jboss-app>
And I want to secure TestBean. I have to add jboss-ejb3.xml to TestEjb.jar\META-INF\. TestBean is secured by bean-sec-domain.
<?xml version="1.0" encoding="UTF-8"?> <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="urn:security" version="3.1" impl-version="2.0"> <assembly-descriptor xmlns="http://java.sun.com/xml/ns/javaee"> <security:security xmlns:security="urn:security"> <security:security-domain>bean-sec-domain</security:security-domain> <ejb-name>TestBean</ejb-name> </security:security> </assembly-descriptor> </jboss:ejb-jar>
Remote interface is real simple with 2 methods.
Client:
Hashtable<String, Object> p = new Hashtable<String, Object>(); p.put(Context.INITIAL_CONTEXT_FACTORY, InitialContextFactory.class.getName()); p.put(Context.PROVIDER_URL, "remote://127.0.0.1:4447/"); p.put(InitialContext.SECURITY_PRINCIPAL, "testX"); p.put(InitialContext.SECURITY_CREDENTIALS, "test1234"); p.put("jboss.naming.client.ejb.context", true); p.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); InitialContext c = new InitialContext(p); TestBeanRemote vLookup = (TestBeanRemote) c.lookup("java:/TestEar/TestEjb/TestBean!"+ TestBeanRemote.class.getName()); System.out.println("x" + vLookup.getNameFree()); System.out.println("x" + vLookup.getName());
After this you can see
xname testX true xsecured name testX true
That's all.
And now some other tests:
Most important mart is
p.put("jboss.naming.client.ejb.context", true);
without this property you will see "No EJB receiver available for handling [appName:TestEar,modulename:TestEjb,distinctname:] combination"
when you put in class path file jboss-ejb-client.properties with standard
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=x1 remote.connection.x1.host=127.0.0.1 remote.connection.x1.port = 4447 remote.connection.x1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false remote.connection.x1.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
and comment p.put("jboss.naming.client.ejb.context", true);
and in console is now
xname $local false Exception in thread "main" javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public abstract java.lang.String mates.test.TestBeanRemote.getName() of bean: TestBean is not allowed
jboss.naming.client.ejb.context setup EJBContext on client side. See org.jboss.naming.remote.client.InitialContextFactory
Comments