blob: 86c6e3c65cad375b279ebd5b9e8e93b9bd43b204 [file] [log] [blame]
= Simple Remote Tomcat Users
:index-group: Security
:jbake-type: page
:jbake-status: published
This is an example on how to use JNDI with security restrictions in TomEE.
== Contract
In our example Contract is an interface annotated with @Remote which indicates that all methods of this interface can be accessed by client code.
[source,java]
----
@Remote
public interface Contract {
String hi();
}
----
== ContractImpl
ContractImpl is a concrete implementation of the Contract interface restricting access to the hi method for users with role test.
[source,java]
----
public class ContractImpl implements Contract {
@Override
@RolesAllowed("test")
public String hi() {
return "hi";
}
}
----
== ContractTest
In this class we test the correctness of our application with Arquillian by creating a war with Contract and ContractImpl classes and deploying to
an embedded TomEE server with the war name test.war. In arquillian.xml we specify that arquillian pick tomcat-users.xml from src/test/conf folder.
In tomcat-users.xml there is a single user with username "tomcat", password="users" and role "test".
To test we lookup for the ContractImpl and call the hi method using different usernames and passwords.
[source,java]
----
@RunWith(Arquillian.class)
public class ContractTest {
@Deployment(testable = false)
public static Archive<?> app() {
return ShrinkWrap.create(WebArchive.class, "test.war")
.addClasses(Contract.class, ContractImpl.class);
}
@ArquillianResource
private URL base;
@Test
public void valid() throws NamingException {
assertEquals("hi", hi(new Properties() {{
setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
setProperty(Context.PROVIDER_URL, String.format("http://localhost:%s/tomee/ejb", base.getPort()));
setProperty(Context.SECURITY_PRINCIPAL, "tomcat");
setProperty(Context.SECURITY_CREDENTIALS, "users");
}}));
}
@Test
public void invalid() throws NamingException {
try {
hi(new Properties() {{
setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
setProperty(Context.PROVIDER_URL, String.format("http://localhost:%s/tomee/ejb", base.getPort()));
setProperty(Context.SECURITY_PRINCIPAL, "tomcat");
setProperty(Context.SECURITY_CREDENTIALS, "wrong");
}});
fail();
} catch (final AuthenticationException ae) {
// ok
}
}
@Test
public void missingCredentials() throws NamingException {
try {
hi(new Properties() {{
setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
setProperty(Context.PROVIDER_URL, String.format("http://localhost:%s/tomee/ejb", base.getPort()));
}});
fail();
} catch (final EJBAccessException eae) {
// no-op
}
}
private String hi(final Properties clientConfig) throws NamingException {
return Contract.class.cast(new InitialContext(clientConfig).lookup("java:global/test/ContractImpl!org.superbiz.Contract")).hi();
}
}
----
== Run the application:
mvn install
All test cases will pass.