Edition 5.1.2
/usr/sbin/alternatives Utility Mono-spaced Bold
To see the contents of the filemy_next_bestselling_novelin your current working directory, enter thecat my_next_bestselling_novelcommand at the shell prompt and press Enter to execute the command.
Press Enter to execute the command.Press Ctrl+Alt+F2 to switch to the first virtual terminal. Press Ctrl+Alt+F1 to return to your X-Windows session.
mono-spaced bold. For example:
File-related classes includefilesystemfor file systems,filefor files, anddirfor directories. Each class has its own associated set of permissions.
Choose → → from the main menu bar to launch Mouse Preferences. In the Buttons tab, click the Left-handed mouse check box and click to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand).To insert a special character into a gedit file, choose → → from the main menu bar. Next, choose → from the Character Map menu bar, type the name of the character in the Search field and click . The character you sought will be highlighted in the Character Table. Double-click this highlighted character to place it in the Text to copy field and then click the button. Now switch back to your document and choose → from the gedit menu bar.
Mono-spaced Bold Italic or Proportional Bold Italic
To connect to a remote machine using ssh, typesshat a shell prompt. If the remote machine isusername@domain.nameexample.comand your username on that machine is john, typessh john@example.com.Themount -o remountcommand remounts the named file system. For example, to remount thefile-system/homefile system, the command ismount -o remount /home.To see the version of a currently installed package, use therpm -qcommand. It will return a result as follows:package.package-version-release
Publican is a DocBook publishing system.
mono-spaced roman and presented thus:
books Desktop documentation drafts mss photos stuff svn books_tests Desktop1 downloads images notes scripts svgs
mono-spaced roman but add syntax highlighting as follows:
package org.jboss.book.jca.ex1; import javax.naming.InitialContext; public class ExClient { public static void main(String args[]) throws Exception { InitialContext iniCtx = new InitialContext(); Object ref = iniCtx.lookup("EchoBean"); EchoHome home = (EchoHome) ref; Echo echo = home.create(); System.out.println("Created Echo"); System.out.println("Echo.echo('Hello') = " + echo.echo("Hello")); } }
JBoss Enterprise Application Platform 5 and the component doc-JBoss_Security_Guide. The following link will take you to a pre-filled bug report for this product: http://bugzilla.redhat.com/.
Description field. Be as specific as possible when describing the issue; this will help ensure that we can fix it quickly.
Document URL: Section Number and Name: Describe the issue: Suggestions for improvement: Additional information:
ejb-jar.xml and web.xml deployment descriptors. The following sections look at the purpose and usage of the various security elements.

role-nameType attribute value as an argument to the isCallerInRole(String) method. By using the isCallerInRole method, a component can verify whether the caller is in a role that has been declared with a <security-role-ref> or <role-name> element. The <role-name> element value must link to a <security-role> element through the <role-link> element. The typical use of isCallerInRole is to perform a security check that cannot be defined by using the role-based <method-permissions> elements.
ejb-jar.xml file.
<!-- A sample ejb-jar.xml fragment --> <ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> ... <security-role-ref> <role-name>TheRoleICheck</role-name> <role-link>TheApplicationRole</role-link> </security-role-ref> </session> </enterprise-beans> ... </ejb-jar>
<web-app> <servlet> <servlet-name>AServlet</servlet-name> ... <security-role-ref> <role-name>TheServletRole</role-name> <role-link>TheApplicationRole</role-link> </security-role-ref> </servlet> ... </web-app>

EJBContext.getCallerPrincipal() method. Rather, the caller's security roles are set to the single role specified by the <run-as> or <role-name> element value.
<!-- A sample ejb-jar.xml fragment --> <ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> <!-- ... --> <security-identity> <use-caller-identity/> </security-identity> </session> <session> <ejb-name>RunAsBean</ejb-name> <!-- ... --> <security-identity> <run-as> <description>A private internal role</description> <role-name>InternalRole</role-name> </run-as> </security-identity> </session> </enterprise-beans> <!-- ... --> </ejb-jar>
anonymous is assigned to all outgoing calls. If you want another principal to be associated with the call, you must associate a <run-as-principal> with the bean in the jboss.xml file. The following fragment associates a principal named internal with RunAsBean from the prior example.
<session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session>
web.xml file. The following example shows how to assign the role InternalRole to a servlet:
<servlet> <servlet-name>AServlet</servlet-name> <!-- ... --> <run-as> <role-name>InternalRole</role-name> </run-as> </servlet>
principal. The <run-as-principal> element is available in the jboss-web.xml file to assign a specific principal to go along with the run-as role. The following fragment shows how to associate a principal named internal to the servlet above.
<servlet> <servlet-name>AServlet</servlet-name> <run-as-principal>internal</run-as-principal> </servlet>

ejb-jar.xml file.
<!-- A sample ejb-jar.xml fragment --> <ejb-jar> <!-- ... --> <assembly-descriptor> <security-role> <description>The single application role</description> <role-name>TheApplicationRole</role-name> </security-role> </assembly-descriptor> </ejb-jar>
web.xml file.
<!-- A sample web.xml fragment --> <web-app> <!-- ... --> <security-role> <description>The single application role</description> <role-name>TheApplicationRole</role-name> </security-role> </web-app>

exclude-list.

<method> <ejb-name>EJBNAME</ejb-name> <method-name>*</method-name> </method>
<method> <ejb-name>EJBNAME</ejb-name> <method-name>METHOD</method-name> </method>
<method> <ejb-name>EJBNAME</ejb-name> <method-name>METHOD</method-name> <method-params> <method-param>PARAMETER_1</method-param> <!-- ... --> <method-param>PARAMETER_N</method-param> </method-params> </method>
<ejb-jar> <assembly-descriptor> <method-permission> <description>The employee and temp-employee roles may access any method of the EmployeeService bean </description> <role-name>employee</role-name> <role-name>temp-employee</role-name> <method> <ejb-name>EmployeeService</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <description>The employee role may access the findByPrimaryKey, getEmployeeInfo, and the updateEmployeeInfo(String) method of the AardvarkPayroll bean </description> <role-name>employee</role-name> <method> <ejb-name>AardvarkPayroll</ejb-name> <method-name>findByPrimaryKey</method-name> </method> <method> <ejb-name>AardvarkPayroll</ejb-name> <method-name>getEmployeeInfo</method-name> </method> <method> <ejb-name>AardvarkPayroll</ejb-name> <method-name>updateEmployeeInfo</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission> <method-permission> <description>The admin role may access any method of the EmployeeServiceAdmin bean </description> <role-name>admin</role-name> <method> <ejb-name>EmployeeServiceAdmin</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <description>Any authenticated user may access any method of the EmployeeServiceHelp bean</description> <unchecked/> <method> <ejb-name>EmployeeServiceHelp</ejb-name> <method-name>*</method-name> </method> </method-permission> <exclude-list> <description>No fireTheCTO methods of the EmployeeFiring bean may be used in this deployment</description> <method> <ejb-name>EmployeeFiring</ejb-name> <method-name>fireTheCTO</method-name> </method> </exclude-list> </assembly-descriptor> </ejb-jar>
@DeclareRoles @RolesAllowed, @PermitAll, and @DenyAll@RunAs web.xml security-constraint element.

NONE, INTEGRAL, and CONFIDENTIAL. A value of NONE means that the application does not require any transport guarantees. A value of INTEGRAL means that the application requires the data sent between the client and server to be sent in such a way that it can not be changed in transit. A value of CONFIDENTIAL means that the application requires the data to be transmitted in a fashion that prevents other entities from observing the contents of the transmission. In most cases, the presence of the INTEGRAL or CONFIDENTIAL flag indicates that the use of SSL is required.

BASIC, DIGEST, FORM, and CLIENT-CERT. The <realm-name> child element specifies the realm name to use in HTTP basic and digest authorization. The <form-login-config> child element specifies the log in as well as error pages that should be used in form-based login. If the <auth-method> value is not FORM, then form-login-config and its child elements are ignored.
/restricted path requires an AuthorizedUser role. There is no required transport guarantee and the authentication method used for obtaining the user identity is BASIC HTTP authentication.
<auth-method>FORM</auth-method> in the <login-config> element of the deployment descriptor, web.xml. The login and error pages are also defined in <login-config>, as follows:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>FormAuthenticator to direct users to the appropriate page. JBoss Enterprise Application Platform maintains a session pool so that authentication information does not need to be present for each request. When FormAuthenticator receives a request, it queries org.apache.catalina.session.Manager for an existing session. If no session exists, a new session is created. FormAuthenticator then verifies the credentials of the session.
/dev/urandom (Linux) by default, and hashed with MD5. Checks are performed at session ID creation to ensure that the ID created is unique.
JSESSIONID. Its value is a hex-string of the session ID. This cookie is configured to be non-persistent. This means that on the client side it will be deleted when the browser exits. On the server side, sessions expire after 60 seconds of inactivity, at which time session objects and their credential information are deleted.
FormAuthenticator caches the request, creates a new session if necessary, and redirects the user to the login page defined in login-config. (In the previous example code, the login page is login.html.) The user then enters their user name and password in the HTML form provided. User name and password are passed to FormAuthenticator via the j_security_check form action.
FormAuthenticator then authenticates the user name and password against the realm attached to the web application context. In JBoss Enterprise Application Platform, the realm is JBossWebRealm. When authentication is successful, FormAuthenticator retrieves the saved request from the cache and redirects the user to their original request.
/j_security_check and at least the j_username and j_password parameters exist.
Subject (javax.security.auth.Subject)
Principal (java.security.Principal)
Callback (javax.security.auth.callback.Callback)
CallbackHandler (javax.security.auth.callback.CallbackHandler)
Configuration (javax.security.auth.login.Configuration)
LoginContext (javax.security.auth.login.LoginContext)
LoginModule (javax.security.auth.spi.LoginModule)
Subject class is the central class in JAAS. A Subject represents information for a single entity, such as a person or service. It encompasses the entity's principals, public credentials, and private credentials. The JAAS APIs use the existing Java 2 java.security.Principal interface to represent a principal, which is essentially just a typed name.
public Set getPrincipals() {...} public Set getPrincipals(Class c) {...}
getPrincipals() returns all principals contained in the subject. getPrincipals(Class c) returns only those principals that are instances of class c or one of its subclasses. An empty set is returned if the subject has no matching principals.
java.security.acl.Group interface is a sub-interface of java.security.Principal, so an instance in the principals set may represent a logical grouping of other principals or groups of principals.
LoginContext and passes in the name of the login configuration and a CallbackHandler to populate the Callback objects, as required by the configuration LoginModules.
LoginContext consults a Configuration to load all the LoginModules included in the named login configuration. If no such named configuration exists the other configuration is used as a default.
LoginContext.login method.
LoginModules. As each LoginModule attempts to authenticate the subject, it invokes the handle method on the associated CallbackHandler to obtain the information required for the authentication process. The required information is passed to the handle method in the form of an array of Callback objects. Upon success, the LoginModules associate relevant principals and credentials with the subject.
LoginContext returns the authentication status to the application. Success is represented by a return from the login method. Failure is represented through a LoginException being thrown by the login method.
LoginContext.getSubject method.
LoginContext.logout method.
LoginContext class provides the basic methods for authenticating subjects and offers a way to develop an application that is independent of the underlying authentication technology. The LoginContext consults a Configuration to determine the authentication services configured for a particular application. LoginModule classes represent the authentication services. Therefore, you can plug different login modules into an application without changing the application itself. The following code shows the steps required by an application to authenticate a subject.
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, logout 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"); } } } }
LoginModule interface. This allows an administrator to plug different authentication technologies into an application. You can chain together multiple LoginModules to allow for more than one authentication technology to participate in the authentication process. For example, one LoginModule may perform user name/password-based authentication, while another may interface to hardware devices such as smart card readers or biometric authenticators.
LoginModule is driven by the LoginContext object against which the client creates and issues the login method. The process consists of two phases. The steps of the process are as follows:
LoginContext creates each configured LoginModule using its public no-arg constructor.
LoginModule is initialized with a call to its initialize method. The Subject argument is guaranteed to be non-null. The signature of the initialize method is: public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
login method is called to start the authentication process. For example, a method implementation might prompt the user for a user name and password and then verify the information against data stored in a naming service such as NIS or LDAP. Alternative implementations might interface to smart cards and biometric devices, or simply extract user information from the underlying operating system. The validation of user identity by each LoginModule is considered phase 1 of JAAS authentication. The signature of the login method is boolean login() throws LoginException. A LoginException indicates failure. A return value of true indicates that the method succeeded, whereas a return value of false indicates that the login module should be ignored.
LoginContext's overall authentication succeeds, commit is invoked on each LoginModule. If phase 1 succeeds for a LoginModule, then the commit method continues with phase 2 and associates the relevant principals, public credentials, and/or private credentials with the subject. If phase 1 fails for a LoginModule, then commit removes any previously stored authentication state, such as user names or passwords. The signature of the commit method is: boolean commit() throws LoginException. Failure to complete the commit phase is indicated by throwing a LoginException. A return of true indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.
LoginContext's overall authentication fails, then the abort method is invoked on each LoginModule. The abort method removes or destroys any authentication state created by the login or initialize methods. The signature of the abort method is boolean abort() throws LoginException. Failure to complete the abort phase is indicated by throwing a LoginException. A return of true indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.
logout on the LoginContext. This in turn results in a logout method invocation on each LoginModule. The logout method removes the principals and credentials originally associated with the subject during the commit operation. Credentials should be destroyed upon removal. The signature of the logout method is: boolean logout() throws LoginException. Failure to complete the logout process is indicated by throwing a LoginException. A return of true indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.
LoginModule must communicate with the user to obtain authentication information, it uses a CallbackHandler object. Applications implement the CallbackHandler interface and pass it to the LoginContext, which send the authentication information directly to the underlying login modules.
CallbackHandler both to gather input from users, such as a password or smart card PIN, and to supply information to users, such as status information. By allowing the application to specify the CallbackHandler, underlying LoginModules remain independent from the different ways applications interact with users. For example, a CallbackHandler's implementation for a GUI application might display a window to solicit user input. On the other hand, a CallbackHandler implementation for a non-GUI environment, such as an application server, might simply obtain credential information by using an application server API. The CallbackHandler interface has one method to implement:
void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException;
Callback interface is the last authentication class we will look at. This is a tagging interface for which several default implementations are provided, including the NameCallback and PasswordCallback used in an earlier example. A LoginModule uses a Callback to request information required by the authentication mechanism. LoginModules pass an array of Callbacks directly to the CallbackHandler.handle method during the authentication's login phase. If a callbackhandler does not understand how to use a Callback object passed into the handle method, it throws an UnsupportedCallbackException to abort the login call.
org.jboss.security.AuthenticationManager
org.jboss.security.RealmMapping
org.jboss.security.SecurityProxy
org.jboss.security.AuthorizationManager
org.jboss.security.AuditManager
org.jboss.security.MappingManager

org.jboss.ejb.Container, org.jboss.SecurityInterceptor and org.jboss.SecurityProxyInterceptor. The other classes are interfaces and classes provided by the JBoss security subsystem.
org.jboss.security.AuthenticationManager
org.jboss.security.AuthorizationManager
isValid method is invoked to determine whether a user identity and associated credentials as known in the operational environment are valid proof of the user's identity.
SecurityProxyInterceptor plugin. A SecurityProxy allows for the externalization of custom security checks on a per-method basis for both the EJB home and remote interface methods.
AuthenticationManager, RealmMapping, and SubjectSecurityManager interfaces. SecurityDomain is the recommended way to implement security in components, because of the advantages the JAAS Subject offers, and the increased support offered to to ASP-style application and resource deployments. A java.security.KeyStore, and the Java Secure Socket Extension (JSSE) com.sun.net.ssl.KeyManagerFactory and com.sun.net.ssl.TrustManagerFactory interfaces are included in the class.
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 operation environment has been assigned the indicated role from the application domain.
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 Java EE security model are not. The JBossSX framework is simply an implementation of the basic security plug-in interfaces that are based on JAAS.


AuthenticationManager and RealmMapping interfaces. When specified as a top-level element, it defines what security domain is specified 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.
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.
org.jboss.security.SecurityProxy interface. Alternatively, you can use a common interface that uses an object to implement methods in the home, remote, local home, or local interfaces of the EJB. 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 SecurityProxy implementation used by the default JBossSX installation.
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 Example 3.1, “Custom EchoSecurityProxy Implementation.”
package org.jboss.book.security.ex1; import java.lang.reflect.Method; import javax.ejb.EJBContext; import org.apache.log4j.Category; import org.jboss.security.SecurityProxy; /** A simple example of a custom SecurityProxy implementation * that demonstrates method argument based security checks. * @author Scott.Stark@jboss.org * @version $Revision: 1.4 $ */ public class EchoSecurityProxy implements SecurityProxy { Category log = Category.getInstance(EchoSecurityProxy.class); Method echo; public void init(Class beanHome, Class beanRemote, Object securityMgr) throws InstantiationException { log.debug("init, beanHome="+beanHome + ", beanRemote="+beanRemote + ", securityMgr="+securityMgr); // Get the echo method for equality testing in invoke try { Class[] params = {String.class}; echo = beanRemote.getDeclaredMethod("echo", params); } catch(Exception e) { String msg = "Failed to find an echo(String) method"; log.error(msg, e); throw new InstantiationException(msg); } } public void setEJBContext(EJBContext ctx) { log.debug("setEJBContext, ctx="+ctx); } public void invokeHome(Method m, Object[] args) throws SecurityException { // We don't validate access to home methods } public void invoke(Method m, Object[] args, Object bean) throws SecurityException { log.debug("invoke, m="+m); // Check for the echo method if (m.equals(echo)) { // Validate that the msg arg is not 4 letter word String arg = (String) args[0]; if (arg == null || arg.length() == 4) throw new SecurityException("No 4 letter words"); } // We are not responsible for doing the invoke } }
EchoSecurityProxy checks that the method to be invoked on the bean instance corresponds to the echo(String) method loaded the init method. If there is a match, the method argument is obtained and its length compared against 4 or null. Either case results in a SecurityException being thrown.
jboss.xml descriptor that installs the EchoSecurityProxy as the custom proxy for the EchoBean is given in Example 3.2, “jboss.xml descriptor”.
<jboss> <security-domain>java:/jaas/other</security-domain> <enterprise-beans> <session> <ejb-name>EchoBean</ejb-name> <security-proxy>org.jboss.book.security.ex1.EchoSecurityProxy</security-proxy> </session> </enterprise-beans> </jboss>
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")); } }
Four is a four-letter word. Run the client as follows using Ant from the examples directory:
[examples]$ ant -Dchap=security -Dex=1 run-example
run-example1:
...
[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.AccessException: SecurityException; nested exception is:
[java] java.lang.SecurityException: No 4 letter words
...
[java] Caused by: java.lang.SecurityException: No 4 letter words
...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 above 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.
org.jboss.security.plugins.JaasSecurityManager. This is the default implementation of the AuthenticationManager and RealmMapping interfaces. Figure 4.1, “Relationship between <security-domain> deployment descriptor value, component container, and JaasSecurityManager.” shows how the JaasSecurityManager integrates into the EJB and web container layers based on the <security-domain> element of the corresponding component deployment descriptor.

jwdomain. The EJB and web containers have a request interceptor architecture that includes a security interceptor, which enforces the container security model. At deployment time, the <security-domain> element value in the jboss.xml and jboss-web.xml descriptors is used to obtain the security manager instance associated with the container. The security interceptor then uses the security manager to perform its role. When a secured component is requested, the security interceptor delegates security checks to the security manager instance associated with the container.
JaasSecurityManager implementation performs security checks based on the information associated with the Subject instance that results from executing the JAAS login modules configured under the name matching the <security-domain> element value. We will drill into the JaasSecurityManager implementation and its use of JAAS in the following section.
JaasSecurityManager uses the JAAS packages to implement the AuthenticationManager and RealmMapping interface behavior. In particular, its behavior derives from the execution of the login module instances that are configured under the name that matches the security domain to which the JaasSecurityManager has been assigned. The login modules implement the security domain's principal authentication and role-mapping behavior. Thus, you can use the JaasSecurityManager across different security domains simply by plugging in different login module configurations for the domains.
JaasSecurityManager's usage of the JAAS authentication process, you will walk through a client invocation of an EJB home method invocation. The prerequisite setting is that the EJB has been deployed in the JBoss server and its home interface methods have been secured using <method-permission> elements in the ejb-jar.xml descriptor, and it has been assigned a security domain named jwdomain using the jboss.xml descriptor <security-domain> element.

InitialContext properties is provided via an alternate configuration.
LoginContext instance and passing in the name of the configuration to use. The configuration name is other. This one-time login associates the login principal and credentials with all subsequent EJB method invocations. Note that the process might not authenticate the user. The nature of the client-side login depends on the login module configuration that the client uses. In this example, the other client-side login configuration entry is set up to use the ClientLoginModule module (an org.jboss.security.ClientLoginModule). This is the default client side module that simply binds the user name and password to the JBoss EJB invocation layer for later authentication on the server. The identity of the client is not authenticated on the client.
LoginContext constructor. The EJB security domain is jwdomain. If the JAAS login authenticates the user, a JAAS Subject is created that contains the following in its PrincipalsSet:
java.security.Principal that corresponds to the client identity as known in the deployment security environment.
java.security.acl.Group named Roles that contains the role names from the application domain to which the user has been assigned. org.jboss.security.SimplePrincipal objects are used to represent the role names; SimplePrincipal is a simple string-based implementation of Principal. These roles are used to validate the roles assigned to methods in ejb-jar.xml and the EJBContext.isCallerInRole(String) method implementation.
java.security.acl.Group named CallerPrincipal, which contains a single org.jboss.security.SimplePrincipal that corresponds to the identity of the application domain's caller. The CallerPrincipal sole group member will be the value returned by the EJBContext.getCallerPrincipal() method. The purpose of this mapping is to allow a Principal as known in the operational security environment to map to a Principal with a name known to the application. In the absence of a CallerPrincipal mapping the deployment security environment principal is used as the getCallerPrincipal method value. That is, the operational principal is the same as the application domain principal.
ejb-jar.xml descriptor <role-name> elements of all <method-permission> elements containing the invoked method.
doesUserHaveRole method is invoked on the security manager by the security interceptor to see if the caller has one of the assigned role names. This method iterates through the role names and checks if the authenticated user's Subject Roles group contains a SimplePrincipal with the assigned role name. Access is allowed if any role name is a member of the Roles group. Access is denied if none of the role names are members.
java.lang.SecurityException. If no SecurityException is thrown, access to the EJB method is allowed and the method invocation passes to the next container interceptor. Note that the SecurityProxyInterceptor handles this check and this interceptor is not shown.
web.xml that match the requested resource and the accessed HTTP method.
allRoles, and whether STRICT_MODE is used.
JaasSecurityManager supports the notion of an authentication cache that is used to store principal and credential information from previous successful logins. You can specify the authentication cache instance to use as part of the JaasSecurityManager configuration as you will see when the associated MBean service is discussed in following section. In the absence of any user-defined cache, a default cache that maintains credential information for a configurable period of time is used.
JaasSecurityManagerService MBean service manages security managers. Although its name begins with Jaas, the security managers it handles need not use JAAS in their implementation. The name arose from the fact that the default security manager implementation is the JaasSecurityManager. The primary role of the JaasSecurityManagerService is to externalize the security manager implementation. You can change the security manager implementation by providing an alternate implementation of the AuthenticationManager and RealmMapping interfaces.
JaasSecurityManagerService is to provide a JNDI javax.naming.spi.ObjectFactory implementation to allow for simple code-free management of the JNDI name to security manager implementation mapping. Security is enabled by specifying the JNDI name of the security manager implementation via the <security-domain> deployment descriptor element.
JaasSecurityManagerService manages the association of security manager instances to names by binding a next naming system reference with itself as the JNDI ObjectFactory under the name java:/jaas. This permits a naming convention of the form java:/jaas/XYZ as the value for the <security-domain> element, and the security manager instance for the XYZ security domain will be created as needed.
XYZ is created on the first lookup against the java:/jaas/XYZ binding by creating an instance of the class specified by the SecurityManagerClassName attribute using a constructor that takes the name of the security domain.
java:/jaas prefix in each <security-domain> deployment descriptor element was required to correctly bind the JNDI name of a security domain to the security manager bindings.
java:/jaas prefix is not required for security domain declaration. The java:/jaas prefix is still supported, and remains for backward compatibility.
<jboss> <!-- Configure all containers to be secured under the "customer" security domain --> <security-domain>customer</security-domain> <!-- ... --> </jboss>
customer will return a security manager instance that has been associated with the security domain named customer. This security manager will implement the AuthenticationManager and RealmMapping security interfaces and will be of the type specified by the JaasSecurityManagerServiceSecurityManagerClassName attribute.
JaasSecurityManagerService MBean is configured by default for use in the standard JBoss distribution, and you can often use the default configuration as is. The configurable attributes of the JaasSecurityManagerService include:
org.jboss.security.AuthenticationManager and org.jboss.security.RealmMapping interfaces. If not specified this defaults to the JAAS-based org.jboss.security.plugins.JaasSecurityManager.
javax.security.auth.callback.CallbackHandlerimplementation used by the JaasSecurityManager.
JaasSecurityManager if the default implementation (org.jboss.security.auth.callback.SecurityAssociationHandler) does not meet your needs. Most implementations will find the default handler is sufficient.
org.jboss.security.SecurityProxyFactory implementation. If not specified this defaults to org.jboss.security.SubjectSecurityProxyFactory.
ObjectFactory location capable of returning CachePolicy instances on a per-<security-domain> basis. This is done by appending the name of the security domain to this name when looking up the CachePolicy for a domain. If this fails, the location is treated as a single CachePolicy for all security domains. As a default, a timed cache policy is used.
AuthenticationCacheJndiName has been changed from the default value.
DefaultCacheTimeout in order for the timeout to be meaningful. The default resolution is 60 seconds (1 minute). This has no affect if the AuthenticationCacheJndiName has been changed from the default value.
JaasSecurityManagerService also supports a number of useful operations. These include flushing any security domain authentication cache at runtime, getting the list of active users in a security domain authentication cache, and any of the security manager interface methods.
public void flushAuthenticationCache(String securityDomain).
MBeanServer server = ...; String jaasMgrName = "jboss.security:service=JaasSecurityManager"; ObjectName jaasMgr = new ObjectName(jaasMgrName); Object[] params = {domainName}; String[] signature = {"java.lang.String"}; server.invoke(jaasMgr, "flushAuthenticationCache", params, signature);
Principals keys in a security domain authentication cache that are not expired. The MBean operation signature is: public List getAuthenticationCachePrincipals(String securityDomain).
MBeanServer server = ...; String jaasMgrName = "jboss.security:service=JaasSecurityManager"; ObjectName jaasMgr = new ObjectName(jaasMgrName); Object[] params = {domainName}; String[] signature = {"java.lang.String"}; List users = (List) server.invoke(jaasMgr, "getAuthenticationCachePrincipals", params, signature);
public boolean isValid(String securityDomain, Principal principal, Object credential); public Principal getPrincipal(String securityDomain, Principal principal); public boolean doesUserHaveRole(String securityDomain, Principal principal, Object credential, Set roles); public Set getUserRoles(String securityDomain, Principal principal, Object credential);
AuthenticationManager and RealmMapping interface method of the associated security domain named by the securityDomain argument.
org.jboss.security.plugins.JaasSecurityDomain is an extension of JaasSecurityManager that adds the notion of a KeyStore, a JSSE KeyManagerFactory and a TrustManagerFactory for supporting SSL and other cryptographic use cases. The additional configurable attributes of the JaasSecurityDomain include:
KeyStore implementation. This is the type argument passed to the java.security.KeyStore.getInstance(String type) factory method. The default is JKS.
KeyStore database. This is used to obtain an InputStream to initialize the KeyStore. If the string does not contain a name/value URL, the value is treated as a file.
KeyStore database contents. The KeyStorePass is also used in combination with the Salt and IterationCount attributes to create a PBE secret key used with the encode/decode operations. The KeyStorePass attribute value format is one of the following:
KeyStore. The toCharArray() value of the string is used without any manipulation.
{EXT}... where the ... is the exact command line that will be passed to the Runtime.exec(String) method to execute a platform-specific command. The first line of the command output is used as the password.
{CLASS}classname[:ctorarg] where the [:ctorarg] is an optional string that will be passed to the constructor when instantiating the classname. The password is obtained from classname by invoking a toCharArray() method if found, otherwise, the toString() method is used.
PBEParameterSpec salt value.
PBEParameterSpec iteration count value.
TrustStore implementation. This is the type argument passed to the java.security.KeyStore.getInstance(String type) factory method. The default is JKS.
TrustStore database. This is used to obtain an InputStream to initialize the KeyStore. If the string is not a value URL, it is treated as a file.
TrustStorePass is a simple password and does not have the same configuration options as the KeyStorePass.
JaasSecurityDomain as a the security manager under java:/jaas/<domain> where <domain> is the name passed to the MBean constructor. The name defaults to jboss.security:service=JaasSecurityManager.
Table of Contents
/schema/security-beans_1_0.xsd inside the jboss-as/lib/jbosssx.jar/
/schema/security-beans_1_0.xsd inside the jboss-as/common/lib/jbosssx.jar
<application-policy xmlns="urn:jboss:security-beans:1.0" name=""> <authentication> <login-module code="" flag="[required|requisite|sufficient|optional]" extends=""> <module-option name=""></module-option> </login-module> </authentication> <authorization> <policy-module code="" flag="[required|requisite|sufficient|optional]"/> </authorization> <mapping> <mapping-module code="" type="" /> </mapping> </application-policy>
xmlns attribute.
name attribute sets the name of the security domain referenced by an application. The security domain name is bound in JNDI under the java:/jaas context, and is accessed by applications via reference in their deployment descriptors.
code attribute to specify what login module implementation an application can use, and the flag attribute to tell the application how to parse each login module present in the stack. The flag attribute supports the following values:
code attribute to specify what policy module implementation an application can use, and the flag attribute to tell the application how to parse each policy module present in the policy stack. The flag attribute supports the following values:
code attribute to specify what mapping module implementation an application can use, and the flag attribute to tell the application how to parse each mapping module present in the policy stack. The flag attribute supports the following values:
jmx-console that uses a single login module, UsersRolesLoginModule (refer to Section 12.1.6, “UsersRolesLoginModule”).
jboss-as/server/$PROFILE/conf/props directory.
<application-policy xmlns="urn:jboss:security-beans:1.0 name="jmx-console"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="usersProperties">props/jmx-console-users.properties</module-option> <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option> </login-module> </authentication> </application-policy>
web-console that uses two login modules in the authentication login module stack.
LdapLoginModule (refer to Section 12.1.1, “LdapLoginModule”), whereas the other <login-module> obtains authentication credentials using BaseCertLoginModule (refer to Section 12.1.8, “BaseCertLoginModule”).
<application-policy xmlns="urn:jboss:security-beans:1.0 name="web-console"> <authentication> <!-- LDAP configuration --> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="sufficient" /> <!-- database configuration --> <login-module code="org.jboss.security.auth.spi.BaseCertLoginModule" flag="sufficient" /> </authentication> </application-policy>
conf/jboss-service.xml JaasSecurityManagerService MBean definition.
deploy/security/security-jboss-beans.xml JNDISecurityManagement bean.
jboss-service.xml configuration file.
Open the configuration file
$JBOSS_HOME/server/$PROFILE/conf/
jboss-service.xml file.
jboss-service.xml file contains the configuration in Example 7.3, “jboss-service default configuration”
<?xml version="1.0" encoding="UTF-8"?>
...
<!-- ==================================================================== -->
<!-- Security -->
<!-- ==================================================================== -->
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService" name="jboss.security:service=JaasSecurityManager">
<!-- A flag which indicates whether the SecurityAssociation server mode
is set on service creation. This is true by default since the
SecurityAssociation should be thread local for multi-threaded server
operation.-->
<attribute name="ServerMode">true</attribute>
<attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
<attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
<!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
in seconds.
If you want to disable caching of security credentials, set this to 0 to
force authentication to occur every time. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.-->
<attribute name="DefaultCacheTimeout">1800</attribute>
<!-- DefaultCacheResolution: Specifies the default timed cache policy
resolution in seconds. This controls the interval at which the cache
current timestamp is updated and should be less than the DefaultCacheTimeout
in order for the timeout to be meaningful. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.-->
<attribute name="DefaultCacheResolution">60</attribute>
<!-- DeepCopySubjectMode: This set the copy mode of subjects done by the
security managers to be deep copies that makes copies of the subject
principals and credentials if they are cloneable. It should be set to
true if subject include mutable content that can be corrupted when
multiple threads have the same identity and cache flushes/logout clearing
the subject in one thread results in subject references affecting other
threads.-->
<attribute name="DeepCopySubjectMode">false</attribute>
</mbean>
...
Append the attribute
<?xml version="1.0" encoding="UTF-8"?>
...
<!-- ==================================================================== -->
<!-- Security -->
<!-- ==================================================================== -->
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService" name="jboss.security:service=JaasSecurityManager">
<!-- A flag which indicates whether the SecurityAssociation server mode
is set on service creation. This is true by default since the
SecurityAssociation should be thread local for multi-threaded server
operation.-->
<attribute name="ServerMode">true</attribute>
<attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
<attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
<!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
in seconds.
If you want to disable caching of security credentials, set this to 0 to
force authentication to occur every time. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.-->
<attribute name="DefaultCacheTimeout">1800</attribute>
<!-- DefaultCacheResolution: Specifies the default timed cache policy
resolution in seconds. This controls the interval at which the cache
current timestamp is updated and should be less than the DefaultCacheTimeout
in order for the timeout to be meaningful. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.-->
<attribute name="DefaultCacheResolution">60</attribute>
<!-- DeepCopySubjectMode: This set the copy mode of subjects done by the
security managers to be deep copies that makes copies of the subject
principals and credentials if they are cloneable. It should be set to
true if subject include mutable content that can be corrupted when
multiple threads have the same identity and cache flushes/logout clearing
the subject in one thread results in subject references affecting other
threads.-->
<attribute name="DeepCopySubjectMode">false</attribute>
<attribute name="CallbackHandlerClassName">org.jboss.security.plugins.[Custom_Callback_Handler_Name]</attribute>
</mbean>
...
Restart server
jboss-service.xml file to use a custom callback handler.
Create custom callback instance
Open the configuration file
$JBOSS_HOME/server/$PROFILE/deploy/security/
security-jboss-beans.xml file.
security-jboss-beans.xml file contains the JNDIBasedSecurityManagement bean configuration in Example 7.5, “security-jboss-beans default configuration”
<!-- JNDI Based Security Management --> <bean name="JBossSecuritySubjectFactory" class="org.jboss.security.integration.JBossSecuritySubjectFactory" />
Append the injection property
<bean name="JBossSecuritySubjectFactory" class="org.jboss.security.integration.JBossSecuritySubjectFactory"> <property name="securityManagement"> <inject bean="JNDIBasedSecurityManagement" /> </property> </bean>
Restart server
security-jboss-beans.xml file to inject your custom callback handler.
jboss-web-policy and jboss-ejb-policy authorization configured in jboss-as/server/$PROFILE/deploy/security/security-policies-jboss-beans.xml is used.
security-policies-jboss-beans.xml.
jboss.xml (for EJBs) and jboss-web.xml (for WAR).
jboss-web-policy, and jboss-ejb-policy.
Open the security policy bean
$JBOSS_HOME/server/$PROFILE/deploy/security
security-policies-jboss-beans.xml file.
security-policies-jboss-beans.xml file contains the configuration in Example 8.1, “security-policies-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="jboss-web-policy" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.DelegatingAuthorizationModule" flag="required"/> </authorization> </application-policy> <application-policy xmlns="urn:jboss:security-beans:1.0" name="jboss-ejb-policy" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.DelegatingAuthorizationModule" flag="required"/> </authorization> </application-policy> </deployment>
Change the application-policy definitions
<policy-module> code attribute with the name of the JACC authorization module.
<?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="jboss-web-policy" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.JACCAuthorizationModule" flag="required"/> </authorization> </application-policy> <application-policy xmlns="urn:jboss:security-beans:1.0" name="jboss-ejb-policy" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.JACCAuthorizationModule" flag="required"/> </authorization> </application-policy> <application-policy xmlns="urn:jboss:security-beans:1.0" name="jacc-test" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.JACCAuthorizationModule" flag="required"/> </authorization> </application-policy> </deployment>
Restart server
security-policy-jboss-beans.xml file with JACC authorization enabled for each application policy.
test-domain security domain uses the UsersRolesLoginModule login module and uses JACC authorization. The test-domain-inherited security domain inherits the login module information from test-domain, and specifies XACML authorization must be used.
Open the security policy
jboss-as/server/$PROFILE/conf/login-config.xml file, or create a deployment descriptor file containing the settings. Choose the deployment descriptor if you want to package the security domain settings with your application.
Locate and open login-config.xml
login-config.xml file for the server profile you are using and open the file for editing.
$JBOSS_HOME/jboss-as/server/$PROFILE/conf/login-config.xml
Create a jboss-beans.xml descriptor
[prefix]-jboss-beans.xml descriptor, replacing [prefix] with a meaningful name (for example, test-war-jboss-beans.xml)
/deploy directory of the server profile you are configuring.
jboss-as/server/$PROFILE/deploy/[prefix]-jboss-beans.xml
Specify the test-domain security domain
test-domain security domain. This domain contains the authentication information, including the <login-module> definition, and the JACC authorization policy module definition.
<?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="test-domain"> <authentication> <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required"> <module-option name = "unauthenticatedIdentity">anonymous</module-option> <module-option name="usersProperties">u.properties</module-option> <module-option name="rolesProperties">r.properties</module-option> </login-module> </authentication> <authorization> <policy-module code="org.jboss.security.authorization.modules.JACCAuthorizationModule" flag="required"/> </authorization> </application-policy> </deployment>
Append the test-domain-inherited security domain
test-domain-inherited application policy definition after the test-domain application policy.
extends attribute to other, so the login module information is inherited.
<policy-module> element.
<?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="test-domain"> <authentication> <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required"> <module-option name = "unauthenticatedIdentity">anonymous</module-option> <module-option name="usersProperties">u.properties</module-option> <module-option name="rolesProperties">r.properties</module-option> </login-module> </authentication> <authorization> <policy-module code="org.jboss.security.authorization.modules.JACCAuthorizationModule" flag="required"/> </authorization> </application-policy> <application-policy xmlns="urn:jboss:security-beans:1.0" name="test-domain-inherited" extends="other"> <authorization> <policy-module code="org.jboss.security.authorization.modules.XACMLAuthorizationModule" flag="required"/> </authorization> </application-policy> </deployment>
Restart server
*-jboss-beans.xml) to specify different authorization policies to the standard authentication in your implementation.
org.jboss.security.authorization.modules.AuthorizationModuleDelegate class provides a number of subclasses that allow you to implement module delegation:
AbstractJACCModuleDelegate
WebPolicyModuleDelegate
EJBPolicyModuleDelegate
WebXACMLPolicyModuleDelegate
WebJACCPolicyModuleDelegate
EJBXACMLPolicyModuleDelegate
EJBJACCPolicyModuleDelegate
org.jboss.security.authorization.modules.AuthorizationModuleDelegate class.
<application-policy xmlns="urn:jboss:security-beans:1.0" name="test-domain" extends="other"> <authorization> <policy-module code="xxx.yyy.MyAuthorizationModule" flag="required"> <module-option name="delegateMap">web=xxx.yyy.mywebauthorizationdelegate,ejb=xxx.yyy.myejbauthorizationdelegate</module-option> </policy-module> </authorization> </application-policy>
org.jboss.security.mapping.providers.DeploymentRolesMappingProvider class as the value for the code attribute in the <mapping-module> element. Additionally, the type attribute must be set to role. Refer to Section 6.1.3, “<mapping>” for information about the <mapping> element schema.
<application-policy name="test-domain"> <authentication> ... </authentication> <mapping> <mapping-module code="org.jboss.security.mapping.providers.DeploymentRolesMappingProvider" type="role"/> </mapping> ... </application-policy>
WEB-INF/jboss-web.xml (.war or .sar) file.
<assembly-descriptor> ... <security-role> <role-name>Support</role-name> <principal-name>Mark</principal-name> <principal-name>Tom</principal-name> </security-role> ... </assembly-descriptor>
WEB-INF/jboss-web.xml.
Open the log4j configuration file
$JBOSS_HOME/server/$PROFILE/conf/
jboss-log4j.xml file using a text editor.
Uncomment the security audit category
jboss-log4j.xml file is commented out. Uncomment the category definition shown in Example 10.1, “log4j Security Audit Provider category”.
<?xml version="1.0" encoding="UTF-8"?> <!-- Limit the verbose MC4J EMS (lib used by admin-console) categories --> <category name="org.mc4j.ems"> <priority value="WARN"/> </category> <!-- Show the evolution of the DataSource pool in the logs [inUse/Available/Max] <category name="org.jboss.resource.connectionmanager.JBossManagedConnectionPool"> <priority value="TRACE"/> </category> --> <!-- Category specifically for Security Audit Provider --> <category name="org.jboss.security.audit.providers.LogAuditProvider" additivity="false"> <priority value="TRACE"/> <appender-ref ref="AUDIT"/> </category> <!-- Limit the org.jboss.serial (jboss-serialization) to INFO as its DEBUG is verbose --> <category name="org.jboss.serial"> <priority value="INFO"/> </category>
Uncomment the audit appender
jboss-log4j.xml file is commented out. Uncomment the appender definition shown in Example 10.1, “log4j Security Audit Provider category”.
... <!-- Emit events as JMX notifications <appender name="JMX" class="org.jboss.monitor.services.JMXNotificationAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="Threshold" value="WARN"/> <param name="ObjectName" value="jboss.system:service=Logging,type=JMXNotificationAppender"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c] %m"/> </layout> </appender> --> <!-- Security AUDIT Appender --> <appender name="AUDIT" class="org.jboss.logging.appender.DailyRollingFileAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="File" value="${jboss.server.log.dir}/audit.log"/> <param name="Append" value="true"/> <param name="DatePattern" value="'.'yyyy-MM-dd"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c] (%t:%x) %m%n"/> </layout> </appender> <!-- ================ --> <!-- Limit categories --> <!-- ================ --> <!-- Limit the org.apache category to INFO as its DEBUG is verbose --> <category name="org.apache"> <priority value="INFO"/> </category> ...
Save, and restart server
jboss-log4j.xml file.
Verify security auditing is functioning correctly
audit.log file is located in jboss-as/server/$PROFILE/log/ directory.
audit.log output.
2008-12-05 16:08:26,719 TRACE [org.jboss.security.audit.providers.LogAuditProvider] (http-127.0.0.1-8080-2:) [Success]policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518; Resource:=[org.jboss.security.authorization.resources.EJBResource:contextMap={policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518}:method=public abstract org.jboss.test.security.interfaces.RunAsServiceRemote org.jboss.test.security.interfaces.RunAsServiceRemoteHome.create() throws java.rmi.RemoteException,javax.ejb.CreateException:ejbMethodInterface=Home:ejbName=RunAs:ejbPrincipal=jduke:MethodRoles=Roles(identitySubstitutionCaller,):securityRoleReferences=null:callerSubject=Subject:
Principal: [roles=[identitySubstitutionCaller, extraRunAsRole],principal=runAsUser]
Principal: Roles(members:extraRunAsRole,identitySubstitutionCaller)
:callerRunAs=[roles=[identitySubstitutionCaller, extraRunAsRole],principal=runAsUser]:callerRunAs=[roles=[identitySubstitutionCaller, extraRunAsRole],principal=runAsUser]:ejbRestrictionEnforcement=false:ejbVersion=null];Source=org.jboss.security.plugins.javaee.EJBAuthorizationHelper;Exception:=;audit.log output.
[Error]policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518;Resource:=[org.jboss.security.authorization.resources.EJBResource:contextMap={policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518}:method=public java.security.Principal org.jboss.test.security.ejb3.SimpleStatelessSessionBean.invokeUnavailableMethod():ejbMethodInterface=Remote:ejbName=SimpleStatelessSessionBean:ejbPrincipal=UserA:MethodRoles=Roles(<NOBODY>,):securityRoleReferences=null:callerSubject=Subject:
Principal: UserA
Principal: Roles(members:RegularUser,Administrator)
:callerRunAs=null:callerRunAs=null:ejbRestrictionEnforcement=false:ejbVersion=null];Source=org.jboss.security.plugins.javaee.EJBAuthorizationHelper;Exception:=Authorization Failed: ;Enable EJB security auditing
Activate auditing in the server realm
server.xml file.
server.xml file is located in the jboss-as/server/$PROFILE/deploy/jbossweb.sar/ directory.
<Realm> element must have the enableAudit="true" attribute set, as per Example 10.5, “server.xml audit activation”.
<Realm className="org.jboss.web.tomcat.security.JBossWebRealm" certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping" allRolesMode="authOnly"
enableAudit="true"/>Specify auditing levels system property
run.sh (Linux) or run.bat (Microsoft Windows) script.
jboss-as/server/$PROFILE/deploy/properties-service.xml file.
Linux
jboss-as/bin/run.sh file.
## Specify the Security Audit options #System Property setting to configure the web audit: #* off = turn it off #* headers = audit the headers #* cookies = audit the cookie #* parameters = audit the parameters #* attributes = audit the attributes #* headers,cookies,parameters = audit the headers,cookie and # parameters #* headers,cookies = audit the headers and cookies JAVA_OPTS="$JAVA_OPTS -Dorg.jboss.security.web.audit=headers,cookies,parameter"
Microsoft Windows
jboss-as/bin/run.bat file.
rem Specify the Security Audit options rem System Property setting to configure the web audit rem * off = turn it off rem * headers = audit the headers rem * cookies = audit the cookie rem * parameters = audit the parameters rem * attributes = audit the attributes rem * headers,cookies,parameters = audit the headers,cookie and rem parameters rem * headers,cookies = audit the headers and cookies set JAVA_OPTS=%JAVA_OPTS% " -Dorg.jboss.security.web.audit=headers,cookies,parameter"
properties-service.xml
SystemPropertiesService class MBean in the jboss-as/server/$PROFILE/deploy/properties-service.xml file, and declare the java property as an <attribute>. You can uncomment the relevant operating system block in the code sample below.
... <mbean code="org.jboss.varia.property.SystemPropertiesService" name="jboss:type=Service,name=SystemProperties"> <!-- Linux Attribute Declaration --> <!-- <attribute name="Properties">JAVA_OPTS="$JAVA_OPTS -Dorg.jboss.security.web.audit=headers,cookies,parameter" </attribute> --> <!-- Windows Attribute Declaration --> <!-- <attribute name="Properties">JAVA_OPTS=%JAVA_OPTS% " -Dorg.jboss.security.web.audit=headers,cookies,parameter" </attribute> --> </mbean> ...
Verify security auditing is functioning correctly
audit.log file is located in jboss-as/server/$PROFILE/log/ directory.
audit.log output.
2008-12-05 16:08:38,997 TRACE [org.jboss.security.audit.providers.LogAuditProvider] (http-127.0.0.1-8080-17:) [Success]policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518;Resource:=[org.jboss.security.authorization.resources.WebResource:contextMap={policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@76ed4518,securityConstraints=[Lorg.apache.catalina.deploy.SecurityConstraint;@6feeae6, resourcePermissionCheck=true},canonicalRequestURI=/restricted/get-only/x,request=[/web-constraints:cookies=null:headers=user-agent=Jakarta Commons-HttpClient/3.0,authorization=host=localhost:8080,][parameters=],CodeSource=null];securityConstraints=SecurityConstraint[RestrictedAccess - Get Only];Source=org.jboss.security.plugins.javaee.WebAuthorizationHelper;resourcePermissionCheck=true;Exception:=;audit.log output.
2008-12-05 16:08:41,561 TRACE [org.jboss.security.audit.providers.LogAuditProvider] (http-127.0.0.1-8080-4:) [Failure]principal=anil;Source=org.jboss.web.tomcat.security.JBossWebRealm;request=[/jaspi-web-basic:cookies=null:headers=user-agent=Jakarta Commons-HttpClient/3.0,authorization=host=localhost:8080,][parameters=][attributes=];2008-12-05 16:07:30,129 TRACE [org.jboss.security.audit.providers.LogAuditProvider] (WorkerThread#1[127.0.0.1:55055]:)
*-jboss-beans.xml. It is included in the META-INF directory of EJB Jars, or the WEB-INF directory of web application (WAR).
jboss-as/server/$PROFILE/conf/login-config.xml file.
UsersRolesLoginModule for the authorization policy, however you are not limited to this login module when creating a modular security domain. Refer to Section 12.1, “Using Modules” for additional login modules shipped with JBoss Enterprise Application Platform.
Create deployment descriptor
[domain_name]-jboss-beans.xml. While the domain_name is arbitrary, you should choose a name that is meaningful to the application ensure the name of the deployment descriptor is unique across the server profile.
<deployment> element.
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="urn:jboss:bean-deployer:2.0"> </deployment>
Define application policies
<?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="web-test"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="unauthenticatedIdentity">anonymous</module-option> <module-option name="usersProperties">u.properties</module-option> <module-option name="rolesProperties">r.properties</module-option> </login-module> </authentication> </application-policy> <application-policy xmlns="urn:jboss:security-beans:1.0" name="ejb-test"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="unauthenticatedIdentity">anonymous</module-option> <module-option name="usersProperties">u.properties</module-option> <module-option name="rolesProperties">r.properties</module-option> </login-module> </authentication> </application-policy> </deployment>
Deploy or package the deployment descriptor
jboss-as/server/$PROFILE/deploy directory of the required server profile in your installation.
META-INF directory of the EJB Jar, or the WEB-INF directory of your web application (WAR).
LdapLoginModule is a LoginModule implementation that authenticates against a Lightweight Directory Access Protocol (LDAP) server. Use the LdapLoginModule if your user name and credentials are stored in an LDAP server that is accessible using a Java Naming and Directory Interface (JNDI) LDAP provider.
InitialContextFactory implementation class name. This defaults to the Sun LDAP provider implementation com.sun.jndi.ldap.LdapCtxFactory.
none, simple, and strong. If the property is undefined, the behavior is determined by the service provider.
principalDNSuffix for more info.
principalDNSuffix the userDN will be formed as principalDNPrefix + username + principalDNSuffix
Object using the org.jboss.security.auth.callback.ObjectCallback type of Callback rather than as a char[] password using a JAAS PasswordCallback. This allows for passing non-char[] credential information to the LDAP server. The available values are true and false.
rolesCtxDN in that the context to search for a user's roles can be unique for each user.
roles.
roleAttributeID. The default is false.
true.
true, this property is used to find the role object's name attribute. The default is group.
uid.
true, the full userDN is used as the match value. If false, only the user name is used as the match value against the uidAttributeName attribute. The default value is false.
UsernamePasswordLoginModule superclass.
false . If set to true, the LDAP server will validate the empty password. The default is true.
InitialLdapContext with an environment composed of the LDAP JNDI properties described previously in this section.
String password or the Object credential depending on the useObjectCredential option.
InitialLdapContext instance is created), the user's roles are queried by performing a search on the rolesCtxDN location with search attributes set to the roleAttributeName and uidAttributeName option values. The roles names are obtaining by invoking the toString method on the role attributes in the search result set.
<application-policy name="testLDAP"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"> <module-option name="java.naming.factory.initial"> com.sun.jndi.ldap.LdapCtxFactory </module-option> <module-option name="java.naming.provider.url"> ldap://ldaphost.jboss.org:1389/ </module-option> <module-option name="java.naming.security.authentication"> simple </module-option> <module-option name="principalDNPrefix">uid=</module-option> <module-option name="principalDNSuffix"> ,ou=People,dc=jboss,dc=org </module-option> <module-option name="rolesCtxDN"> ou=Roles,dc=jboss,dc=org </module-option> <module-option name="uidAttributeID">member</module-option> <module-option name="matchOnUserDN">true</module-option> <module-option name="roleAttributeID">cn</module-option> <module-option name="roleAttributeIsDN">false </module-option> </login-module> </authentication> </application-policy>
java.naming.factory.initial, java.naming.factory.url and java.naming.security options in the testLDAP <login-module> configuration indicate the following conditions:
ldaphost.jboss.org on port 1389
jsmith would map to uid=jsmith,ou=People,dc=jboss,dc=org.
userPassword attribute of the user's entry (theduke in this example). Most LDAP servers operate in this manner, however if your LDAP server handles authentication differently you must ensure LDAP is configured according to your production environment requirements.
rolesCtxDN for entries whose uidAttributeID match the user. If matchOnUserDN is true, the search will be based on the full DN of the user. Otherwise the search will be based on the actual user name entered. In this example, the search is under ou=Roles,dc=jboss,dc=org for any entries that have a member attribute equal to uid=jduke,ou=People,dc=jboss,dc=org. The search would locate cn=JBossAdmin under the roles entry.
cn. The value returned would be JBossAdmin, so the jsmith user is assigned to the JBossAdmin role.
dn: dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jsmith,ou=People,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person uid: jsmith cn: John sn: Smith userPassword: theduke dn: ou=Roles,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: Roles dn: cn=JBossAdmin,ou=Roles,dc=jboss,dc=org objectclass: top objectclass: groupOfNames cn: JBossAdmin member: uid=jsmith,ou=People,dc=jboss,dc=org description: the JBossAdmin group
org.jboss.security.auth.spi.LdapExtLoginModule searches for the user to bind, as well as the associated roles, for authentication. The roles query recursively follows DNs to navigate a hierarchical role structure.
{EXT}cat file_with_password.
java.naming.security.principal. The encrypted form of the password is that returned by the JaasSecurityDomainencrypt64(byte[]) method. The org.jboss.security.plugins.PBEUtils can also be used to generate the encrypted form.
{0} expression exists. This substitution behavior originates from the standard DirContext.search(Name, String, Object[], SearchControls cons) method. An common example search filter is (uid={0}).
{0} expression exists. The authenticated userDN is substituted into the filter anywhere a {1} is seen. An example search filter that matches on the input username is (member={0}). An alternative that matches on the authenticated userDN is (member={1}).
true, the role attribute represents the distinguished name of a role object. If set to false, the role name is taken from the value of roleAttributeID. The default is false.
true.
true, this property is the DN of the context to query for the roleNameAttributeID attribute. If the roleAttributeIsDN property is set to false, this property is the attribute name of the role name.
true, this property is used to find the role object's name attribute. The default is group.
0 (deactivated).
empty(length==0) passwords should be passed to the LDAP server.
false, empty passwords are rejected. If set to true, the LDAP server validates the empty password. The default is true.
true, the DN is checked for the roleNameATtributeID. If set to false, the DN is not checked for the roleNameAttributeID. This flag can improve the performance of LDAP queries.
true, the DN is parsed for the username. If set to false the DN is not parsed for the username. This option is used together with usernameBeginString and usernameEndString.

version: 1 dn: o=example2,dc=jboss,dc=org objectClass: top objectClass: dcObject objectClass: organization dc: jboss o: JBoss dn: ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: judke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke2 employeeNumber: judke2-123 sn: Duke2 uid: jduke2 userPassword:: dGhlZHVrZTI= dn: ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke dn: uid=jduke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke2 dn: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the echo role member: uid=jduke,ou=People,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke description: the duke role member: uid=jduke,ou=People,o=example2,dc=jboss,dc=org dn: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo2 description: the Echo2 role member: uid=jduke2,ou=People,dc=jboss,dc=org dn: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke2 description: the duke2 role member: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org dn: cn=JBossAdmin,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: JBossAdmin description: the JBossAdmin group member: uid=jduke,ou=People,dc=jboss,dc=org
testLdapExample2 {
org.jboss.security.auth.spi.LdapExtLoginModule
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url="ldap://lamia/"
java.naming.security.authentication=simple
bindDN="cn=Root,dc=jboss,dc=org"
bindCredential=secret1
baseCtxDN="ou=People,o=example2,dc=jboss,dc=org"
baseFilter="(uid={0})"
rolesCtxDN="ou=Roles,o=example2,dc=jboss,dc=org";
roleFilter="(uid={0})"
roleAttributeIsDN="true"
roleAttributeID="memberOf"
roleNameAttributeID="cn"
};dn: o=example3,dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person objectClass: inetOrgPerson uid: jduke employeeNumber: judke-123 cn: Java Duke sn: Duke userPassword: theduke dn: ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org uid: jduke dn: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the JBossAdmin group member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org
testLdapExample3 {
org.jboss.security.auth.spi.LdapExtLoginModule
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url="ldap://lamia/"
java.naming.security.authentication=simple
bindDN="cn=Root,dc=jboss,dc=org"
bindCredential=secret1
baseCtxDN="ou=People,o=example3,dc=jboss,dc=org"
baseFilter="(cn={0})"
rolesCtxDN="ou=Roles,o=example3,dc=jboss,dc=org";
roleFilter="(member={1})"
roleAttributeID="cn"
};dn: o=example4,dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,o=example4,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example4,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: jduke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: ou=Roles,o=example4,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG1 member: cn=empty dn: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG2 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org dn: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG3 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R1 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R2,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R2 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R3,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R3 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R4,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R4 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R5,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R5 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org
testLdapExample4 {
org.jboss.security.auth.spi.LdapExtLoginModule
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url="ldap://lamia/"
java.naming.security.authentication=simple
bindDN="cn=Root,dc=jboss,dc=org"
bindCredential=secret1
baseCtxDN="ou=People,o=example4,dc=jboss,dc=org"
baseFilter="(cn={0})"
rolesCtxDN="ou=Roles,o=example4,dc=jboss,dc=org";
roleFilter="(member={1})"
roleAttributeID="memberOf"
};
<?xml version="1.0" encoding="UTF-8"?>
<application-policy name="AD_Default">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >
<!--
Some AD configurations may require searching against
the Global Catalog on port 3268 instead of the usual
port 389. This is most likely when the AD forest
includes multiple domains.
-->
<module-option name="java.naming.provider.url">ldap://ldap.jboss.org:389</module-option>
<module-option name="bindDN">JBOSS\someadmin</module-option>
<module-option name="bindCredential">password</module-option>
<module-option name="baseCtxDN">cn=Users,dc=jboss,dc=org</module-option>
<module-option name="baseFilter">(sAMAccountName={0})</module-option>
<module-option name="rolesCtxDN">cn=Users,dc=jboss,dc=org</module-option>
<module-option name="roleFilter">(sAMAccountName={0})</module-option>
<module-option name="roleAttributeID">memberOf</module-option>
<module-option name="roleAttributeIsDN">true</module-option>
<module-option name="roleNameAttributeID">cn</module-option>
<module-option name="searchScope">ONELEVEL_SCOPE</module-option>
<module-option name="allowEmptyPasswords">false</module-option>
</login-module>
</authentication>
</application-policy>
<?xml version="1.0" encoding="UTF-8"?>
<application-policy name="AD_Recursive">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >
<module-option name="java.naming.provider.url">ldap://ad.jboss.org:389</module-option>
<module-option name="bindDN">JBOSS\searchuser</module-option>
<module-option name="bindCredential">password</module-option>
<module-option name="baseCtxDN">CN=Users,DC=jboss,DC=org</module-option>
<module-option name="baseFilter">(sAMAccountName={0})</module-option>
<module-option name="rolesCtxDN">CN=Users,DC=jboss,DC=org</module-option>
<module-option name="roleFilter">(member={1})</module-option>
<module-option name="roleAttributeID">cn</module-option>
<module-option name="roleAttributeIsDN">false</module-option>
<module-option name="roleRecursion">2</module-option>
<module-option name="searchScope">ONELEVEL_SCOPE</module-option>
<module-option name="allowEmptyPasswords">false</module-option>
<module-option name="java.naming.referral">follow</module-option>
</login-module>
</authentication>
</application-policy>
password-stacking attribute to useFirstPass. If a previous module configured for password stacking has authenticated the user, all the other stacking modules will consider the user authenticated and only attempt to provide a set of roles for the authorization step.
password-stacking option is set to useFirstPass, this module first looks for a shared user name and password under the property names javax.security.auth.login.name and javax.security.auth.login.password respectively in the login module shared state map.
<application-policy name="todo"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"> <!-- LDAP configuration --> <module-option name="password-stacking">useFirstPass</module-option> </login-module> <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"> <!-- database configuration --> <module-option name="password-stacking">useFirstPass</module-option> </login-module> </authentication> </application-policy>
nobody and contains based64-encoded, MD5 hashes of the passwords in a usersb64.properties file. The usersb64.properties file can be part of the deployment classpath, or be saved in the /conf directory.
<policy> <application-policy name="testUsersRoles"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="usersProperties">usersb64.properties</module-option> <module-option name="rolesProperties">test-users-roles.properties</module-option> <module-option name="unauthenticatedIdentity">nobody</module-option> <module-option name="hashAlgorithm">MD5</module-option> <module-option name="hashEncoding">base64</module-option> </login-module> </authentication> </application-policy> </policy>
java.security.MessageDigest algorithm to use to hash the password. There is no default so this option must be specified to enable hashing. Typical values are MD5 and SHA.
base64, hex or rfc2617. The default is base64.
true.
rfc2617) is utilized to compute a server-side hash, which should match the hashed value sent from the client.
org.jboss.security.Util class provides a static helper method that will hash a password using the specified encoding. The following example produces a base64-encoded, MD5 hashed password.
String hashedPassword = Util.createPasswordHash("MD5",
Util.BASE64_ENCODING, null, null, "password");
password - is piped into the OpenSSL digest function then piped into another OpenSSL function to convert into base64-encoded format.
echo -n password | openssl dgst -md5 -binary | openssl base64
X03MO1qnZdYdgyfeuILPmQ==. This value must be stored in the users properties file specified in the application policy - usersb64.properties - in the example above.
unauthenticated identity is a login module configuration option that assigns a specific identity (guest, for example) to requests that are made with no associated authentication information. This can be used to allow unprotected servlets to invoke methods on EJBs that do not require a specific role. Such a principal has no associated roles and so can only access either unsecured EJBs or EJB methods that are associated with the unchecked permission constraint.
UsersRolesLoginModule is a simple login module that supports multiple users and user roles loaded from Java properties files. The user name-to-password mapping file is called users.properties and the user name-to-roles mapping file is called roles.properties.
<filename_prefix>-users.properties.
<filename_prefix>-roles.properties.
<deployment xmlns="urn:jboss:bean-deployer:2.0"> <!-- ejb3 test application-policy definition --> <application-policy xmlns="urn:jboss:security-beans:1.0" name="ejb3-sampleapp"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="usersProperties">ejb3-sampleapp-users.properties</module-option> <module-option name="rolesProperties">ejb3-sampleapp-roles.properties</module-option> </login-module> </authentication> </application-policy> </deployment>
ejb3-sampleapp-users.properties file uses a username=password format with each user entry on a separate line:
username1=password1 username2=password2 ...
ejb3-sampleapp-roles.properties file referenced in Example 12.10, “UserRolesLoginModule” uses the pattern username=role1,role2, with an optional group name value. For example:
username1=role1,role2,... username1.RoleGroup1=role3,role4,... username2=role1,role3,...
ejb3-sampleapp-roles.properties is used to assign the user name roles to a particular named group of roles where the XXX portion of the property name is the group name. The user name=... form is an abbreviation for user name.Roles=..., where the Roles group name is the standard name the JaasSecurityManager expects to contain the roles which define the users permissions.
jduke user name:
jduke=TheDuke,AnimatedCharacter jduke.Roles=TheDuke,AnimatedCharacter
DatabaseServerLoginModule is a Java Database Connectivity-based (JDBC) login module that supports authentication and role mapping. Use this login module if you have your user name, password and role information stored in a relational database.
DatabaseServerLoginModule is based on two logical tables:
Table Principals(PrincipalID text, Password text) Table Roles(PrincipalID text, Role text, RoleGroup text)
Principals table associates the user PrincipalID with the valid password and the Roles table associates the user PrincipalID with its role sets. The roles used for user permissions must be contained in rows with a RoleGroup column value of Roles.
java.sql.ResultSet has the same logical structure as the Principals and Roles tables described previously. The actual names of the tables and columns are not relevant as the results are accessed based on the column index.
Principals and Roles, as already declared. The following statements populate the tables with the following data:
PrincipalIDjava with a Password of echoman in the Principals table
PrincipalIDjava with a role named Echo in the RolesRoleGroup in the Roles table
PrincipalIDjava with a role named caller_java in the CallerPrincipalRoleGroup in the Roles table
INSERT INTO Principals VALUES('java', 'echoman')
INSERT INTO Roles VALUES('java', 'Echo', 'Roles')
INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')
DataSource of the database containing the logical Principals and Roles tables. If not specified this defaults to java:/DefaultDS.
select Password from Principals where PrincipalID=?. If not specified this is the exact prepared statement that will be used.
select Role, RoleGroup from Roles where PrincipalID=?. If not specified this is the exact prepared statement that will be used.
Principal implementation class. This must support a constructor taking a string argument for the principal name.
DatabaseServerLoginModule configuration could be constructed as follows:
CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64)) CREATE TABLE UserRoles(username VARCHAR(64), userRoles VARCHAR(32))
login-config.xml entry would be:
<policy> <application-policy name="testDB"> <authentication> <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"> <module-option name="dsJndiName">java:/MyDatabaseDS</module-option> <module-option name="principalsQuery">select passwd from Users username where username=?</module-option> <module-option name="rolesQuery">select userRoles, 'Roles' from UserRoles where username=?</module-option> </login-module> </authentication> </application-policy> </policy>
BaseCertLoginModule authenticates users based on X509 certificates. A typical use case for this login module is CLIENT-CERT authentication in the web tier.
CertRolesLoginModule and DatabaseCertLoginModule extend the behavior to obtain the authorization roles from either a properties file or database.
BaseCertLoginModule needs a KeyStore to perform user validation. This is obtained through a org.jboss.security.SecurityDomain implementation. Typically, the SecurityDomain implementation is configured using the org.jboss.security.plugins.JaasSecurityDomain MBean as shown in this jboss-service.xml configuration fragment:
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.ch8:service=SecurityDomain"> <constructor> <arg type="java.lang.String" value="jmx-console"/> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">unit-tests-server</attribute> </mbean>
jmx-console, with a SecurityDomain implementation available through JNDI under the name java:/jaas/jmx-console. The security domain follows the JBossSX security domain naming pattern.
jmx-console.war, using client certificates and role-based authorization.
Declare Resources and Roles
web.xml to declare the resources to be secured along with the allowed roles and security domain to be used for authentication and authorization.
<?xml version="1.0"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> ... <!-- A security constraint that restricts access to the HTML JMX console to users with the role JBossAdmin. Edit the roles to what you want and uncomment the WEB-INF/jboss-web.xml/security-domain element to enable secured access to the HTML JMX console. --> <security-constraint> <web-resource-collection> <web-resource-name>HtmlAdaptor</web-resource-name> <description>An example security config that only allows users with the role JBossAdmin to access the HTML JMX console web application </description> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>JBossAdmin</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>JBoss JMX Console</realm-name> </login-config> <security-role> <role-name>JBossAdmin</role-name> </security-role> </web-app>
Specify the JBoss Security Domain
jboss-web.xml file, specify the required security domain.
<jboss-web> <security-domain>jmx-console</security-domain> </jboss-web>
Specify Login Module Configuration
conf/login-config.xml file.
<application-policy name="jmx-console"> <authentication> <login-module code="org.jboss.security.auth.spi.BaseCertLoginModule" flag="required"> <module-option name="password-stacking">useFirstPass</module-option> <module-option name="securityDomain">jmx-console</module-option> </login-module> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="password-stacking">useFirstPass</module-option> <module-option name="usersProperties">jmx-console-users.properties</module-option> <module-option name="rolesProperties">jmx-console-roles.properties</module-option> </login-module> </authentication> </application-policy>
BaseCertLoginModule is used for authentication of the client cert, and the UsersRolesLoginModule is only used for authorization due to the password-stacking=useFirstPass option. Both the localhost.keystore and the jmx-console-roles.properties require an entry that maps to the principal associated with the client cert.
[conf]$ keytool -printcert -file unit-tests-client.export
Owner: CN=unit-tests-client, OU=JBoss Inc., O=JBoss Inc., ST=Washington, C=US
Issuer: CN=jboss.com, C=US, ST=Washington, L=Snoqualmie Pass, EMAILADDRESS=admin
@jboss.com, OU=QA, O=JBoss Inc.
Serial number: 100103
Valid from: Wed May 26 07:34:34 PDT 2004 until: Thu May 26 07:34:34 PDT 2005
Certificate fingerprints:
MD5: 4A:9C:2B:CD:1B:50:AA:85:DD:89:F6:1D:F5:AF:9E:AB
SHA1: DE:DE:86:59:05:6C:00:E8:CC:C0:16:D3:C2:68:BF:95:B8:83:E9:58localhost.keystore would need the certificate in Example 12.11, “Certificate Example” stored with an alias of CN=unit-tests-client, OU=JBoss Inc., O=JBoss Inc., ST=Washington, C=US. The jmx-console-roles.properties would also need an entry for the same entry. Since the DN contains characters that are normally treated as delimiters, you must escape the problem characters using a backslash ('\') as illustrated below.
# A sample roles.properties file for use with the UsersRolesLoginModule CN\=unit-tests-client,\ OU\=JBoss\ Inc.,\ O\=JBoss\ Inc.,\ ST\=Washington,\ C\=US=JBossAdmin admin=JBossAdmin
IdentityLoginModule is a simple login module that associates a hard-coded user name to any subject authenticated against the module. It creates a SimplePrincipal instance using the name specified by the principal option.
SimplePrincipal all users are authenticated as. The principal name defaults to guest if no principal option is specified.
jduke and assign role names of TheDuke, and AnimatedCharacter:.
<policy> <application-policy name="testIdentity"> <authentication> <login-module code="org.jboss.security.auth.spi.IdentityLoginModule" flag="required"> <module-option name="principal">jduke</module-option> <module-option name="roles">TheDuke,AnimatedCharacter</module-option> </login-module> </authentication> </application-policy> </policy>
RunAsLoginModule (org.jboss.security.auth.spi.RunAsLoginModule) is a helper module that pushes a run as role onto the stack for the duration of the login phase of authentication, and pops the run as role in either the commit or abort phase.
RunAsLoginModule must be configured ahead of the login modules that require a run as role established.
nobody is used.
javax.security.auth.Subject instance or an org.jboss.security.RunAsIdentity instance. Both these classes store one or more principals that represent the identity and a list of roles that the identity possesses. In the case of the javax.security.auth.Subject a list of credentials is also stored.
ejb-jar.xml deployment descriptor, you specify one or more roles that a user must have to access the various EJB methods. A comparison of these lists reveals whether the user has one of the roles necessary to access the EJB method.
ejb-jar.xml file, you specify a <security-identity> element with a <run-as> role defined as a child of the <session> element.
<session> ... <security-identity> <run-as> <role-name>Admin</role-name> </run-as> </security-identity> ... </session>
<run-as-principal> element in the jboss-web.xml file.
<session> ... <security-identity> <run-as-principal>John</run-as-principal> </security-identity> ... </session>
<security-identity> element in both the ejb-jar.xml and jboss-web.xml files are parsed at deployment time. The <run-as> role name and the <run-as-principal> name are then stored in the org.jboss.metadata.SecurityIdentityMetaData class.
jboss-web.xml deployment descriptor <assembly-descriptor> element group.
<assembly-descriptor> ... <security-role> <role-name>Support</role-name> <principal-name>John</principal-name> <principal-name>Jill</principal-name> <principal-name>Tony</principal-name> </security-role> ... </assembly-descriptor>
<run-as-principal> of "Mark" was created. The configuration in this example extends the "Admin" role, by adding the "Support" role. The new role contains extra principals, including the originally defined principal "John".
<security-role> element in both the ejb-jar.xml and jboss.xml files are parsed at deployment time. The <role-name> and the <principal-name> data is stored in the org.jboss.metadata.SecurityIdentityMetaData class.
ClientLoginModule (org.jboss.security.ClientLoginModule) is an implementation of LoginModule for use by JBoss clients for establishing caller identity and credentials. This simply sets the org.jboss.security.SecurityAssociation.principal to the value of the NameCallback filled in by the callbackhandler, and the org.jboss.security.SecurityAssociation.credential to the value of the PasswordCallback filled in by the callbackhandler.
ClientLoginModule is the only supported mechanism for a client to establish the current thread's caller. Both stand-alone client applications, and server environments (acting as JBoss EJB clients where the security environment has not been configured to use JBossSX transparently) must use ClientLoginModule.
ClientLoginModule.
false.
LdapLoginModule. When password-stacking option is set to useFirstPass, the module first looks for a shared user name and password using javax.security.auth.login.name and javax.security.auth.login.password respectively in the login module shared state map. This allows a module configured prior to this one to establish a valid JBoss user name and password.
SecurityAssociation principal and credential seen on entry to the login() method are saved and restored on either abort or logout. This is necessary if you must change identities and then restore the original caller identity. If set to true, the principal and credential information is saved and restored on abort or logout. If set to false, abort and logout clear the SecurityAssociation. The default value is false.
SPNEGOLoginModule (org.jboss.security.negotiation.spnego.SPNEGOLoginModule) is an implementation of LoginModule that establishes caller identity and credentials with a KDC. The module implements SPNEGO (Simple and Protected GSSAPI Negotiation mechanism) and is a part of the JBoss Negotiation project. This authentication can be used in the chained configuration with the AdvancedLDAPLoginModule to allow cooperation with an LDAP server. For further information on JBoss Negotiation refer to the Negotiation User Guide.
JaasSecurityManager requires a particular usage pattern of the Subject principals set. You must understand the JAAS Subject class's information storage features and the expected usage of these features to write a login module that works with the JaasSecurityManager.
LoginModule implementations that can help you implement custom login modules.
Subject by using the following methods:
java.util.Set getPrincipals() java.util.Set getPrincipals(java.lang.Class c) java.util.Set getPrivateCredentials() java.util.Set getPrivateCredentials(java.lang.Class c) java.util.Set getPublicCredentials() java.util.Set getPublicCredentials(java.lang.Class c)
Subject identities and roles, JBossSX has selected the most logical choice: the principals sets obtained via getPrincipals() and getPrincipals(java.lang.Class). The usage pattern is as follows:
java.security.Principal objects in the SubjectPrincipals set. The Principal implementation that represents the user identity must base comparisons and equality on the name of the principal. A suitable implementation is available as the org.jboss.security.SimplePrincipal class. Other Principal instances may be added to the SubjectPrincipals set as needed.
Principals set, and are grouped in named role sets using java.security.acl.Group instances. The Group interface defines a collection of Principals and/or Groups, and is a subinterface of java.security.Principal.
Subject.
Roles and CallerPrincipal.
Roles group is the collection of Principals for the named roles as known in the application domain under which the Subject has been authenticated. This role set is used by methods like the EJBContext.isCallerInRole(String), which EJBs can use to see if the current caller belongs to the named application domain role. The security interceptor logic that performs method permission checks also uses this role set.
CallerPrincipalGroup consists of the single Principal identity assigned to the user in the application domain. The EJBContext.getCallerPrincipal() method uses the CallerPrincipal to allow the application domain to map from the operation environment identity to a user identity suitable for the application. If a Subject does not have a CallerPrincipalGroup, the application identity is the same as operational environment identity.
Subject usage patterns described in Section 12.2, “Custom Modules”, JBossSX includes login modules that populate the authenticated Subject with a a template pattern that enforces correct Subject usage.
org.jboss.security.auth.spi.AbstractServerLoginModule class.
javax.security.auth.spi.LoginModule interface and offers abstract methods for the key tasks specific to an operation environment security infrastructure. The key details of the class are highlighted in Example 12.14, “AbstractServerLoginModule Class Fragment”. The JavaDoc comments detail the responsibilities of subclasses.
loginOk instance variable is pivotal. This must be set to true if the login succeeds, or false by any subclasses that override the login method. If this variable is incorrectly set, the commit method will not correctly update the subject.
package org.jboss.security.auth.spi; /** * This class implements the common functionality required for a JAAS * server-side LoginModule and implements the JBossSX standard * Subject usage pattern of storing identities and roles. Subclass * this module to create your own custom LoginModule and override the * login(), getRoleSets(), and getIdentity() methods. */ public abstract class AbstractServerLoginModule implements javax.security.auth.spi.LoginModule { protected Subject subject; protected CallbackHandler callbackHandler; protected Map sharedState; protected Map options; protected Logger log; /** Flag indicating if the shared credential should be used */ protected boolean useFirstPass; /** * Flag indicating if the login phase succeeded. Subclasses that * override the login method must set this to true on successful * completion of login */ protected boolean loginOk; // ... /** * Initialize the login module. This stores the subject, * callbackHandler and sharedState and options for the login * session. Subclasses should override if they need to process * their own options. A call to super.initialize(...) must be * made in the case of an override. * * <p> * The options are checked for the <em>password-stacking</em> parameter. * If this is set to "useFirstPass", the login identity will be taken from the * <code>javax.security.auth.login.name</code> value of the sharedState map, * and the proof of identity from the * <code>javax.security.auth.login.password</code> value of the sharedState map. * * @param subject the Subject to update after a successful login. * @param callbackHandler the CallbackHandler that will be used to obtain the * the user identity and credentials. * @param sharedState a Map shared between all configured login module instances * @param options the parameters passed to the login module. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { // ... } /** * Looks for javax.security.auth.login.name and * javax.security.auth.login.password values in the sharedState * map if the useFirstPass option was true and returns true if * they exist. If they do not or are null this method returns * false. * Note that subclasses that override the login method * must set the loginOk var to true if the login succeeds in * order for the commit phase to populate the Subject. This * implementation sets loginOk to true if the login() method * returns true, otherwise, it sets loginOk to false. */ public boolean login() throws LoginException { // ... } /** * Overridden by subclasses to return the Principal that * corresponds to the user primary identity. */ abstract protected Principal getIdentity(); /** * Overridden by subclasses to return the Groups that correspond * to the role sets assigned to the user. Subclasses should * create at least a Group named "Roles" that contains the roles * assigned to the user. A second common group is * "CallerPrincipal," which provides the application identity of * the user rather than the security domain identity. * * @return Group[] containing the sets of roles */ abstract protected Group[] getRoleSets() throws LoginException; }
org.jboss.security.auth.spi.UsernamePasswordLoginModule.
char[] password as the authentication credentials. It also supports the mapping of anonymous users (indicated by a null user name and password) to a principal with no roles. The key details of the class are highlighted in the following class fragment. The JavaDoc comments detail the responsibilities of subclasses.
package org.jboss.security.auth.spi; /** * An abstract subclass of AbstractServerLoginModule that imposes a * an identity == String username, credentials == String password * view on the login process. Subclasses override the * getUsersPassword() and getUsersRoles() methods to return the * expected password and roles for the user. */ public abstract class UsernamePasswordLoginModule extends AbstractServerLoginModule { /** The login identity */ private Principal identity; /** The proof of login identity */ private char[] credential; /** The principal to use when a null username and password are seen */ private Principal unauthenticatedIdentity; /** * The message digest algorithm used to hash passwords. If null then * plain passwords will be used. */ private String hashAlgorithm = null; /** * The name of the charset/encoding to use when converting the * password String to a byte array. Default is the platform's * default encoding. */ private String hashCharset = null; /** The string encoding format to use. Defaults to base64. */ private String hashEncoding = null; // ... /** * Override the superclass method to look for an * unauthenticatedIdentity property. This method first invokes * the super version. * * @param options, * @option unauthenticatedIdentity: the name of the principal to * assign and authenticate when a null username and password are * seen. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { super.initialize(subject, callbackHandler, sharedState, options); // Check for unauthenticatedIdentity option. Object option = options.get("unauthenticatedIdentity"); String name = (String) option; if (name != null) { unauthenticatedIdentity = new SimplePrincipal(name); } } // ... /** * A hook that allows subclasses to change the validation of the * input password against the expected password. This version * checks that neither inputPassword or expectedPassword are null * and that inputPassword.equals(expectedPassword) is true; * * @return true if the inputPassword is valid, false otherwise. */ protected boolean validatePassword(String inputPassword, String expectedPassword) { if (inputPassword == null || expectedPassword == null) { return false; } return inputPassword.equals(expectedPassword); } /** * Get the expected password for the current username available * via the getUsername() method. This is called from within the * login() method after the CallbackHandler has returned the * username and candidate password. * * @return the valid password String */ abstract protected String getUsersPassword() throws LoginException; }
AbstractServerLoginModule versus UsernamePasswordLoginModule is based on whether a string-based user name and credentials are usable for the authentication technology you are writing the login module for. If the string-based semantic is valid, then subclass UsernamePasswordLoginModule, otherwise subclass AbstractServerLoginModule.
AbstractServerLoginModule or UsernamePasswordLoginModule to ensure that your login module provides the authenticated Principal information in the form expected by the JBossSX security manager.
AbstractServerLoginModule, you must override the following:
void initialize(Subject, CallbackHandler, Map, Map): if you have custom options to parse.
boolean login(): to perform the authentication activity. Be sure to set the loginOk instance variable to true if login succeeds, false if it fails.
Principal getIdentity(): to return the Principal object for the user authenticated by the log() step.
Group[] getRoleSets(): to return at least one Group named Roles that contains the roles assigned to the Principal authenticated during login(). A second common Group is named CallerPrincipal and provides the user's application identity rather than the security domain identity.
UsernamePasswordLoginModule, you must override the following:
void initialize(Subject, CallbackHandler, Map, Map): if you have custom options to parse.
Group[] getRoleSets(): to return at least one Group named Roles that contains the roles assigned to the Principal authenticated during login(). A second common Group is named CallerPrincipal and provides the user's application identity rather than the security domain identity.
String getUsersPassword(): to return the expected password for the current user name available via the getUsername() method. The getUsersPassword() method is called from within login() after the callbackhandler returns the user name and candidate password.
UsernamePasswordLoginModule and obtains a user's password and role names from a JNDI lookup.
password/<username> (where <username> is the current user being authenticated). Similarly, a lookup of the form roles/<username> returns the requested user's roles.
JndiUserAndPass custom login module.
UsernamePasswordLoginModule, all JndiUserAndPass does is obtain the user's password and roles from the JNDI store. The JndiUserAndPass does not interact with the JAAS LoginModule operations.
package org.jboss.book.security.ex2; import java.security.acl.Group; import java.util.Map; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import org.jboss.security.SimpleGroup; import org.jboss.security.SimplePrincipal; import org.jboss.security.auth.spi.UsernamePasswordLoginModule; /** * An example custom login module that obtains passwords and roles * for a user from a JNDI lookup. * * @author Scott.Stark@jboss.org * @version $Revision: 1.4 $ */ public class JndiUserAndPass extends UsernamePasswordLoginModule { /** The JNDI name to the context that handles the password/username lookup */ private String userPathPrefix; /** The JNDI name to the context that handles the roles/ username lookup */ private String rolesPathPrefix; /** * Override to obtain the userPathPrefix and rolesPathPrefix options. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { super.initialize(subject, callbackHandler, sharedState, options); userPathPrefix = (String) options.get("userPathPrefix"); rolesPathPrefix = (String) options.get("rolesPathPrefix"); } /** * Get the roles the current user belongs to by querying the * rolesPathPrefix + '/' + super.getUsername() JNDI location. */ protected Group[] getRoleSets() throws LoginException { try { InitialContext ctx = new InitialContext(); String rolesPath = rolesPathPrefix + '/' + super.getUsername(); String[] roles = (String[]) ctx.lookup(rolesPath); Group[] groups = {new SimpleGroup("Roles")}; log.info("Getting roles for user="+super.getUsername()); for(int r = 0; r < roles.length; r ++) { SimplePrincipal role = new SimplePrincipal(roles[r]); log.info("Found role="+roles[r]); groups[0].addMember(role); } return groups; } catch(NamingException e) { log.error("Failed to obtain groups for user="+super.getUsername(), e); throw new LoginException(e.toString(true)); } } /** * Get the password of the current user by querying the * userPathPrefix + '/' + super.getUsername() JNDI location. */ protected String getUsersPassword() throws LoginException { try { InitialContext ctx = new InitialContext(); String userPath = userPathPrefix + '/' + super.getUsername(); log.info("Getting password for user="+super.getUsername()); String passwd = (String) ctx.lookup(userPath); log.info("Found password="+passwd); return passwd; } catch(NamingException e) { log.error("Failed to obtain password for user="+super.getUsername(), e); throw new LoginException(e.toString(true)); } } }
org.jboss.book.security.ex2.service.JndiStore MBean. This service binds an ObjectFactory that returns a javax.naming.Context proxy into JNDI. The proxy handles lookup operations done against it by checking the prefix of the lookup name against password and roles.
password, a user's password is being requested. When the name begins with roles the user's roles are being requested. The example implementation always returns a password of theduke and an array of roles names equal to {"TheDuke", "Echo"} regardless of what the user name is. You can experiment with other implementations as you wish.
[examples]$ ant -Dchap=security -Dex=2 run-example
...
run-example2:
[echo] Waiting for 5 seconds for deploy...
[java] [INFO,ExClient] Login with user name=jduke, password=theduke
[java] [INFO,ExClient] Looking up EchoBean2
[java] [INFO,ExClient] Created Echo
[java] [INFO,ExClient] Echo.echo('Hello') = Hello
JndiUserAndPass custom login module for the server side authentication of the user is determined by the login configuration for the example security domain. The EJB JAR META-INF/jboss.xml descriptor sets the security domain.
<?xml version="1.0"?> <jboss> <security-domain>security-ex2</security-domain> </jboss>
META-INF/login-config.xml descriptor defines the login module configuration.
<application-policy name = "security-ex2"> <authentication> <login-module code="org.jboss.book.security.ex2.JndiUserAndPass" flag="required"> <module-option name="userPathPrefix">/security/store/password</module-option> <module-option name = "rolesPathPrefix">/security/store/roles</module-option> </login-module> </authentication> </application-policy>
Table of Contents
This document describes a cryptographically strong network authentication mechanism known as the Secure Remote Password (SRP) protocol. This mechanism is suitable for negotiating secure connections using a user-supplied password, while eliminating the security problems traditionally associated with reusable passwords. This system also performs a secure key exchange in the process of authentication, allowing security layers (privacy and/or integrity protection) to be enabled during the session. Trusted key servers and certificate infrastructures are not required, and clients are not required to store or manage any long-term keys. SRP offers both security and deployment advantages over existing challenge-response techniques, making it an ideal drop-in replacement where secure password authentication is needed.
LoginModule implementation that uses the RMI implementation for use in authenticating clients in a secure fashion
LoginModule implementation that uses the authentication cache managed by the SRP JMX MBean.

LoginModule implementation that communicates with the authentication server through an org.jboss.security.srp.SRPServerInterface proxy. A client enables authentication using SRP by creating a login configuration entry that includes the org.jboss.security.srp.jaas.SRPLoginModule . This module supports the following configuration options:
org.jboss.security.srp.jaas.SRPPrincipal .
SRPServerInterface object used to communicate with the SRP authentication server. If both srpServerJndiName and srpServerRmiUrl options are specified, srpServerJndiName takes priority over srpServerRmiUrl .
SRPServerInterface proxy used to communicate with the SRP authentication server.
true , the feature is activated.
javax.crypto.SealedObject . If set to true , the feature is activated.
true , the feature is activated.
InitialContext constructor. This is useful if the SRP server interface is not available from the default InitialContext .
SRPLoginModule and the standard ClientLoginModule must be configured to allow SRP authentication credentials to be used for access validation to security Java EE components. An example login configuration is described in Example 13.1, “Login Configuration Entry” .
srp {
org.jboss.security.srp.jaas.SRPLoginModule required
srpServerJndiName="SRPServerInterface"
;
org.jboss.security.ClientLoginModule required
password-stacking="useFirstPass"
;
};
org.jboss.security.srp.SRPService MBean. The other MBean is org.jboss.security.srp.SRPVerifierStoreService .
org.jboss.security.srp.SRPService is responsible for exposing an RMI accessible version of the SRPServerInterface as well as updating the SRP authentication session cache.
SRPService binds the serializable dynamic proxy to the SRPServerInterface . The default value is srp/SRPServerInterface .
SRPVerifierSource implementation the SRPService must use. The source JNDI name defaults to srp/DefaultVerifierSource .
org.jboss.util.CachePolicy authentication implementation used for caching authentication information is bound. The SRP session cache is made available for use through this binding. The authentication JNDI cache defaults to srp/AuthenticationCache .
SRPRemoteServerInterface . The default value is 10099.
java.rmi.server.RMIClientSocketFactory implementation class name used during the export of the SRPServerInterface . The default value is RMIClientSocketFactory .
java.rmi.server.RMIServerSocketFactory implementation class name used during the export of the SRPServerInterface . The default value is RMIServerSocketFactory .
SRPLoginModule configuration used by the client must have the useAuxChallenge option enabled.
false , the second user authentication attempt will succeed, however the resulting SRP session will not overwrite the previous SRP session state. The default value is false .
org.jboss.security.srp.SRPVerifierStoreService is an example MBean service that binds an implementation of the SRPVerifierStore interface that uses a file of serialized objects as the persistent store. Although not realistic for a production environment, it does allow for testing of the SRP protocol and provides an example of the requirements for an SRPVerifierStore service.
SRPVerifierStoreService MBean attributes include the following:
SRPVerifierStore implementation should be available. If not specified it defaults to srp/DefaultVerifierSource .
SRPVerifierStore.ser .
SRPVerifierStoreService MBean also supports addUser and delUser operations for addition and deletion of users. The signatures are:
public void addUser(String username, String password) throws IOException; public void delUser(String username) throws IOException;
SRPLoginModule retrieves from the naming service the SRPServerInterface instance for the remote authentication server.
SRPLoginModule next requests the SRP parameters associated with the user name attempting the login. There are a number of parameters involved in the SRP algorithm that must be chosen when the user password is first transformed into the verifier form used by the SRP algorithm. Rather than hard-coding the parameters (which could be done with minimal security risk), the JBossSX implementation allows a user to retrieve this information as part of the exchange protocol. The getSRPParameters(username) call retrieves the SRP parameters for the given user name.
SRPLoginModule begins an SRP session by creating an SRPClientSession object using the login user name, clear-text password, and SRP parameters obtained from step 2. The client then creates a random number A that will be used to build the private SRP session key. The client then initializes the server side of the SRP session by invoking the SRPServerInterface.init method and passes in the user name and client generated random number A. The server returns its own random number B. This step corresponds to the exchange of public keys.
SRPLoginModule obtains the private SRP session key that has been generated as a result of the previous messages exchanges. This is saved as a private credential in the login Subject. The server challenge response M2 from step 4 is verified by invoking the SRPClientSession.verify method. If this succeeds, mutual authentication of the client to server, and server to client have been completed. The client side SRPLoginModule next creates a challenge M1 to the server by invoking SRPClientSession.response method passing the server random number B as an argument. This challenge is sent to the server via the SRPServerInterface.verify method and server's response is saved as M2. This step corresponds to an exchange of challenges. At this point the server has verified that the user is who they say they are.
SRPLoginModule saves the login user name and M1 challenge into the LoginModule sharedState map. This is used as the Principal name and credentials by the standard JBoss ClientLoginModule. The M1 challenge is used in place of the password as proof of identity on any method invocations on Java EE components. The M1 challenge is a cryptographically strong hash associated with the SRP session. Its interception via a third partly cannot be used to obtain the user's password.
SRPCacheLoginModule.
M1 challenge and effectively use the challenge to make requests as the associated user name. Custom interceptors can be used to prevent the issue, by encrypting the challenge using the SRP session key.
org.jboss.security.srp.jaas.SRPCacheLoginModule. The SRPCacheLoginModule has a single configuration option named cacheJndiName that sets the JNDI location of the SRP authentication CachePolicy instance. This must correspond to the AuthenticationCacheJndiName attribute value of the SRPService MBean.
SRPCacheLoginModule authenticates user credentials by obtaining the client challenge from the SRPServerSession object in the authentication cache and comparing this to the challenge passed as the user credentials. Figure 13.2, “SRPCacheLoginModule with SRP Session Cache” illustrates the operation of the SRPCacheLoginModule.login method implementation.

SRPVerifierStore interface that integrates with your existing security information stores. The SRPVerifierStore interface is shown in Example 13.2, “The SRPVerifierStore interface”.
SRPVerifierStore interface is not recommended for a production security environment because it requires all password hash information to be available as a file of serialized objects.
package org.jboss.security.srp; import java.io.IOException; import java.io.Serializable; import java.security.KeyException; public interface SRPVerifierStore { public static class VerifierInfo implements Serializable { public String username; public byte[] salt; public byte[] g; public byte[] N; } public VerifierInfo getUserVerifier(String username) throws KeyException, IOException; public void setUserVerifier(String username, VerifierInfo info) throws IOException; public void verifyUserChallenge(String username, Object auxChallenge) throws SecurityException; }
SRPVerifierStore implementation is to provide access to the SRPVerifierStore.VerifierInfo object for a given user name. The getUserVerifier(String) method is called by the SRPService at that start of a user SRP session to obtain the parameters needed by the SRP algorithm. The elements of the VerifierInfo objects are:
org.jboss.security.Util class has a calculateVerifier method that performs that password hashing algorithm. The output password takes the form H(salt | H(username | ':' | password)), where H is the SHA secure hash function as defined by RFC2945. The user name is converted from a string to a byte[] using UTF-8 encoding.
org.jboss.security.srp.SRPConf utility class provides several settings for g, including a suitable default obtained via SRPConf.getDefaultParams().g().
org.jboss.security.srp.SRPConf utility class provides several settings for N including a good default which can obtained via SRPConf.getDefaultParams().N().
Create Hashed Password Information Store
setUserVerifier(String, VerifierInfo) as a noOp method, or a method that throws an exception stating that the store is read-only.
Create SRPVerifierStore Interface
SRPVerifierStore interface implementation that understands how to obtain the VerifierInfo from the store you created.
verifyUserChallenge(String, Object) can be used to integrate existing hardware token based schemes like SafeWord or Radius into the SRP algorithm. This interface method is called only when the client SRPLoginModule configuration specifies the hasAuxChallenge option.
Create JNDI MBean
SRPVerifierStore interface available to JNDI, and exposes any configurable parameters required.
org.jboss.security.srp.SRPVerifierStoreService will allow you to implement this, however you can also implement the MBean using a Java properties file implementation of SRPVerifierStore (refer to Section 13.3, “Secure Remote Password Example”).
SecurityConfig MBean. A custom implementation of the SRPVerifierStore interface is also used in the example. The interface uses an in-memory store that is seeded from a Java properties file, rather than a serialized object store as used by the SRPVerifierStoreService.
org.jboss.book.security.ex3.service.PropertiesVerifierStore. The following shows the contents of the JAR that contains the example EJB and SRP services.
[examples]$ jar tf output/security/security-ex3.jar META-INF/MANIFEST.MF META-INF/ejb-jar.xml META-INF/jboss.xml org/jboss/book/security/ex3/Echo.class org/jboss/book/security/ex3/EchoBean.class org/jboss/book/security/ex3/EchoHome.class roles.properties users.properties security-ex3.sar
jboss-service.xml descriptor of the security-ex3.sar is described in Example 13.3, “The security-ex3.sar jboss-service.xml Descriptor”.
<server> <!-- The custom JAAS login configuration that installs a Configuration capable of dynamically updating the config settings --> <mbean code="org.jboss.book.security.service.SecurityConfig" name="jboss.docs.security:service=LoginConfig-EX3"> <attribute name="AuthConfig">META-INF/login-config.xml</attribute> <attribute name="SecurityConfigName">jboss.security:name=SecurityConfig</attribute> </mbean> <!-- The SRP service that provides the SRP RMI server and server side authentication cache --> <mbean code="org.jboss.security.srp.SRPService" name="jboss.docs.security:service=SRPService"> <attribute name="VerifierSourceJndiName">srp-test/security-ex3</attribute> <attribute name="JndiName">srp-test/SRPServerInterface</attribute> <attribute name="AuthenticationCacheJndiName">srp-test/AuthenticationCache</attribute> <attribute name="ServerPort">0</attribute> <depends>jboss.docs.security:service=PropertiesVerifierStore</depends> </mbean> <!-- The SRP store handler service that provides the user password verifier information --> <mbean code="org.jboss.security.ex3.service.PropertiesVerifierStore" name="jboss.docs.security:service=PropertiesVerifierStore"> <attribute name="JndiName">srp-test/security-ex3</attribute> </mbean> </server>
ServiceConfig and the PropertiesVerifierStore and SRPService MBeans. Note that the JndiName attribute of the PropertiesVerifierStore is equal to the VerifierSourceJndiName attribute of the SRPService, and that the SRPService depends on the PropertiesVerifierStore. This is required because the SRPService needs an implementation of the SRPVerifierStore interface for accessing user password verification information.
srp {
org.jboss.security.srp.jaas.SRPLoginModule required
srpServerJndiName="srp-test/SRPServerInterface"
;
org.jboss.security.ClientLoginModule required
password-stacking="useFirstPass"
;
};
SRPLoginModule with a srpServerJndiName option value that corresponds to the JBoss server component SRPService JndiName attribute value(srp-test/SRPServerInterface). The ClientLoginModule must also be configured with the password-stacking="useFirstPass" value to propagate the user authentication credentials generated by the SRPLoginModule to the EJB invocation layer.
<application-policy name="security-ex3"> <authentication> <login-module code="org.jboss.security.srp.jaas.SRPCacheLoginModule" flag = "required"> <module-option name="cacheJndiName">srp-test/AuthenticationCache</module-option> </login-module> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required"> <module-option name="password-stacking">useFirstPass</module-option> </login-module> </authentication> </application-policy>
cacheJndiName=srp-test/AuthenticationCache configuration option tells the SRPCacheLoginModule the location of the CachePolicy that contains the SRPServerSession for users who have authenticated against the SRPService. This value corresponds to the SRPServiceAuthenticationCacheJndiName attribute value.
UsersRolesLoginModule with the password-stacking=useFirstPass configuration option. You must use a second login module with the SRPCacheLoginModule because SRP is only an authentication technology. To set the principal's roles that in turn determine the associated permissions, a second login module must be configured to accept the authentication credentials validated by the SRPCacheLoginModule .
UsersRolesLoginModule is augmenting the SRP authentication with properties file based authorization. The user's roles are obtained from the roles.properties file included in the EJB JAR.
[examples]$ ant -Dchap=security -Dex=3 run-example
...
run-example3:
[echo] Waiting for 5 seconds for deploy...
[java] Logging in using the 'srp' configuration
[java] Created Echo
[java] Echo.echo()#1 = This is call 1
[java] Echo.echo()#2 = This is call 2examples/logs directory, the ex3-trace.log file contains a detailed trace of the client side of the SRP algorithm. The traces show step-by-step the construction of the public keys, challenges, session key and verification.
Echo.echo()#2 fails with an authentication exception. The client code sleeps for 15 seconds after making the first call to demonstrate the behavior of the SRPService cache expiration. The SRPService cache policy timeout has been set to 10 seconds to force this issue. As discussed in Section 13.3, “Secure Remote Password Example” you must set the cache timeout correctly, or handle re-authentication on failure.
java.security.manager and java.security.policy .
java.lang.SecurityManager, is used. To use another security manager implementation, supply the fully qualified classname of a subclass of java.lang.SecurityManager with this option.
java.security.policy=policyFileURL policyFileURL will augment the default security policy configured by the VM.
java.security.policy==policyFileURL policyFileURL will replace the default security policy configured by the VM.
policyFileURL value can be a URL or a file path.
jboss-as/bin/server.policy.cert is included as a starting point.
run.conf (Linux) or run.conf.bat (Windows) is used to configure the Security Manager and security policy. This file is found in the jboss-as/bin directory.
run.conf or run.conf.bat file from jboss-as/bin/ to the server profile (for example: jboss-as/server/production/run.conf ), and make the configuration changes there. A configuration file in the server profile takes precedence over the global run.conf / run.conf.bat file when the server profile is started.
run.conf (Linux), or run.conf.bat (Windows) in the server profile directory, if one exists there, or in jboss-as/bin . Refer to Configuration File for details on the location of this file.
Specify the JBoss home directory
run.conf (Linux), or run.conf.bat (Windows). Add the jboss.home.dir option, specifying the path to the jboss-as directory of your installation.
JAVA_OPTS="$JAVA_OPTS -Djboss.home.dir=/path/to/jboss-eap-5.1/jboss-as"
JAVA_OPTS="%JAVA_OPTS% -Djboss.home.dir=c:\path\jboss-eap-5.1\jboss-as"
Specify the server home directory
jboss.server.home.dir option, specifying the path to your server profile.
JAVA_OPTS="$JAVA_OPTS -Djboss.server.home.dir=path/to/jboss-eap-5.1/jboss-as/server/production"
JAVA_OPTS="%JAVA_OPTS% -Djboss.server.home.dir=c:\path\to\jboss-eap-5.1\jboss-as\server\production"
Specify the Protocol Handler
java.protocol.handler.pkgs option, specifying the JBoss stub handler.
JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.jboss.handlers.stub"
JAVA_OPTS="%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.jboss.handlers.stub"
Specify the security policy to use
$POLICY variable, specifying the security policy to use. Add the variable definition before the line that activates the Security Manager.
POLICY="server.policy.cert"
Activate the Security Manager
# :
#JAVA_OPTS="$JAVA_OPTS -Djava.security.manager -Djava.security.policy=$POLICY"
#JAVA_OPTS="%JAVA_OPTS% -Djava.security.manager -Djava.security.policy=%POLICY%"
Optional: Import Red Hat's JBoss signing key
cacerts key store.
JAVA_HOME is set to the location of a JDK supported by JBoss Enterprise Application Platform 5. You configure JAVA_HOME when you first install JBoss Enterprise Application Platform 5. Refer to the Installation Guide for further information.
alternatives command to select from JDKs installed on your Linux system. Refer to Appendix A, Setting the default JDK with the /usr/sbin/alternatives Utility .
JAVA_HOME with the directory location of your Java installation:
[~]$ sudoJAVA_HOME/bin/keytool -import -alias jboss -file JBossPublicKey.RSA \ -keystoreJAVA_HOME/lib/security/cacerts
C:>JAVA_HOME\bin\keytool -import -alias jboss -file JBossPublicKey.RSA -keystoreJAVA_HOME\lib\security\cacerts
changeit .
java.security.debug option configures the level of security-related information reported.
java -Djava.security.debug=help will produce help output with the full range of debugging options. Setting the debug level to all is useful when troubleshooting a security-related failure whose cause is completely unknown, but for general use it will produce too much information. A sensible general default is access:failure .
run.conf (Linux), or run.conf.bat (Windows):
JAVA_OPTS="$JAVA_OPTS -Djava.security.debug=access:failure"
JAVA_OPTS="%JAVA_OPTS% -Djava.security.debug=access:failure"
org.jboss.system.security.DebuggingJavaSecurityManager prints out the protection domain corresponding to a failing permission. This additional information is very useful information when debugging permissions problems.
$JBOSS_HOME/bin/run.conf (Linux) or $JBOSS_HOME/bin/run.conf.bat. See Configuration File for the location of this file.
JAVA_OPTS="$JAVA_OPTS -Djava.security.manager=org.jboss.system.security.DebuggingJavaSecurityManager"
JAVA_OPTS="%JAVA_OPTS% -Djava.security.manager=org.jboss.system.security.DebuggingJavaSecurityManager"
java.security.manager references in the file.
java.security.policy option specifying the policy file to use
jboss-as/bin/server.policy.cert is an example security policy for JBoss Enterprise Application Platform. You can use this file as the basis for your own security policy.
policytool application, included with the JDK, provides a graphical tool for editing and writing security policy.
java.security.AllPermission : you can potentially allow changes to the system binary, including the JVM runtime environment.
java.lang.RuntimePermissions are described below.
org.jboss.security.SecurityAssociation.getPrincipalInfo org.jboss.security.SecurityAssociation getPrincipal() and getCredential() methods. The risk involved with using this runtime permission is the ability to see the current thread caller and credentials.
org.jboss.security.SecurityAssociation.getSubject org.jboss.security.SecurityAssociation getSubject() method.
org.jboss.security.SecurityAssociation.setPrincipalInfo org.jboss.security.SecurityAssociation setPrincipal() , setCredential() , setSubject() , pushSubjectContext() , and popSubjectContext() methods. The risk involved with using this runtime permission is the ability to set the current thread caller and credentials.
org.jboss.security.SecurityAssociation.setServer org.jboss.security.SecurityAssociation setServer method. The risk involved with using this runtime permission is the ability to enable or disable multi-thread storage of the caller principal and credential.
org.jboss.security.SecurityAssociation.setRunAsRole org.jboss.security.SecurityAssociation pushRunAsRole and popRunAsRole , pushRunAsIdentity and popRunAsIdentity methods. The risk involved with using this runtime permission is the ability to change the current caller run-as role principal.
org.jboss.security.SecurityAssociation.accessContextInfo org.jboss.security.SecurityAssociation accessContextInfo, "Get" and accessContextInfo, "Set" methods, allowing you to both set and get the current security context info.
org.jboss.naming.JndiPermission bind , rebind , unbind , lookup , list , listBindings , createSubcontext , and all .
/* indicate the specified permissions apply to all files and directories of the pathname. Pathnames ending in /- indicate recursive permissions to all files and subdirectories of the pathname. Pathnames consisting of the special token <<ALL BINDINGS>> matches any file in any directory.
org.jboss.security.srp.SRPPermission org.hibernate.secure.HibernatePermission org.jboss.metadata.spi.stack.MetaDataStackPermission modify (push/pop onto the stack), peek (peek onto the stack), and * (all).
org.jboss.config.spi.ConfigurationPermission org.jboss.kernel.KernelPermission org.jboss.kernel.plugins.util.KernelLocatorPermission cacerts file with the certificates of several trusted Certificate Authorities (CAs). Any keys signed by these CAs are automatically trusted. Large organizations may have their own internal Certificate Authority, for example using Red Hat Certificate System. In this case the signing certificate of the internal Certificate Authority is typically installed on clients as part of a Corporate Standard Build, and then all certificates signed with that certificate are trusted. CA-signed certificates are best practice for production scenarios.
cacerts file of clients, you need to export a certificate for that key on the server, and import that certificate on any client that connects via SSL.
keytool , a command line tool for generating key pairs and certificates. The certificates generated by keytool can be sent for signing by a CA or can be distributed to clients as a self-signed certificate.
localhost.keystore . You will need to make this key store available to the EJB3 invoker on the server. The key pair in our example will be saved in the key store under the alias 'ejb-ssl'. We will need this key alias, and the key pair password you supply (if any), when configuring the EJB3 Remoting connector in Create a secure remoting connector for RMI .
keytool -genkey -alias ejb-ssl -keystore localhost.keystore -storepassKEYSTORE_PASSWORD-keypassEJB-SSL_KEYPAIR_PASSWORD-dname "CN=SERVER_NAME,OU=QE,O=example.com,L=Brno,C=CZ"
localhost.keystore under the alias ejb-ssl .
keytool parameters
keytool parameters keytool adds the key pair to a new key store called keystore in the current user's home directory. This key store file is a hidden file.
ejb-ssl key from the key store named localhost.keystore .
keytool -export -alias ejb-ssl -file mycert.cer -keystore localhost.keystoremycert.cer .
keytool -import -alias ejb-ssl -file mycert.cer -keystore localhost.truststorelocalhost.truststore location to the application using the javax.net.ssl.trustStore property, and the trust store password using the javax.net.ssl.trustStorePassword property. Example 15.1, “Invoking the com.acme.Runclient application with a specific trust store” is an example command that invokes the application com.acme.RunClient , a hypothetical application that makes remote method calls to an EJB on a JBoss Application Server. This command is run from the root of the application's package directory (the directory containing com directory in the file path com/acme/RunClient.class ).
java -cp$JBOSS_HOME/client/jbossall-client.jar:. -Djavax.net.ssl.trustStore=${resources}/localhost.truststore \ -Djavax.net.ssl.trustStorePassword=TRUSTSTORE_PASSWORDcom.acme.RunClient
ejb3-connectors-jboss-beans.xml in a JBoss Application Server profile deploy directory contains JBoss Remoting connector definitions for EJB3 remote method invocation.
ejb3-connectors-jboss-beans.xml file. Both beans are required to configure a secure connector for EJB3 using the key pair created in Procedure 15.1, “ Generate a new key pair and add it to the key store "localhost.keystore" in the JBoss server conf directory. ”.
keyPassword property in the sample configuration is the key pair password specified when the key pair was created.
<bean name="EJB3SSLRemotingConnector" class="org.jboss.remoting.transport.Connector"> <property name="invokerLocator">sslsocket://${jboss.bind.address}:3843</property> <property name="serverConfiguration"> <inject bean="ServerConfiguration" /> </property> <property name="serverSocketFactory"> <inject bean="sslServerSocketFactory" /> </property> </bean> <bean name="sslServerSocketFactory" class="org.jboss.security.ssl.DomainServerSocketFactory"> <constructor> <parameter><inject bean="EJB3SSLDomain"/></parameter> </constructor> </bean> <bean name="EJB3SSLDomain" class="org.jboss.security.plugins.JaasSecurityDomain"> <constructor> <parameter>EJB3SSLDomain</parameter> </constructor> <property name="keyStoreURL">resource:localhost.keystore</property> <property name="keyStorePass">KEYSTORE_PASSWORD</property> <property name="keyAlias">ejb-ssl</property> <property name="keyPassword">EJB-SSL_KEYPAIR_PASSWORD</property> </bean>
@org.jboss.annotation.ejb.RemoteBinding .
StatefulSSL . The proxy implementing the remote interface, returned to a client when the bean is requested from JNDI, communicates with the server via SSL.
@RemoteBinding(clientBindUrl="sslsocket://0.0.0.0:3843", jndiBinding="StatefulSSL") @Remote(BusinessInterface.class) public class StatefulBean implements BusinessInterface { ... }
@RemoteBindings({ @RemoteBinding(clientBindUrl="sslsocket://0.0.0.0:3843", jndiBinding="StatefulSSL") @RemoteBinding(jndiBinding="StatefulNormal") }) @Remote(BusinessInterface.class) public class StatefulBean implements BusinessInterface { ... }
0.0.0.0, meaning "all interfaces". Change this to the value of the ${jboss.bind.address} system property.
StatefulNormal from JNDI, the returned proxy implementing the remote interface communicates with the server via the unencrypted socket protocol; and if StatefulSSL is requested, the returned proxy implementing the remote interface communicates with the server via SSL.
jboss-as/server/$PROFILE/deploy/jbossweb.sar/server.xml and uncomment the HTTPS connector.
<!-- SSL/TLS Connector configuration using the admin devl guide keystore --> <Connector protocol="HTTP/1.1" SSLEnabled="true" port="8443" address="${jboss.bind.address}" scheme="https" secure="true" clientAuth="false" keystoreFile="${jboss.server.home.dir}/conf/localhost.keystore" keystorePass="KEYSTORE_PASSWORD" sslProtocol = "TLS" />
ServletServerInvoker .
servlet-invoker.war in jboss-as/server/$PROFILE/deploy/.
WEB-INF directory in the servlet-invoker.war directory.
web.xml in that WEB-INF directory, with the following content:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>ServerInvokerServlet</servlet-name> <description>The ServerInvokerServlet receives requests via HTTP protocol from within a web container and passes it onto the ServletServerInvoker for processing. </description> <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class> <init-param> <param-name>locatorUrl</param-name> <param-value>servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</param-value> <description>The servlet server invoker</description> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>SSLServerInvokerServlet</servlet-name> <description>The ServerInvokerServlet receives requests via HTTPS protocol from within a web container and passes it onto the ServletServerInvoker for processing. </description> <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class> <init-param> <param-name>locatorUrl</param-name> <param-value>sslservlet://${jboss.bind.address}:8443/servlet-invoker/SSLServerInvokerServlet</param-value> <description>The servlet server invoker</description> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ServerInvokerServlet</servlet-name> <url-pattern>/ServerInvokerServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>SSLServerInvokerServlet</servlet-name> <url-pattern>/SSLServerInvokerServlet/*</url-pattern> </servlet-mapping> </web-app>
locatorUrl is used to connect the servlet to the remoting connector through the " InvokerLocator attribute of the remoting connector we define in Procedure 15.8, “Configure secure remoting connector for RMI via HTTPS” .
servlet-invoker-service.xml in jboss-as/server/$PROFILE/deploy/, with the following content:
<?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=connector,transport=servlet" display-name="Servlet transport Connector"> <attribute name="InvokerLocator">servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</attribute> <attribute name="Configuration"> <handlers> <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler> </handlers> </attribute> </mbean> <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=connector,transport=sslservlet" display-name="Servlet transport Connector"> <attribute name="InvokerLocator">sslservlet://${jboss.bind.address}:8443/servlet-invoker/SSLServerInvokerServlet</attribute> <attribute name="Configuration"> <handlers> <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler> </handlers> </attribute> </mbean> </server>
// RMI tunneled over HTTPS @Stateless @RemoteBinding(clientBindUrl = "https://0.0.0.0:8443/servlet-invoker/SSLServerInvokerServlet") @Remote(Calculator.class) @SecurityDomain("other") public class CalculatorHttpsBean implements Calculator { ....
// RMI tunneled over HTTP @Stateless @RemoteBinding(clientBindUrl = "http://0.0.0.0:8080/servlet-invoker/ServerInvokerServlet") @Remote(Calculator.class) @SecurityDomain("other") public class CalculatorHttpBean extends CalculatorImpl { ....
Properties props = new Properties(); props.put("java.naming.factory.initial", "org.jboss.naming.HttpNamingContextFactory"); props.put("java.naming.provider.url", "https://localhost:8443/invoker/JNDIFactory"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming"); Context ctx = new InitialContext(props); props.put(Context.SECURITY_PRINCIPAL, username); props.put(Context.SECURITY_CREDENTIALS, password); Calculator calculator = (Calculator) ctx.lookup(jndiName); // use the bean to do any operations
Properties props = new Properties(); props.put("java.naming.factory.initial", "org.jboss.naming.HttpNamingContextFactory"); props.put("java.naming.provider.url", "http://localhost:8080/invoker/JNDIFactory"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming"); Context ctx = new InitialContext(props); props.put(Context.SECURITY_PRINCIPAL, username); props.put(Context.SECURITY_CREDENTIALS, password); Calculator calculator = (Calculator) ctx.lookup(jndiName); // use the bean to do any operations
user name and password values correspond to a valid user name and password for the security domain that is used to secure the http-invoker. This security domain is set in jboss-as/$PROFILE/deploy/http-invoker.sar/invoker.war/WEB-INF/jboss-web.xml .
$JBOSS_HOME/server/deploy/remoting-jboss-beans.xml file of a JBoss Application Server profile. Add the following SSL Socket Factory bean and an SSL Domain bean in this file.
<bean name="sslServerSocketFactoryEJB2" class="org.jboss.security.ssl.DomainServerSocketFactory"> <constructor> <parameter><inject bean="EJB2SSLDomain"/></parameter> </constructor> </bean> <bean name="EJB2SSLDomain" class="org.jboss.security.plugins.JaasSecurityDomain"> <constructor> <parameter>EJB2SSLDomain</parameter> </constructor> <property name="keyStoreURL">resource:localhost.keystore</property> <property name="keyStorePass">changeit</property> <property name="keyAlias">ejb-ssl</property> <property name="keyPassword">EJB-SSL_KEYPAIR_PASSWORD</property> </bean>
$JBOSS_HOME/server/$PROFILE/conf/jboss-service.xml file of a JBoss Application Server profile:
<!-- This section is for custom (SSL) server socket factory --> <mbean code="org.jboss.remoting.security.SSLSocketBuilder" name="jboss.remoting:service=SocketBuilder,type=SSL" display-name="SSL Server Socket Factory Builder"> <!-- IMPORTANT - If making ANY customizations, this MUST be set to false. --> <!-- Otherwise, will used default settings and the following attributes will be ignored. --> <attribute name="UseSSLServerSocketFactory">false</attribute> <!-- This is the url string to the key store to use --> <attribute name="KeyStoreURL">localhost.keystore</attribute> <!-- The password for the key store --> <attribute name="KeyStorePassword">sslsocket</attribute> <!-- The password for the keys (will use KeystorePassword if this is not set explicitly. --> <attribute name="KeyPassword">sslsocket</attribute> <!-- The protocol for the SSLContext. Default is TLS. --> <attribute name="SecureSocketProtocol">TLS</attribute> <!-- The algorithm for the key manager factory. Default is SunX509. --> <attribute name="KeyManagementAlgorithm">SunX509</attribute> <!-- The type to be used for the key store. --> <!-- Defaults to JKS. Some acceptable values are JKS (Java Keystore - Sun's keystore format), --> <!-- JCEKS (Java Cryptography Extension keystore - More secure version of JKS), and --> <!-- PKCS12 (Public-Key Cryptography Standards #12 keystore - RSA's Personal Information Exchange Syntax Standard). --> <!-- These are not case sensitive. --> <attribute name="KeyStoreType">JKS</attribute> </mbean> <mbean code="org.jboss.remoting.security.SSLServerSocketFactoryService" name="jboss.remoting:service=ServerSocketFactory,type=SSL" display-name="SSL Server Socket Factory"> <depends optional-attribute-name="SSLSocketBuilder" proxy-type="attribute">jboss.remoting:service=SocketBuilder,type=SSL</depends> </mbean>
deploy/remoting-jboss-beans.xml file in the JBoss Application Server profile, update the code to reflect the information below:
... <bean name="UnifiedInvokerConnector" class="org.jboss.remoting.transport.Connector"> <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=Connector,transport=socket", exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,registerDirectly=true) </annotation> <property name="serverConfiguration"><inject bean="UnifiedInvokerConfiguration"/></property> <property name="serverSocketFactory"><inject bean="sslServerSocketFactoryEJB2"/></property> <!-- add this to configure the SSL socket for the UnifiedInvoker --> </bean> ... <bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration"> <constructor> <!-- transport: Others include sslsocket, bisocket, sslbisocket, http, https, rmi, sslrmi, servlet, sslservlet. --> <parameter>sslsocket</parameter><!-- changed from socket to sslsocket --> </constructor> ... </bean> ...
jboss in a key store at jboss-as/bin/password/password.keystore.
jboss-as/bin/password directory.
keytool to generate the key pair with the following command:
keytool -genkey -alias jboss -keyalg RSA -keysize 1024 -keystore password.keystorechown command to change ownership to the JBoss Application Server process owner, and chmod 600 password.keystore to make the file readable only by the owner.
keytool command, refer to Section 15.1, “SSL Encryption overview”.
password_tool. This tool will encrypt and store your key store password. Your key store password will then be available to the JBoss Password Tool for masking passwords, and to the JBoss Application Server for decrypting them at run time.
jboss-as/bin directory.
./password_tool.sh for Unix-based systems, or password_tool.bat for Windows-based systems.
Keystore is null. Please specify keystore below:'.
0: Encrypt Keystore Password' by pressing 0, then Enter.
Enter keystore password'.
Enter Salt (String should be at least 8 characters)'.
Enter Iterator Count (integer value)'.
Keystore Password encrypted into password/jboss_keystore_pass.dat'.
5:Exit' to exit.
Keystore is null. Cannot store.'. This is normal.
password/jboss_keystore_pass.dat readable by the JBoss Application Server process owner only.
chown command to change ownership to the JBoss Application Server process owner, and chmod 600 jboss-keystore_pass.dat to make the file readable only by the owner.
jboss-keystore_pass.dat file and repeat the procedure. Be aware that if you change the key store any masked passwords that were previously generated will no longer function.
jboss-as/bin/password/jboss_password_enc.dat. This file is encrypted using a key pair you provide to the password tool, and it contains the passwords that will be masked in configuration files. Passwords are stored and retrieved from this file by 'domain', an arbitrary unique identifier that you specify to the Password Tool when storing the password, and that you specify as part of the annotation that replaces that clear text password in configuration files. This allows the JBoss Application Server to retrieve the correct password from the file at run time.
jboss-as/bin/password/password.keystore) and encrypted key store password file (jboss-as/bin/password/jboss_keystore_pass.dat) readable by your user, and the encrypted passwords file jboss-as/bin/password/jboss_password_enc.dat (if it already exists) read and writeable, while you perform this operation.
jboss-as/bin directory.
./password_tool.sh for Unix-based systems, or password_tool.bat for Windows-based systems.
Keystore is null. Please specify keystore below:'.
1:Specify KeyStore' by pressing 1 then Enter.
Enter Keystore location including the file name'.
jboss-as/bin. This should be password/password.keystore, unless you have performed an advanced installation and changed the defaults as per Section 16.6, “Changing the password masking defaults”.
Enter Keystore alias'.
jboss, unless you have performed an advanced installation and changed the defaults as per Section 16.6, “Changing the password masking defaults”.
Loading domains [', followed by any existing password masks, and the main menu.
2:Create Password' by pressing 2, then Enter
Enter security domain:'.
Enter passwd:'.
Password created for domain:mask name'
5:Exit'
<annotation>@org.jboss.security.integration.password.Password(securityDomain=MASK_NAME, methodName=setPROPERTY_NAME)</annotation>
deploy/messaging/messaging-jboss-beans.xml. If you create a password mask named "messaging", then the before and after snippet of the configuration file looks like this:
<property name="suckerPassword">CHANGE ME!!</property>
<annotation>@org.jboss.security.integration.password.Password(securityDomain=messaging, methodName=setSuckerPassword)</annotation>
jboss-as/bin/password/password.keystore, and the key alias jboss. If you store the key pair used for password masking elsewhere, or under a different alias, you will need to update the server profiles with the new location or key alias.
deploy/security/security-jboss-beans.xml under each of the included JBoss Application Server server profiles.
<!-- Password Mask Management Bean-->
<bean name="JBossSecurityPasswordMaskManagement"
class="org.jboss.security.integration.password.PasswordMaskManagement" >
<property name="keyStoreLocation">password/password.keystore</property>
<property name="keyStoreAlias">jboss</property>
<property name="passwordEncryptedFileName">password/jboss_password_enc.dat</property>
<property name="keyStorePasswordEncryptedFileName">password/jboss_keystore_pass.dat</property>
</bean>
*-ds.xml data source files. These database connection details include clear text passwords. You can increase the security of your server by replacing clear text passwords in data source files with encrypted passwords.
SecureIdentityLoginModule is described in Section 17.1, “Secured Identity”.
JaasSecurityDomainIdentityLoginModule is described in Section 17.1, “Secured Identity”.
org.jboss.resource.security.SecureIdentityLoginModule can be used to both encrypt database passwords and to provide a decrypted version of the password when the data source configuration is required by the server. The SecureIdentityLoginModule uses a hard-coded password to encrypt/decrypt the data source password.
SecureIdentityLoginModule main method by passing in the clear text password. The SecureIdentityLoginModule is provided by jbosssx.jar.
jboss-as directory
PASSWORD:
java -cp client/jboss-logging-spi.jar:common/lib/jbosssx.jar \
org.jboss.resource.security.SecureIdentityLoginModule PASSWORD
java -cp client\jboss-logging-spi.jar;common\lib\jbosssx.jar \
org.jboss.resource.security.SecureIdentityLoginModule PASSWORD
jboss-as directory
java -cp client/jboss-logging-spi.jar:lib/jbosssx.jar \
org.jboss.resource.security.SecureIdentityLoginModule PASSWORD
java -cp client\jboss-logging-spi.jar;lib\jbosssx.jar \
org.jboss.resource.security.SecureIdentityLoginModule PASSWORD
conf/login-config.xml file, where application authentication policies are defined for that profile. To create an application authentication policy for your encrypted password, add a new <application-policy> element to the <policy> element.
login-config.xml file showing an application authentication policy of name "EncryptDBPassword".
<policy> ... <!-- Example usage of the SecureIdentityLoginModule --> <application-policy name="EncryptDBPassword"> <authentication> <login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required"> <module-option name="username">admin</module-option> <module-option name="password">5dfc52b51bd35553df8592078de921bc</module-option> <module-option name="managedConnectionFactoryName">jboss.jca:name=PostgresDS,service=LocalTxCM</module-option> </login-module> </authentication> </application-policy> </policy>
*-ds.xml file. Remove the <user-name> and <password> elements from this file, and replace them with a <security-domain> element. This element will contain the application authentication policy name specified following Section 17.1.2, “Create an application authentication policy with the encrypted password”.
<?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>PostgresDS</jndi-name> <connection-url>jdbc:postgresql://127.0.0.1:5432/test?protocolVersion=2</connection-url> <driver-class>org.postgresql.Driver</driver-class> <min-pool-size>1</min-pool-size> <max-pool-size>20</max-pool-size> <!-- REPLACED WITH security-domain BELOW <user-name>admin</user-name> <password>password</password> --> <security-domain>EncryptDBPassword</security-domain> <metadata> <type-mapping>PostgreSQL 8.0</type-mapping> </metadata> </local-tx-datasource> </datasources>
org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule is a login module for statically defining a data source using a password that has been encrypted by a JaasSecurityDomain. The base64 format of the data source password may be generated using PBEUtils:
java -cp jboss-as/common/lib/jbosssx.jar org.jboss.security.plugins.PBEUtils \saltcountdomain-passworddata-source-password
java -cp jboss-as/lib/jbosssx.jar org.jboss.security.plugins.PBEUtils \saltcountdomain-passworddata-source-password
PBEUtils are:
java -cp jbosssx.jar org.jboss.security.plugins.PBEUtils abcdefgh 13 master password Encoded password: 3zbEkBDfpQAASa3H39pIyP
$JBOSS_HOME/server/$PROFILE/conf/login-config.xml file.
<application-policy name="EncryptedHsqlDbRealm"> <authentication> <login-module code= "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule" flag = "required"> <module-option name="username">sa</module-option> <module-option name="password">E5gtGMKcXPP</module-option> <module-option name="managedConnectionFactoryName"> jboss.jca:service=LocalTxCM,name=DefaultDS </module-option> <module-option name="jaasSecurityDomain"> jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword </module-option> </login-module> </authentication> </application-policy>
$JBOSS_HOME/docs/examples/jca/hsqldb-encrypted-ds.xml illustrates that data source configuration along with the JaasSecurityDomain configuration for the keystore:
.../conf/server.password. You first need to run the following command, which will store the encryption details and obfuscated master password:
java -cp jboss-as/lib/jbosssx.jar org.jboss.security.plugins.FilePasswordsaltcountmaster_passwordpassword_fileFor example: java -cp jboss-as/lib/jbosssx.jar org.jboss.security.plugins.FilePassword abcdefgh 13 master jboss-as/server/$PROFILE/conf/server.password
<?xml version="1.0" encoding="UTF-8"?> <!-- The Hypersonic embedded database JCA connection factory config that illustrates the use of the JaasSecurityDomainIdentityLoginModule to use encrypted password in the data source configuration. $Id: hsqldb-encrypted-ds.xml,v 1.1.2.1 2004/06/04 02:20:52 starksm Exp $ --> <datasources> ... <application-policy name="EncryptedHsqlDbRealm"> <authentication> <login-module code="org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule" flag = "required"> <module-option name="username">sa</module-option> <module-option name="password">E5gtGMKcXPP</module-option> <module-option name="managedConnectionFactoryName"> jboss.jca:service=LocalTxCM,name=DefaultDS </module-option> <module-option name="jaasSecurityDomain"> jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword </module-option> </login-module> </authentication> </application-policy> <mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=JaasSecurityDomain, domain=ServerMasterPassword"> <constructor> <arg type="java.lang.String" value="ServerMasterPassword"></arg> </constructor> <!-- The opaque master password file used to decrypt the encrypted database password key --> <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/server.password</attribute> <attribute name="Salt">abcdefgh</attribute> <attribute name="IterationCount">13</attribute> </mbean> <!-- This mbean can be used when using in process persistent db --> <mbean code="org.jboss.jdbc.HypersonicDatabase" name="jboss:service=Hypersonic,database=localDB"> <attribute name="Database">localDB</attribute> <attribute name="InProcessMode">true</attribute> </mbean> ... </datasources>
java.security.InvalidAlgorithmParameterException: Parameters missing is raised when the following MBean is not yet started as a service:
(jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword)
hsqldb-encrypted-ds.xml code shown previously.
<depends>jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</depends>
server.xml file.
Append connector element
server.xml in $JBOSS_HOME/server/$PROFILE/deploy/jbossweb.sar
<!-- SSL/TLS Connector with encrypted keystore password configuration --> <Connector port="8443" address="${jboss.bind.address}" maxThreads="100" minSpareThreads="5" maxSpareThreads="15" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" securityDomain="java:/jaas/encrypt-keystore-password" SSLImplementation="org.jboss.net.ssl.JBossImplementation" > </Connector>.
Configure JaasSecurityDomain MBean
$JBOSS_HOME/server/$PROFILE/deploy/security-service.xml file.
security-service.xml, append the <mbean> element block to the file.
<server> <mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=PBESecurityDomain"> <constructor> <arg type="java.lang.String" value="encrypt-keystore-password"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/keystore.password</attribute> <attribute name="Salt">welcometojboss</attribute> <attribute name="IterationCount">13</attribute> </mbean> </server>
Generate encrypted password
jboss-as/server/$PROFILE/conf/localhost.keystore file. The <mbean> also specifies the encrypted password file is stored in jboss-as/server/$PROFILE/conf/keystore.password file.
localhost.keystore file.
jboss-as/server/$PROFILE/conf directory.
[conf]$ java -cp $JBOSS_HOME/lib/jbosssx.jar \org.jboss.security.plugins.FilePassword welcometojboss 13 unit-tests-server keystore.password
-cp) and the FilePassword security plugin to create a keystore.password file with the password set as unit-tests-server. To verify you have permission to create a keystore.password file, you supply the salt and iteration parameters configured in the <mbean> <attribute> elements of the JaasSecurityDomain.
/conf directory so the keystore.password file is saved to this directory.
Update the Tomcat service MBean
$JBOSS_HOME/server/$PROFILE/deploy/jbossweb.sar/META-INF .
jboss-beans.xml and append the following <depends> tag toward the end of the file. Adding the <depends> tag specifies that Tomcat must start after jboss.security:service=PBESecurityDomain .
<!-- Transaction manager for unfinished transaction checking in the CachedConnectionValve --> <depends>jboss:service=TransactionManager</depends> <depends>jboss.security:service=PBESecurityDomain</depends> <!-- Inject the TomcatDeployer -->
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=PBESecurityDomain"> <constructor> <arg type="java.lang.String" value="encrypt-keystore-password"></arg> </constructor> <attribute name="KeyStoreType">pkcs12</attribute> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/keystore.password</attribute> <attribute name="Salt">welcometojboss</attribute> <attribute name="IterationCount">13</attribute> </mbean>
server.xml ) or wants to make use of a predefined JaasSecurityDomain.
Update jboss-service.xml to add a connector
$JBOSS_HOME/server/ $PROFILE /deploy/jbossweb.sar/META-INF, and add the following code block to the jboss-service.xml file.
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=SecurityDomain"> <constructor> <arg type="java.lang.String" value="jbosstest-ssl"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">unit-tests-server</attribute> </mbean>
Add a <depends> tag to the Tomcat service
$JBOSS_HOME/server/$PROFILE/deploy/jbossweb.sar .
server.xml and append the following <depends> element toward the end of the file:
<depends>jboss.security:service=SecurityDomain</depends> </mbean> </server>
Define the JaasSecurityDomain MBean in a *-service.xml file
security-service.xml in the deploy directory, for example.
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=SecurityDomain"> <constructor> <arg type="java.lang.String" value="jbosstest-ssl"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">unit-tests-server</attribute> </mbean>
Define JaasSecurityDomain MBean
JBOSS_HOME/server/PROFILE/conf/jboss-service.xml, or to a *-service.xml deployment descriptor in the JBOSS_HOME/server/ PROFILE /deploy folder.
<mbean code="org.jboss.security.plugins.JaasSecurityDomain"
name="jboss.security:service=JaasSecurityDomain,domain=jmx-console">
<constructor>
<arg type="java.lang.String" value="jmx-console"></arg>
</constructor>
<attribute name="KeyStorePass">some_password</attribute>
<attribute name="Salt">abcdefgh</attribute>
<attribute name="IterationCount">66</attribute>
</mbean>
PBEwithMD5andDES. Other cipher algorithms include DES, TripleDES, Blowfish, and PBEWithMD5AndTripleDES. All algorithms are symmetric algorithms. You specify a cipher algorithm by appending an <attribute> element with the CypherElement attribute set to one of these values.
Adjust password, salt, and iteration count
Start the platform
[bin]$ ./run.sh -c PROFILEOpen the JMX Console
org.jboss.security.plugins.JaasSecurityDomain MBean.
Invoke the LdapExtLoginModule
org.jboss.security.plugins.JaasSecurityDomain page, find the encode64(String password) method.
password the LdapExtLoginModule will use to this method.
encode64(String password) method.
Configure Login Module
<module-option name="jaasSecurityDomain">jboss.security:service=JaasSecurityDomain,domain=jmx-console</module-option> <module-option name="bindCredential">2gx7gcAxcDuaHaJMgO5AVo</module-option>
bindCredential is replaced with the encrypted Base64 password obtained in Step 5.
| Port | Type | Description | Service |
|---|---|---|---|
| 1090 | TCP | RMI/JRMP port for connecting to the JMX MBeanServer | jboss.remoting:service=JMXConnectorServer,protocol=rmi |
| 1098 | TCP | Naming service port for RMI requests from client proxies | jboss:service=Naming |
| 1099 | TCP | Naming service port | jboss:service=Naming |
| 1100 | TCP | Port for the HA-JNDI service | jboss:service=HAJNDI |
| 1101 | TCP | HA-JNDI service port for RMI requests from client proxies | jboss:service=HAJNDI |
| 1102 | UDP | HA-JNDI multicast port for auto-discovery requests | jboss:service=HAJNDI |
| 1161 | UDP | Port for the SNMP adaptor MBean | jboss.jmx:name=SnmpAgent,service=snmp,type=adaptor |
| 1162 | UDP | Port for the SNMP trap receiver | jboss.jmx:name=SnmpAgent,service=trapd,type=logger |
| 3528 | TCP | IIOP port for the Corba ORB | jboss:service=CorbaORB |
| 3873 | TCP | EJB3 Remoting Connector Port | jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3 |
| 4444 | TCP | Port for the legacy RMI/JRMP invoker | jboss:service=invoker,type=jrmp |
| 4445 | TCP | Port for the legacy Pooled invoker | jboss:service=invoker,type=pooled |
| 4446 | TCP | Port for JBoss Remoting Connector of UnifiedInvoker | UnifiedInvokerConnector |
| 4447 | TCP | Port for the high-availability version of the legacy RMI/JRMP invoker | jboss:service=invoker,type=jrmpha |
| 4448 | TCP | Port for the high-availability version of the legacy Pooled invoker | jboss:service=invoker,type=pooledha |
| 4457 | TCP | Port for JBoss Messaging 1.x | jboss.messaging:service=Connector,transport=bisocket |
| 4712 | TCP | Port for JBoss TS Recovery Manager | TransactionManager |
| 4713 | TCP | Port for JBossTS Transaction Status Manager | TransactionManager |
| 4714 | TCP | Port for provision of unique process id for JBossTS | TransactionManager |
| 5445 | TCP | Port for JBoss Messaging 2.x/HornetQ; | JBM2/HornetQ |
| 5446 | TCP | SSL port for JBoss Messaging 2.x/HornetQ | JBM2/HornetQ |
| 5455 | TCP | HornetQ batch port; refer to Configuring the Netty transport in HornetQ User Guide | HornetQ |
| 5465 | TCP | HornetQ backup server port | HornetQ |
| 5466 | TCP | Backup SSL port for HornetQ | HornetQ |
| 5475 | TCP | Backup batch port for HornetQ | HornetQ |
| 7500 | TCP | Multicast port on which JGroups listens for diagnostic requests from its Probe utility | JGroups |
| 7600 | TCP |
Port used for the JGroups tcp stack
| JGroups |
| 7650 | TCP |
Port used by the JGroups tcp-sync stack
| JGroups |
| 7900 | TCP |
Port used by the JGroups jbm-data. This port is used by cluster nodes to communicate with each other and is not usually firewalled. If this option is desireable, keep in mind that other UDP ports may also need to be opened.
| JGroups |
| 8009 | TCP | Port for AJP connector | jboss:service=WebService |
| 8080 | TCP | JBoss Web HTTP connector port (drives also the values for the HTTPS and AJP sockets) | jboss.web:service=WebServer |
| 8083 | TCP | Port for dynamic class and resource loading | jboss:service=WebService |
| 8443 | TCP | Port for JBoss Web HTTPS connector | jboss.web:service=WebServer |
| 45688 | UDP |
Multicast port for JGroups udp stack communication
| JGroups |
| 45689 | UDP |
Multicast port for communication of the JGroups udp-async stack
| JGroups |
| 45699 | UDP |
Multicast port for communication of the JGroups udp-sync stack
| JGroups |
| 45700 | TCP |
Multicast port on which JGroups tcp stack performs discovery
| JGroups |
| 45701 | TCP |
Multicast port on which JGroups tcp-sync stack performs discovery
| JGroups |
| 45710 | UDP |
Multicast port on which JGroups jbm-data stack performs discovery
| JGroups |
| 53200 | TCP |
Port used by the FD_SOCK protocol in the JGroups jbm_control stack
| JGroups |
| 54200 | TCP |
Port used by the FD_SOCK protocol in the JGroups udp stack
| JGroups |
| 54225 | UDP |
Port used by the FD_SOCK protocol in the JGroups udp-async stack
| JGroups |
| 55200 | UDP |
Port for JGroups udp stack
| JGroups |
| 55225 | UDP |
Port used by the JGroups udp-async stack
| JGroups |
| 55250 | UDP |
Port used by the JGroups udp-sync stack
| JGroups |
| 57600 | UDP |
Port used by the FD_SOCK protocol in the JGroups udp stack
| JGroups |
| 57650 | TCP |
Port used by the FD_SOCK protocol in the JGroups tcp-sync stack
| JGroups |
| 57900 | TCP |
Port used by the FD_SOCK protocol in the JGroups jbm-data stack
| JGroups |
jmx-console.war found in the deploy directory provides an HTML view into the JMX Microkernel. As such, it provides access to administrative actions like shutting down the server, stopping services, deploying new services, etc. It should either be secured like any other web application, or removed.
http-invoker.sar found in the deploy directory is a service that provides RMI/HTTP access for EJBs and the JNDI Naming service. This includes a servlet that processes posts of marshaled org.jboss.invocation.Invocation objects that represent invocations that should be dispatched onto the MBeanServer. Effectively this allows access to MBeans that support the detached invoker operation via HTTP POST requests. Securing this access point involves securing the JMXInvokerServlet servlet found in the http-invoker.sar/invoker.war/WEB-INF/web.xml descriptor. There is a secure mapping defined for the /restricted/JMXInvokerServlet path by default. Remove the other paths and configure the http-invoker security domain setup in the http-invoker.sar/invoker.war/WEB-INF/jboss-web.xml deployment descriptor.
jmx-invoker-service.xml is a configuration file that exposes the JMX MBeanServer interface via an RMI compatible interface using the RMI/JRMP detached invoker service.

Invoker interface illustrates the generic invoke operation.
package org.jboss.invocation; import java.rmi.Remote; import org.jboss.proxy.Interceptor; import org.jboss.util.id.GUID; public interface Invoker extends Remote { GUID ID = new GUID(); String getServerHostName() throws Exception; Object invoke(Invocation invocation) throws Exception; }
Remote to be compatible with RMI, but this does not mean that an invoker must expose an RMI service stub. The detached invoker service acts as a transport gateway that accepts invocations represented as the org.jboss.invocation.Invocation object over its specific transport. The invoker service unmarshalls the invocation, forwards the invocation onto the destination MBean service represented by the Target MBean in Figure 21.1, “The main components in the detached invoker architecture”, and marshalls the return value or exception resulting from the forwarded call back to the client.
Invocation object is just a representation of a method invocation context. This includes the target MBean name, the method, the method arguments, a context of information associated with the proxy by the proxy factory, and an arbitrary map of data associated with the invocation by the client proxy interceptors.
public Object invoke(org.jboss.invocation.Invocation) throws Exception
HashMap<Long, Method> mapping from the exposed interface java.lang.reflect.Methods to the long hash representation using the org.jboss.invocation.MarshalledInvocation.calculateHash method.
invoke(Invocation) JMX operation and use the interface method hash mapping to transform from the long hash representation of the invoked method to the java.lang.reflect.Method of the exposed interface. Reflection is used to perform the actual invocation on the object associated with the MBean service that actually implements the exposed interface.
org.jboss.jmx.connector.invoker.InvokerAdaptorService and its configuration for access via RMI/JRMP as an example of the steps required to provide remote access to an MBean service.
InvokerAdaptorService is a simple MBean service that exists to fulfill the target MBean role in the detached invoker pattern.
package org.jboss.jmx.connector.invoker; public interface InvokerAdaptorServiceMBean extends org.jboss.system.ServiceMBean { Class getExportedInterface(); void setExportedInterface(Class exportedInterface); Object invoke(org.jboss.invocation.Invocation invocation) throws Exception; } package org.jboss.jmx.connector.invoker; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.UndeclaredThrowableException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServer; import javax.management.ObjectName; import org.jboss.invocation.Invocation; import org.jboss.invocation.MarshalledInvocation; import org.jboss.mx.server.ServerConstants; import org.jboss.system.ServiceMBeanSupport; import org.jboss.system.Registry; public class InvokerAdaptorService extends ServiceMBeanSupport implements InvokerAdaptorServiceMBean, ServerConstants { private static ObjectName mbeanRegistry; static { try { mbeanRegistry = new ObjectName(MBEAN_REGISTRY); } catch (Exception e) { throw new RuntimeException(e.toString()); } } private Map marshalledInvocationMapping = new HashMap(); private Class exportedInterface; public Class getExportedInterface() { return exportedInterface; } public void setExportedInterface(Class exportedInterface) { this.exportedInterface = exportedInterface; } protected void startService() throws Exception { // Build the interface method map Method[] methods = exportedInterface.getMethods(); HashMap tmpMap = new HashMap(methods.length); for (int m = 0; m < methods.length; m ++) { Method method = methods[m]; Long hash = new Long(MarshalledInvocation.calculateHash(method)); tmpMap.put(hash, method); } marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap); // Place our ObjectName hash into the Registry so invokers can // resolve it Registry.bind(new Integer(serviceName.hashCode()), serviceName); } protected void stopService() throws Exception { Registry.unbind(new Integer(serviceName.hashCode())); } public Object invoke(Invocation invocation) throws Exception { // Make sure we have the correct classloader before unmarshalling Thread thread = Thread.currentThread(); ClassLoader oldCL = thread.getContextClassLoader(); // Get the MBean this operation applies to ClassLoader newCL = null; ObjectName objectName = (ObjectName) invocation.getValue("JMX_OBJECT_NAME"); if (objectName != null) { // Obtain the ClassLoader associated with the MBean deployment newCL = (ClassLoader) server.invoke(mbeanRegistry, "getValue", new Object[] { objectName, CLASSLOADER }, new String[] { ObjectName.class.getName(), "java.lang.String" }); } if (newCL != null && newCL != oldCL) { thread.setContextClassLoader(newCL); } try { // Set the method hash to Method mapping if (invocation instanceof MarshalledInvocation) { MarshalledInvocation mi = (MarshalledInvocation) invocation; mi.setMethodMap(marshalledInvocationMapping); } // Invoke the MBeanServer method via reflection Method method = invocation.getMethod(); Object[] args = invocation.getArguments(); Object value = null; try { String name = method.getName(); Class[] sig = method.getParameterTypes(); Method mbeanServerMethod = MBeanServer.class.getMethod(name, sig); value = mbeanServerMethod.invoke(server, args); } catch(InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof Exception) { throw (Exception) t; } else { throw new UndeclaredThrowableException(t, method.toString()); } } return value; } finally { if (newCL != null && newCL != oldCL) { thread.setContextClassLoader(oldCL); } } } }
InvokerAdaptorServiceMBean, the code has been split into logical blocks, with commentary about how each block operates.
package org.jboss.jmx.connector.invoker; public interface InvokerAdaptorServiceMBean extends org.jboss.system.ServiceMBean { Class getExportedInterface(); void setExportedInterface(Class exportedInterface); Object invoke(org.jboss.invocation.Invocation invocation) throws Exception; } package org.jboss.jmx.connector.invoker; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.UndeclaredThrowableException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServer; import javax.management.ObjectName; import org.jboss.invocation.Invocation; import org.jboss.invocation.MarshalledInvocation; import org.jboss.mx.server.ServerConstants; import org.jboss.system.ServiceMBeanSupport; import org.jboss.system.Registry; public class InvokerAdaptorService extends ServiceMBeanSupport implements InvokerAdaptorServiceMBean, ServerConstants { private static ObjectName mbeanRegistry; static { try { mbeanRegistry = new ObjectName(MBEAN_REGISTRY); } catch (Exception e) { throw new RuntimeException(e.toString()); } } private Map marshalledInvocationMapping = new HashMap(); private Class exportedInterface; public Class getExportedInterface() { return exportedInterface; } public void setExportedInterface(Class exportedInterface) { this.exportedInterface = exportedInterface; } ...
InvokerAdaptorServiceMBean Standard MBean interface of the InvokerAdaptorService has a single ExportedInterface attribute and a single invoke(Invocation) operation.
ExportedInterface MBeanServer class in terms of method name and signature.
invoke(Invocation) InvokerAdaptorService.
protected void startService() throws Exception { // Build the interface method map Method[] methods = exportedInterface.getMethods(); HashMap tmpMap = new HashMap(methods.length); for (int m = 0; m < methods.length; m ++) { Method method = methods[m]; Long hash = new Long(MarshalledInvocation.calculateHash(method)); tmpMap.put(hash, method); } marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap); // Place our ObjectName hash into the Registry so invokers can // resolve it Registry.bind(new Integer(serviceName.hashCode()), serviceName); } protected void stopService() throws Exception { Registry.unbind(new Integer(serviceName.hashCode())); }
exportedInterface Class using the org.jboss.invocation.MarshalledInvocation.calculateHash(Method) utility method.
java.lang.reflect.Method instances are not serializable, a MarshalledInvocation version of the non-serializable Invocation class is used to marshall the invocation between the client and server. The MarshalledInvocation replaces the Method instances with their corresponding hash representation. On the server side, the MarshalledInvocation must be told what the hash to Method mapping is.
InvokerAdaptorService service name and its hash code representation. This is used by detached invokers to determine what the target MBean ObjectName of an Invocation is.
Invocation, its store as its hashCode because ObjectNames are relatively expensive objects to create. The org.jboss.system.Registry is a global map like construct that invokers use to store the hash code to ObjectName mappings in.
public Object invoke(Invocation invocation) throws Exception { // Make sure we have the correct classloader before unmarshalling Thread thread = Thread.currentThread(); ClassLoader oldCL = thread.getContextClassLoader(); // Get the MBean this operation applies to ClassLoader newCL = null; ObjectName objectName = (ObjectName) invocation.getValue("JMX_OBJECT_NAME"); if (objectName != null) { // Obtain the ClassLoader associated with the MBean deployment newCL = (ClassLoader) server.invoke(mbeanRegistry, "getValue", new Object[] { objectName, CLASSLOADER }, new String[] { ObjectName.class.getName(), "java.lang.String" }); } if (newCL != null && newCL != oldCL) { thread.setContextClassLoader(newCL); }
org.jboss.mx.server.registry.BasicMBeanRegistry, a JBoss JMX implementation-specific class.
... try { // Set the method hash to Method mapping if (invocation instanceof MarshalledInvocation) { MarshalledInvocation mi = (MarshalledInvocation) invocation; mi.setMethodMap(marshalledInvocationMapping); } ...
ExposedInterface class method hash to method mapping if the invocation argument is of type MarshalledInvocation. The method mapping calculated in Example 21.3, “Block Two”is used here.
ExposedInterface method to the matching method of the MBeanServer class. The InvokerServiceAdaptor decouples the ExposedInterface from the MBeanServer class in that it allows an arbitrary interface. This is required because the standard java.lang.reflect.Proxy class can only proxy interfaces. It also allows you to only expose a subset of the MBeanServer methods and add transport specific exceptions such as java.rmi.RemoteException to the ExposedInterface method signatures.
... // Invoke the MBeanServer method via reflection Method method = invocation.getMethod(); Object[] args = invocation.getArguments(); Object value = null; try { String name = method.getName(); Class[] sig = method.getParameterTypes(); Method mbeanServerMethod = MBeanServer.class.getMethod(name, sig); value = mbeanServerMethod.invoke(server, args); } catch(InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof Exception) { throw (Exception) t; } else { throw new UndeclaredThrowableException(t, method.toString()); } } return value; } finally { if (newCL != null && newCL != oldCL) { thread.setContextClassLoader(oldCL); } } } }
InvokerAdaptorService MBeanServer instance to which the was deployed. The server instance variable is inherited from the ServiceMBeanSupport superclass.
InvokerAdaptorService MBean does not deal directly with any transport specific details. There is the calculation of the method hash to Method mapping, but this is a transport independent detail.
InvokerAdaptorService may be used to expose the same org.jboss.jmx.adaptor.rmi.RMIAdaptor interface via RMI/JRMP as seen in Connecting to JMX Using RMI.
InvokerAdaptorService configurations found in the default setup in the jmx-invoker-adaptor-service.sar deployment. Example 21.7, “Default jmx-invoker-adaptor-server.sar deployment descriptor” shows the jboss-service.xml descriptor for this deployment.
<server> <!-- The JRMP invoker proxy configuration for the InvokerAdaptorService --> <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory" name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory"> <!-- Use the standard JRMPInvoker from conf/jboss-service.xml --> <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute> <!-- The target MBean is the InvokerAdaptorService configured below --> <attribute name="TargetName">jboss.jmx:type=adaptor,name=Invoker</attribute> <!-- Where to bind the RMIAdaptor proxy --> <attribute name="JndiName">jmx/invoker/RMIAdaptor</attribute> <!-- The RMI compatible MBeanServer interface --> <attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute> <attribute name="ClientInterceptors"> <iterceptors> <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor> <interceptor> org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor </interceptor> <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor> </iterceptors> </attribute> <depends>jboss:service=invoker,type=jrmp</depends> </mbean> <!-- This is the service that handles the RMIAdaptor invocations by routing them to the MBeanServer the service is deployed under. --> <mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService" name="jboss.jmx:type=adaptor,name=Invoker"> <attribute name="ExportedInterface">org.jboss.jmx.adaptor.rmi.RMIAdaptor</attribute> </mbean> </server>
org.jboss.invocation.jrmp.server.JRMPProxyFactory, is the proxy factory MBean service that creates proxies for the RMI/JRMP protocol. The configuration of this service as shown in Example 21.7, “Default jmx-invoker-adaptor-server.sar deployment descriptor” states that the JRMPInvoker will be used as the detached invoker, the InvokerAdaptorService is the target mbean to which requests will be forwarded, that the proxy will expose the RMIAdaptor interface, the proxy will be bound into JNDI under the name jmx/invoker/RMIAdaptor, and the proxy will contain 3 interceptors: ClientMethodInterceptor, InvokerAdaptorClientInterceptor, InvokerInterceptor. The configuration of the InvokerAdaptorService simply sets the RMIAdaptor interface that the service is exposing.
InvokerAdaptorService via RMI/JRMP is the detached invoker. The detached invoker we will use is the standard RMI/JRMP invoker used by the EJB containers for home and remote invocations, and this is the org.jboss.invocation.jrmp.server.JRMPInvoker MBean service configured in the conf/jboss-service.xml descriptor. That we can use the same service instance emphasizes the detached nature of the invokers. The JRMPInvoker simply acts as the RMI/JRMP endpoint for all RMI/JRMP proxies regardless of the interface(s) the proxies expose or the service the proxies utilize.
/usr/sbin/alternatives Utility /usr/sbin/alternatives is a tool for managing different software packages that provide the same functionality. Red Hat Enterprise Linux uses /usr/sbin/alternatives to ensure that only one Java Development Kit is set as the system default at one time.
/usr/sbin/alternatives may contain conflicting configurations. Refer to Procedure A.1, “ Using /usr/sbin/alternatives to Set the Default JDK ” for syntax of the /usr/sbin/alternatives command.
/usr/sbin/alternatives to Set the Default JDK Become the root user.
/usr/sbin/alternatives needs to be run with root privileges. Use the su command or other mechanism to gain these privileges.
Set java.
/usr/sbin/alternatives --config java
java is selected. Table A.1, “java alternative commands” shows the relevant command settings for each of the different JDKs.
java alternative commands| JDK | alternative command |
|---|---|
| OpenJDK 1.6 |
/usr/lib/jvm/jre-1.6.0-openjdk/bin/java
|
| Sun Microsystems JDK 1.6 |
/usr/lib/jvm/jre-1.6.0-sun/bin/java
|
Set javac.
/usr/sbin/alternatives --config javac
javac is selected. Table A.2, “javac alternative commands” shows the appropriate command settings for the different JDKs.
javac alternative commands| JDK | alternative command |
|---|---|
| OpenJDK 1.6 |
/usr/lib/jvm/java-1.6.0-openjdk/bin/javac
|
| Sun Microsystems JDK 1.6 |
/usr/lib/jvm/java-1.6.0-sun/bin/javac
|
Extra Step: Set java_sdk_1.6.0.
/usr/sbin/alternatives --config java_sdk_1.6.0
java_sdk is selected. It is /usr/lib/jvm/java-1.6.0-sun.
| Revision History | |||
|---|---|---|---|
| Revision 5.1.2-100 | Thu 8 December 2011 | ||
| |||