The JBoss Security Model


Similar to the rest of the JBoss architecture, security at the lowest level is defined as a set of interfaces for which alternate implementations may be provided. Three basic interfaces define the JBoss server security layer: org.jboss.security.AuthenticationManager, org.jboss.security.RealmMapping, and org.jboss.security.SecurityProxy. Figure 8.8 shows a class diagram of the security interfaces and their relationship to the EJB container architecture.

Figure 8.8. The key security model interfaces and their relationship to the JBoss server EJB container elements.


The shaded classes in Figure 8.8 represent the security interfaces, whereas the nonshaded classes represent the EJB container layer. The two interfaces required for the implementation of the J2EE security model are org.jboss.security.AuthenticationManager and org.jboss.security.RealmMapping. The roles of the security interfaces presented in Figure 8.8 are summarized in the following list:

  • AuthenticationManager This is an interface that is responsible for validating credentials associated with principals. Principals are identities; examples of principals include usernames, employee numbers, and Social Security numbers. Credentials are proof of the identity; examples of credentials include passwords, session keys, and digital signatures. You invoke the isValid method to determine whether a user identity and associated credentials, as known in the operational environment, are valid proof of the user's identity.

  • RealmMapping This is an interface that is responsible for principal mapping and role mapping. The getPrincipal method takes a user identity, as known in the operational environment, and returns the application domain identity. The doesUserHaveRole method validates that the user identity in the operational environment has been assigned the indicated role from the application domain.

  • SecurityProxy This is an interface that describes the requirements for a custom SecurityProxyInterceptor plug-in. A SecurityProxy allows for the externalization of custom security checks on a per-method basis for both the EJB home and remote interface methods.

  • SubjectSecurityManager This is a subinterface of AuthenticationManager that simply adds accessor methods for obtaining the security domain name of the security manager and the current thread's authenticated Subject.

  • SecurityDomain This is an extension of the AuthenticationManager, RealmMapping, and SubjectSecurityManager interfaces. It is a move to a comprehensive security interface based on the JAAS Subject, a java.security.KeyStore, and the JSSE com.sun.net.ssl.KeyManagerFactory and com.sun.net.ssl.TrustManagerFactory interfaces. This interface is a work in progress that will be the basis of a multi-domain security architecture that will better support ASP-style deployments of applications and resources.

Note that the AuthenticationManager, RealmMapping, and SecurityProxy interfaces have no association to JAAS-related classes. Although the JBossSX framework is heavily dependent on JAAS, the basic security interfaces required for implementation of the J2EE security model are not. The JBossSX framework is simply an implementation of the basic security plug-in interfaces that are based on JAAS. The component diagram presented in Figure 8.9 illustrates this fact. The implication of this plug-in architecture is that you are free to replace the JAAS-based JBossSX implementation classes with your own custom security manager implementation that does not make use of JAAS, if you so desire. You'll see how to do this when you look at the JBossSX MBeans available for the configuration of JBossSX in Figure 8.9.

Figure 8.9. The relationship between the JBossSX framework implementation classes and the JBoss server EJB container layer.


Enabling Declarative Security in JBoss, Revisited

Earlier in this chapter, the discussion of the J2EE standard security model ends with a requirement for the use of JBoss server-specific deployment descriptor to enable security. The details of this configuration are presented here because they are part of the generic JBoss security model. Figure 8.10 shows the JBoss-specific EJB and web application deployment descriptor's security-related elements.

Figure 8.10. The security element subsets of the JBoss server jboss.xml and jboss-web.xml deployment descriptors.


The value of a security-domain element specifies the JNDI name of the security manager interface implementation that JBoss uses for the EJB and web containers. This is an object that implements both the AuthenticationManager and RealmMapping interfaces. When specified as a top-level element, it defines what security domain is in effect for all EJBs in the deployment unit. This is the typical usage because mixing security managers within a deployment unit complicates inter-component operation and administration.

To specify the security domain for an individual EJB, you specify the security-domain at the container configuration level. This overrides any top-level security-domain element.

The unauthenticated-principal element specifies the name to use for the Principal object returned by the EJBContext.getUserPrincipal method when an unauthenticated user invokes an EJB. Note that this conveys no special permissions to an unauthenticated caller. Its primary purpose is to allow unsecured servlets and JSP pages to invoke unsecured EJBs and allow the target EJB to obtain a non-null Principal for the caller, using the getUserPrincipal method. This is a J2EE specification requirement.

The security-proxy element identifies a custom security proxy implementation that allows per-request security checks outside the scope of the EJB declarative security model, without requiring you to embed security logic into the EJB implementation. This may be an implementation of the org.jboss.security.SecurityProxy interface or just an object that implements methods in the home, remote, local home, or local interfaces of the EJB to secure without implementing any common interface. If the given class does not implement the SecurityProxy interface, the instance must be wrapped in a SecurityProxy implementation that delegates the method invocations to the object. The org.jboss.security.SubjectSecurityProxy is an example of a SecurityProxy implementation that is used by the default JBossSX installation.

Let's take a look at a simple example of a custom SecurityProxy in the context of a trivial stateless session bean. The custom SecurityProxy validates that no one invokes the bean's echo method with a four-letter word as its argument. This is a check that is not possible with role-based security; you cannot define a FourLetterEchoInvoker role because the security context is the method argument, not a property of the caller. The code for the custom SecurityProxy is given in Listing 8.8, and the full source code is available in the src/main/org/jboss/chap8/ex1 directory of the book examples.

Listing 8.8. The Example 1 Custom EchoSecurityProxy Implementation That Enforces the echo Argument-Based Security Constraint
 CallbackHandler handler = new MyHandler(); LoginContext lc = new LoginContext("some-config", handler); try {     lc.login();     Subject subject = lc.getSubject(); } catch(LoginException e) {     System.out.println("authentication failed");     e.printStackTrace(); } // Perform work as authenticated Subject // ... // Scope of work complete, log out to remove authentication info try {     lc.logout(); } catch(LoginException e) {     System.out.println("logout failed");     e.printStackTrace(); } // A sample MyHandler class class MyHandler     implements CallbackHandler {     public void handle(Callback[] callbacks) throws         IOException, UnsupportedCallbackException     {         for (int i = 0; i < callbacks.length; i++) {             if (callbacks[i] instanceof NameCallback) {                 NameCallback nc = (NameCallback)callbacks[i];                 nc.setName(username);             } else if (callbacks[i] instanceof PasswordCallback) {                 PasswordCallback pc = (PasswordCallback)callbacks[i];                 pc.setPassword(password);             } else {                 throw new UnsupportedCallbackException(callbacks[i],                                                        "Unrecognized Callback");             }         }     } } 

EchoSecurityProxy checks that the method to be invoked on the bean instance corresponds to the echo(String) method that was looked up in the init method. If there is a match, the method argument is obtained, and its length is compared against 4 or null. Either case results in a SecurityException being thrown. Certainly, this is a contrived example, but only in its application. It is a common requirement that applications must perform security checks based on the value of method arguments. The point of the example is to demonstrate how you can introduce custom security beyond the scope of the standard declarative security model, independently of the bean implementation. This allows the specification and coding of the security requirements to be delegated to security experts. Because the security proxy layer can be done independently of the bean implementation, security can be changed to match the deployment environment requirements.

Listing 8.9 shows the associated jboss.xml descriptor that installs EchoSecurityProxy as the custom proxy for EchoBean.

Listing 8.9. The jboss.xml Descriptor, Which Configures EchoSecurityProxy as the Custom Security Proxy for EchoBean
 <jboss>     <security-domain>java:/jaas/other</security-domain>     <enterprise-beans>         <session>             <ejb-name>EchoBean</ejb-name>             <security-proxy>org.jboss.chap8.ex1.EchoSecurityProxy</security-proxy>         </session>     </enterprise-beans> </jboss> 

Now you can test the custom proxy by running a client that attempts to invoke the EchoBean.echo method with the arguments Hello and Four, as illustrated in this fragment:

 public class ExClient {     public static void main(String args[])         throws Exception     {         Logger log = Logger.getLogger("ExClient");         log.info("Looking up EchoBean");         InitialContext iniCtx = new InitialContext();         Object ref = iniCtx.lookup("EchoBean");         EchoHome home = (EchoHome) ref;         Echo echo = home.create();         log.info("Created Echo");         log.info("Echo.echo('Hello') = "+echo.echo("Hello"));         log.info("Echo.echo('Four') = "+echo.echo("Four"));     } } 

The first call should succeed, and the second should fail due to the fact that Four is a four-letter word. You can run the client as follows, using Ant from the examples directory:

[View full width]

[examples]$ ant -Dchap=chap8 -Dex=1 run-example run-example1: [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy [echo] Waiting for 5 seconds for deploy... [java] [INFO,ExClient] Looking up EchoBean [java] [INFO,ExClient] Created Echo [java] [INFO,ExClient] Echo.echo('Hello') = Hello [java] Exception in thread "main" java.rmi.ServerException:RemoteException occurred in server thread; nested exception is: [java] java.rmi.AccessException: SecurityException; nested exception is: [java] java.lang.SecurityException: No 4 letter words ... [java] at org.jboss.chap8.ex1.ExClient.main(ExClient.java:25) [java] Caused by: java.rmi.AccessException: SecurityException;nested exception is: [java] java.lang.SecurityException: No 4 letter words ...

The result is that the echo('Hello') method call succeeds, as expected, and the echo('Four') method call results in a rather messy-looking exception, which is also expected. (The preceding output has been truncated to fit in the book.)

The key part to the exception is that the SecurityException("No 4 letter words") generated by the EchoSecurityProxy was thrown to abort the attempted method invocation, as desired.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net