18.4. EJB Application Security
18.4.1. Security Identity
18.4.1.1. About EJB Security Identity
18.4.1.2. Set the Security Identity of an EJB
<security-identity>
tag in the security configuration.
<security-identity>
tag is present - the EJB's own caller identity is used.
Example 18.30. Set the security identity of an EJB to be the same as its caller
<security-identity>
element declaration.
<ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> <!-- ... --> <security-identity> <use-caller-identity/> </security-identity> </session> <!-- ... --> </enterprise-beans> </ejb-jar>
Example 18.31. Set the security identity of an EJB to a specific role
<run-as>
and <role-name>
tags inside the <security-identity>
tag.
<ejb-jar> <enterprise-beans> <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>
<run-as>
, a principal named anonymous
is assigned to outgoing calls. To assign a different principal, uses the <run-as-principal>
.
<session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session>
Note
<run-as>
and <run-as-principal>
elements inside a servlet element.
See also:
18.4.2. EJB Method Permissions
18.4.2.1. About EJB Method Permissions
<method-permission>
element declaration specifies the roles that can invoke the EJB's interface methods. You can specify permissions for the following combinations:
- All home and component interface methods of the named EJB
- A specified method of the home or component interface of the named EJB
- A specified method within a set of methods with an overloaded name
18.4.2.2. Use EJB Method Permissions
The <method-permission>
element defines the logical roles that are allowed to access the EJB methods defined by <method>
elements. Several examples demonstrate the syntax of the XML. Multiple method permission statements may be present, and they have a cumulative effect. The <method-permission>
element is a child of the <assembly-descriptor>
element of the <ejb-jar>
descriptor.
Example 18.32. Allow roles to access all methods of an EJB
<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>
Example 18.33. Allow roles to access only specific methods of an EJB, and limiting which method parameters can be passed.
<method-permission> <description>The employee role may access the findByPrimaryKey, getEmployeeInfo, and the updateEmployeeInfo(String) method of the AcmePayroll bean </description> <role-name>employee</role-name> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>findByPrimaryKey</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>getEmployeeInfo</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>updateEmployeeInfo</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission>
Example 18.34. Allow any authenticated user to access methods of EJBs
<unchecked/>
element allows any authenticated user to use the specified methods.
<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>
Example 18.35. Completely exclude specific EJB methods from being used
<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>
Example 18.36. A complete <assembly-descriptor>
containing several <method-permission>
blocks
<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 AcmePayroll bean </description> <role-name>employee</role-name> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>findByPrimaryKey</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>getEmployeeInfo</method-name> </method> <method> <ejb-name>AcmePayroll</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>
18.4.3. EJB Security Annotations
18.4.3.1. About EJB Security Annotations
javax.annotation.security
annotations are defined in JSR250.
- @DeclareRoles
- Declares which roles are available.
- @RunAs
- Configures the propagated security identity of a component.
18.4.3.2. Use EJB Security Annotations
You can use either XML descriptors or annotations to control which security roles are able to call methods in your Enterprise JavaBeans (EJBs). For information on using XML descriptors, refer to Section 18.4.2.2, “Use EJB Method Permissions”.
Annotations for Controlling Security Permissions of EJBs
- @DeclareRoles
- Use @DeclareRoles to define which security roles to check permissions against. If no @DeclareRoles is present, the list is built automatically from the @RolesAllowed annotation. For information about configuring roles, refer to the Java EE 6 Tutorial Specifying Authorized Users by Declaring Security Roles.
- @RolesAllowed, @PermitAll, @DenyAll
- Use
@RolesAllowed
to list which roles are allowed to access a method or methods. Use@PermitAll
or@DenyAll
to either permit or deny all roles from using a method or methods. For information about configuring annotation method permissions, refer to the Java EE 6 Tutorial Specifying Authorized Users by Declaring Security Roles. - @RunAs
- Use
@RunAs
to specify a role a method uses when making calls from the annotated method. For information about configuring propagated security identities using annotations, refer to the Java EE 6 Tutorial Propagating a Security Identity (Run-As).
Example 18.37. Security Annotations Example
@Stateless @RolesAllowed({"admin"}) @SecurityDomain("other") public class WelcomeEJB implements Welcome { @PermitAll public String WelcomeEveryone(String msg) { return "Welcome to " + msg; } @RunAs("tempemployee") public String GoodBye(String msg) { return "Goodbye, " + msg; } public String GoodbyeAdmin(String msg) { return "See you later, " + msg; } }
WelcomeEveryone
. The GoodBye
method uses the tempemployee
role when making calls. Only the admin
role can access method GoodbyeAdmin
, and any other methods with no security annotation.
18.4.4. Remote Access to EJBs
18.4.4.1. About Remote Method Access
Supported Transport Types
- Socket / Secure Socket
- RMI / RMI over SSL
- HTTP / HTTPS
- Servlet / Secure Servlet
- Bisocket / Secure Bisocket
Warning
The Remoting system also provides data marshalling and unmarshalling services. Data marshalling refers to the ability to safely move data across network and platform boundaries, so that a separate system can perform work on it. The work is then sent back to the original system and behaves as though it were handled locally.
When you design a client application which uses Remoting, you direct your application to communicate with the server by configuring it to use a special type of resource locator called an InvokerLocator
, which is a simple String with a URL-type format. The server listens for requests for remote resources on a connector
, which is configured as part of the remoting
subsystem. The connector
hands the request off to a configured ServerInvocationHandler
. Each ServerInvocationHandler
implements a method invoke(InvocationRequest)
, which knows how to handle the request.
JBoss Remoting Framework Layers
- The user interacts with the outer layer. On the client side, the outer layer is the
Client
class, which sends invocation requests. On the server side, it is the InvocationHandler, which is implemented by the user and receives invocation requests. - The transport is controlled by the invoker layer.
- The lowest layer contains the marshaller and unmarshaller, which convert data formats to wire formats.
18.4.4.2. About Remoting Callbacks
InvocationRequest
to the client. Your server-side code works the same regardless of whether the callback is synchronous or asynchronous. Only the client needs to know the difference. The server's InvocationRequest sends a responseObject
to the client. This is the payload that the client has requested. This may be a direct response to a request or an event notification.
m_listeners
object. It contains a list of all listeners that have been added to your server handler. The ServerInvocationHandler
interface includes methods that allow you to manage this list.
org.jboss.remoting.InvokerCallbackHandler
, which processes the callback data. After implementing the callback handler, you either add yourself as a listener for a pull callback, or implement a callback server for a push callback.
For a pull callback, your client adds itself to the server's list of listeners using the Client.addListener()
method. It then polls the server periodically for synchronous delivery of callback data. This poll is performed using the Client.getCallbacks()
.
A push callback requires your client application to run its own InvocationHandler. To do this, you need to run a Remoting service on the client itself. This is referred to as a callback server. The callback server accepts incoming requests asynchronously and processes them for the requester (in this case, the server). To register your client's callback server with the main server, pass the callback server's InvokerLocator
as the second argument to the addListener
method.
18.4.4.3. About Remoting Server Detection
18.4.4.4. Configure the Remoting Subsystem
JBoss Remoting has three top-level configurable elements: the worker thread pool, one or more connectors, and a series of local and remote connection URIs. This topic presents an explanation of each configurable item, example CLI commands for how to configure each item, and an XML example of a fully-configured subsystem. This configuration only applies to the server. Most people will not need to configure the Remoting subsystem at all, unless they use custom connectors for their own applications. Applications which act as Remoting clients, such as EJBs, need separate configuration to connect to a specific connector.
Note
The CLI commands are formulated for a managed domain, when configuring the default
profile. To configure a different profile, substitute its name. For a standalone server, omit the /profile=default
part of the command.
There are a few configuration aspects which are outside of the remoting
subsystem:
- Network Interface
- The network interface used by the
remoting
subsystem is thepublic
interface defined in thedomain/configuration/domain.xml
orstandalone/configuration/standalone.xml
.<interfaces> <interface name="management"/> <interface name="public"/> <interface name="unsecure"/> </interfaces>
The per-host definition of thepublic
interface is defined in thehost.xml
in the same directory as thedomain.xml
orstandalone.xml
. This interface is also used by several other subsystems. Exercise caution when modifying it.<interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> <interface name="public"> <inet-address value="${jboss.bind.address:127.0.0.1}"/> </interface> <interface name="unsecure"> <!-- Used for IIOP sockets in the standard configuration. To secure JacORB you need to setup SSL --> <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/> </interface> </interfaces>
- socket-binding
- The default socket-binding used by the
remoting
subsystem binds to TCP port 4447. Refer to the documentation about socket bindings and socket binding groups for more information if you need to change this.Information about socket binding and socket binding groups can be found in the Socket Binding Groups chapter of JBoss EAP's Administration and Configuration Guide available at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4 - Remoting Connector Reference for EJB
- The EJB subsystem contains a reference to the remoting connector for remote method invocations. The following is the default configuration:
<remote connector-ref="remoting-connector" thread-pool-name="default"/>
- Secure Transport Configuration
- Remoting transports use StartTLS to use a secure (HTTPS, Secure Servlet, etc) connection if the client requests it. The same socket binding (network port) is used for secured and unsecured connections, so no additional server-side configuration is necessary. The client requests the secure or unsecured transport, as its needs dictate. JBoss EAP 6 components which use Remoting, such as EJBs, the ORB, and the JMS provider, request secured interfaces by default.
Warning
The worker thread pool is the group of threads which are available to process work which comes in through the Remoting connectors. It is a single element <worker-thread-pool>
, and takes several attributes. Tune these attributes if you get network timeouts, run out of threads, or need to limit memory usage. Specific recommendations depend on your specific situation. Contact Red Hat Global Support Services for more information.
Attribute | Description | CLI Command |
---|---|---|
read-threads |
The number of read threads to create for the remoting worker. Defaults to
1 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-read-threads,value=1)
|
write-threads |
The number of write threads to create for the remoting worker. Defaults to
1 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-write-threads,value=1)
|
task-keepalive |
The number of milliseconds to keep non-core remoting worker task threads alive. Defaults to
60 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-keepalive,value=60)
|
task-max-threads |
The maximum number of threads for the remoting worker task thread pool. Defaults to
16 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-max-threads,value=16)
|
task-core-threads |
The number of core threads for the remoting worker task thread pool. Defaults to
4 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-core-threads,value=4)
|
task-limit |
The maximum number of remoting worker tasks to allow before rejecting. Defaults to
16384 .
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-limit,value=16384)
|
The connector is the main Remoting configuration element. Multiple connectors are allowed. Each consists of a element <connector>
element with several sub-elements, as well as a few possible attributes. The default connector is used by several subsystems of JBoss EAP 6. Specific settings for the elements and attributes of your custom connectors depend on your applications, so contact Red Hat Global Support Services for more information.
Attribute | Description | CLI Command |
---|---|---|
socket-binding | The name of the socket binding to use for this connector. | /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=socket-binding,value=remoting)
|
authentication-provider |
The Java Authentication Service Provider Interface for Containers (JASPIC) module to use with this connector. The module must be in the classpath.
| /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=authentication-provider,value=myProvider)
|
security-realm |
Optional. The security realm which contains your application's users, passwords, and roles. An EJB or Web Application can authenticate against a security realm.
ApplicationRealm is available in a default JBoss EAP 6 installation.
| /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=security-realm,value=ApplicationRealm)
|
Attribute | Description | CLI Command |
---|---|---|
sasl |
Enclosing element for Simple Authentication and Security Layer (SASL) authentication mechanisms
| N/A
|
properties |
Contains one or more
<property> elements, each with a name attribute and an optional value attribute.
| /profile=default/subsystem=remoting/connector=remoting-connector/property=myProp/:add(value=myPropValue)
|
You can specify three different types of outbound connection:
- Outbound connection to a URI.
- Local outbound connection – connects to a local resource such as a socket.
- Remote outbound connection – connects to a remote resource and authenticates using a security realm.
<outbound-connections>
element. Each of these connection types takes an outbound-socket-binding-ref
attribute. The outbound-connection takes a uri
attribute. The remote outbound connection takes optional username
and security-realm
attributes to use for authorization.
Attribute | Description | CLI Command |
---|---|---|
outbound-connection | Generic outbound connection. | /profile=default/subsystem=remoting/outbound-connection=my-connection/:add(uri=http://my-connection)
|
local-outbound-connection | Outbound connection with a implicit local:// URI scheme. | /profile=default/subsystem=remoting/local-outbound-connection=my-connection/:add(outbound-socket-binding-ref=remoting2)
|
remote-outbound-connection |
Outbound connections for remote:// URI scheme, using basic/digest authentication with a security realm.
| /profile=default/subsystem=remoting/remote-outbound-connection=my-connection/:add(outbound-socket-binding-ref=remoting,username=myUser,security-realm=ApplicationRealm)
|
Before defining the SASL child elements, you need to create the initial SASL element. Use the following command:
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:add
Attribute | Description | CLI Command |
---|---|---|
include-mechanisms |
Contains a
value attribute, which is a list of SASL mechanisms.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=include-mechanisms,value=["DIGEST","PLAIN","GSSAPI"]) |
qop |
Contains a
value attribute, which is a list of SASL Quality of protection values, in decreasing order of preference.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=qop,value=["auth"]) |
strength |
Contains a
value attribute, which is a list of SASL cipher strength values, in decreasing order of preference.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=strength,value=["medium"]) |
reuse-session |
Contains a
value attribute which is a boolean value. If true, attempt to reuse sessions.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=reuse-session,value=false) |
server-auth |
Contains a
value attribute which is a boolean value. If true, the server authenticates to the client.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=server-auth,value=false) |
policy |
An enclosing element which contains zero or more of the following elements, which each take a single
value .
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:add /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=forward-secrecy,value=true) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-active,value=false) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-anonymous,value=false) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-dictionary,value=true) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-plain-text,value=false) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=pass-credentials,value=true) |
properties |
Contains one or more
<property> elements, each with a name attribute and an optional value attribute.
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/property=myprop:add(value=1) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/property=myprop2:add(value=2) |
Example 18.38. Example Configurations
<subsystem xmlns="urn:jboss:domain:remoting:1.1"> <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/> </subsystem>
<subsystem xmlns="urn:jboss:domain:remoting:1.1"> <worker-thread-pool read-threads="1" task-keepalive="60" task-max-threads="16" task-core-thread="4" task-limit="16384" write-threads="1" /> <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"> <sasl> <include-mechanisms value="GSSAPI PLAIN DIGEST-MD5" /> <qop value="auth" /> <strength value="medium" /> <reuse-session value="false" /> <server-auth value="false" /> <policy> <forward-secrecy value="true" /> <no-active value="false" /> <no-anonymous value="false" /> <no-dictionary value="true" /> <no-plain-text value="false" /> <pass-credentials value="true" /> </policy> <properties> <property name="myprop1" value="1" /> <property name="myprop2" value="2" /> </properties> </sasl> <authentication-provider name="myprovider" /> <properties> <property name="myprop3" value="propValue" /> </properties> </connector> <outbound-connections> <outbound-connection name="my-outbound-connection" uri="http://myhost:7777/"/> <remote-outbound-connection name="my-remote-connection" outbound-socket-binding-ref="my-remote-socket" username="myUser" security-realm="ApplicationRealm"/> <local-outbound-connection name="myLocalConnection" outbound-socket-binding-ref="my-outbound-socket"/> </outbound-connections> </subsystem>
Configuration Aspects Not Yet Documented
- JNDI and Multicast Automatic Detection
18.4.4.5. Use Security Realms with Remote EJB Clients
- Add a new security realm to the domain controller or standalone server.
- Add the following parameters to the
jboss-ejb-client.properties
file, which is in the classpath of the application. This example assumes the connection is referred to asdefault
by the other parameters in the file.remote.connection.default.username=appuser remote.connection.default.password=apppassword
- Create a custom Remoting connector on the domain or standalone server, which uses your new security realm.
- Deploy your EJB to the server group which is configured to use the profile with the custom Remoting connector, or to your standalone server if you are not using a managed domain.
18.4.4.6. Add a New Security Realm
Run the Management CLI.
Start thejboss-cli.sh
orjboss-cli.bat
command and connect to the server.Create the new security realm itself.
Run the following command to create a new security realm namedMyDomainRealm
on a domain controller or a standalone server.For a domain instance, use this command:/host=master/core-service=management/security-realm=MyDomainRealm:add()
For a standalone instance, use this command:/core-service=management/security-realm=MyDomainRealm:add()
Create the references to the properties file which will store information about the new role.
Run the following command to create a pointer a file namedmyfile.properties
, which will contain the properties pertaining to the new role.Note
The newly created properties file is not managed by the includedadd-user.sh
andadd-user.bat
scripts. It must be managed externally.For a domain instance, use this command:/host=master/core-service=management/security-realm=MyDomainRealm/authentication=properties:add(path=myfile.properties)
For a standalone instance, use this command:/core-service=management/security-realm=MyDomainRealm/authentication=properties:add(path=myfile.properties)
Your new security realm is created. When you add users and roles to this new realm, the information will be stored in a separate file from the default security realms. You can manage this new file using your own applications or procedures.
18.4.4.7. Add a User to a Security Realm
Run the
add-user.sh
oradd-user.bat
command.Open a terminal and change directories to theEAP_HOME/bin/
directory. If you run Red Hat Enterprise Linux or another UNIX-like operating system, runadd-user.sh
. If you run Microsoft Windows Server, runadd-user.bat
.Choose whether to add a Management User or Application User.
For this procedure, typeb
to add an Application User.Choose the realm the user will be added to.
By default, the only available realm isApplicationRealm
. If you have added a custom realm, you can type its name instead.Type the username, password, and roles, when prompted.
Type the desired username, password, and optional roles when prompted. Verify your choice by typingyes
, or typeno
to cancel the changes. The changes are written to each of the properties files for the security realm.
18.4.4.8. About Remote EJB Access Using SSL Encryption
Warning