| = 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. |