Chapter 2. Security Overview
2.1. About Declarative Security
Declarative security is a method to separate security concerns from your application code by using the container to manage security. The container provides an authorization system based on either file permissions or users, groups, and roles. This approach is usually superior to programmatic security, which gives the application itself all of the responsibility for security.
JBoss EAP 6 provides declarative security via security domains.
2.1.1. Java EE Declarative Security Overview
The J2EE security model is declarative in that you describe the security roles and permissions in a standard XML descriptor rather than embedding security into your business component. This isolates security from business-level code because security tends to be more a function of where the component is deployed than an inherent aspect of the component's business logic. For example, consider an Automated Teller Machine (ATM) that is to be used to access a bank account. The security requirements, roles and permissions will vary independent of how you access the bank account, based on what bank is managing the account, where the ATM is located, and so on.
Securing a J2EE application is based on the specification of the application security requirements via the standard J2EE deployment descriptors. You secure access to EJBs and web components in an enterprise application by using the
2.1.2. Security References
Both Enterprise Java Beans (EJBs) and servlets can declare one or more <security-role-ref> elements.
Figure 2.1. Security Roles Reference Model
This element declares that a component is using the <role-name> element's
role-nameTypeattribute value as an argument to the
isCallerInRole(String)method. By using the
isCallerInRolemethod, 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
isCallerInRoleis to perform a security check that cannot be defined by using the role-based <method-permissions> elements.
Example 2.1. ejb-jar.xml descriptor fragment
<!-- 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>
This fragment is an example only. In deployments, the elements in this section must contain role names and links relevant to the EJB deployment.
Example 2.2. web.xml descriptor fragment
<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>
2.1.3. Security Identity
An Enterprise Java Bean (EJB) can specify the identity another EJB must use when it invokes methods on components using the <security-identity> element.
Figure 2.2. J2EE Security Identity Data Model
The invocation identity can be that of the current caller, or it can be a specific role. The application assembler uses the <security-identity> element with a <use-caller-identity> child element. This indicate that the current caller's identity should be propagated as the security identity for method invocations made by the EJB. Propagation of the caller's identity is the default used in the absence of an explicit <security-identity> element declaration.
Alternatively, the application assembler can use the <run-as> or <role-name> child element to specify that a specific security role supplied by the <role-name> element value must be used as the security identity for method invocations made by the EJB.
Note that this does not change the caller's identity as seen by the
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.
One use case for the <run-as> element is to prevent external clients from accessing internal EJBs. You configure this behavior by assigning the internal EJB <method-permission> elements, which restrict access to a role never assigned to an external client. EJBs that must in turn use internal EJBs are then configured with a <run-as> or <role-name> equal to the restricted role. The following descriptor fragment describes an example<security-identity> element usage.
<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>
When you use <run-as> to assign a specific role to outgoing calls, a principal named
anonymousis 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.xmlfile. The following fragment associates a principal named
RunAsBeanfrom the prior example.
<session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session>
The <run-as> element is also available in servlet definitions in a
web.xmlfile. The following example shows how to assign the role
InternalRoleto a servlet:
<servlet> <servlet-name>AServlet</servlet-name> <!-- ... --> <run-as> <role-name>InternalRole</role-name> </run-as> </servlet>
Calls from this servlet are associated with the anonymous
principal. The <run-as-principal> element is available in the
jboss-web.xmlfile to assign a specific principal to go along with the
run-asrole. The following fragment shows how to associate a principal named
internalto the servlet above.
<servlet> <servlet-name>AServlet</servlet-name> <run-as-principal>internal</run-as-principal> </servlet>
2.1.4. Security Roles
The security role name referenced by either the
security-identityelement needs to map to one of the application's declared roles. An application assembler defines logical security roles by declaring
role-namevalue is a logical application role name like Administrator, Architect, SalesManager, etc.
The J2EE specifications note that it is important to keep in mind that the security roles in the deployment descriptor are used to define the logical security view of an application. Roles defined in the J2EE deployment descriptors should not be confused with the user groups, users, principals, and other concepts that exist in the target enterprise's operational environment. The deployment descriptor roles are application constructs with application domain-specific names. For example, a banking application might use role names such as BankManager, Teller, or Customer.
In JBoss EAP, a
security-roleelement is only used to map
security-role-ref/role-namevalues to the logical role that the component role references. The user's assigned roles are a dynamic function of the application's security manager. JBoss does not require the definition of
security-roleelements in order to declare method permissions. However, the specification of
security-roleelements is still a recommended practice to ensure portability across application servers and for deployment descriptor maintenance.
Example 2.3. An ejb-jar.xml descriptor fragment that illustrates the security-role element usage.
<!-- 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>
Example 2.4. An example web.xml descriptor fragment that illustrates the security-role element usage.
<!-- A sample web.xml fragment --> <web-app> <security-role> <description>The single application role</description> <role-name>TheApplicationRole</role-name> </security-role> </web-app>
2.1.5. EJB Method Permissions
An application assembler can set the roles that are allowed to invoke an EJB's home and remote interface methods through method-permission element declarations.
Figure 2.3. J2EE Method Permissions Element
method-permissionelement contains one or more role-name child elements that define the logical roles that are allowed to access the EJB methods as identified by method child elements. You can also specify an
uncheckedelement instead of the
role-nameelement to declare that any authenticated user can access the methods identified by method child elements. In addition, you can declare that no one should have access to a method that has the
exclude-listelement. If an EJB has methods that have not been declared as accessible by a role using a
method-permissionelement, the EJB methods default to being excluded from use. This is equivalent to defaulting the methods into the
Figure 2.4. J2EE Method Element
There are three supported styles of method element declarations.
The first is used for referring to all the home and component interface methods of the named enterprise bean:
<method> <ejb-name>EJBNAME</ejb-name> <method-name>*</method-name> </method>
The second style is used for referring to a specified method of the home or component interface of the named enterprise bean:
<method> <ejb-name>EJBNAME</ejb-name> <method-name>METHOD</method-name> </method>
If there are multiple methods with the same overloaded name, this style refers to all of the overloaded methods.
The third style is used to refer to a specified method within a set of methods with an overloaded name:
<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>
The method must be defined in the specified enterprise bean's home or remote interface. The method-param element values are the fully qualified name of the corresponding method parameter type. If there are multiple methods with the same overloaded signature, the permission applies to all of the matching overloaded methods.
method-intfelement can be used to differentiate methods with the same name and signature that are defined in both the home and remote interfaces of an enterprise bean.
Example 2.5, “An ejb-jar.xml descriptor fragment that illustrates the method-permission element usage.” provides complete examples of the
Example 2.5. An ejb-jar.xml descriptor fragment that illustrates the method-permission element usage.
<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>
2.1.6. Enterprise Beans Security Annotations
Enterprise beans use Annotations to pass information to the deployer about security and other aspects of the application. The deployer can set up the appropriate enterprise bean security policy for the application if specified in annotations, or the deployment descriptor.
Any method values explicitly specified in the deployment descriptor override annotation values. If a method value is not specified in the deployment descriptor, those values set using annotations are used. The overriding granularity is on a per-method basis
Those annotations that address security and can be used in an enterprise beans include the following:
- Declares each security role declared in the code. For information about configuring roles, refer to the Java EE 5 Tutorial Declaring Security Roles Using Annotations.
- Specifies method permissions for annotations. For information about configuring annotation method permissions, refer to the Java EE 5 Tutorial Specifying Method Permissions Using Annotations.
- Configures the propagated security identity of a component. For information about configuring propagated security identities using annotations, refer to the Java EE 5 Tutorial Configuring a Component’s Propagated Security Identity.
2.1.7. Web Content Security Constraints
In a web application, security is defined by the roles that are allowed access to content by a URL pattern that identifies the protected content. This set of information is declared by using the
Figure 2.5. Web Content Security Constraints
The content to be secured is declared using one or more <web-resource-collection> elements. Each <web-resource-collection> element contains an optional series of <url-pattern> elements followed by an optional series of <http-method> elements. The <url-pattern> element value specifies a URL pattern against which a request URL must match for the request to correspond to an attempt to access secured content. The <http-method> element value specifies a type of HTTP request to allow.
The optional <user-data-constraint> element specifies the requirements for the transport layer of the client to server connection. The requirement may be for content integrity (preventing data tampering in the communication process) or for confidentiality (preventing reading while in transit). The <transport-guarantee> element value specifies the degree to which communication between the client and server should be protected. Its values are
CONFIDENTIAL. A value of
NONEmeans that the application does not require any transport guarantees. A value of
INTEGRALmeans 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
CONFIDENTIALmeans 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
CONFIDENTIALflag indicates that the use of SSL is required.
The optional <login-config> element is used to configure the authentication method that should be used, the realm name that should be used for the application, and the attributes that are needed by the form login mechanism.
Figure 2.6. Web Login Configuration
The <auth-method> child element specifies the authentication mechanism for the web application. As a prerequisite to gaining access to any web resources that are protected by an authorization constraint, a user must have authenticated using the configured mechanism. Legal <auth-method> values are
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 log in. If the <auth-method> value is not
form-login-configand its child elements are ignored.
The following configuration example indicates that any URL lying under the web application's
/restrictedpath requires an
AuthorizedUserrole. There is no required transport guarantee and the authentication method used for obtaining the user identity is BASIC HTTP authentication.
Example 2.6. web.xml Descriptor Fragment
<web-app> <security-constraint> <web-resource-collection> <web-resource-name>Secure Content</web-resource-name> <url-pattern>/restricted/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>AuthorizedUser</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <!-- ... --> <login-config> <auth-method>BASIC</auth-method> <realm-name>The Restricted Zone</realm-name> </login-config> <!-- ... --> <security-role> <description>The role required to access restricted content </description> <role-name>AuthorizedUser</role-name> </security-role> </web-app>
2.1.8. Enable Form-based Authentication
Form-based authentication provides flexibility in defining a custom JSP/HTML page for log in, and a separate page to which users are directed if an error occurs during login.
Form-based authentication is defined by including
<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>
When a web application with form-based authentication is deployed, the web container uses
FormAuthenticatorto direct users to the appropriate page. JBoss EAP maintains a session pool so that authentication information does not need to be present for each request. When
FormAuthenticatorreceives a request, it queries
org.apache.catalina.session.Managerfor an existing session. If no session exists, a new session is created.
FormAuthenticatorthen verifies the credentials of the session.
Each session is identified by a session ID, a 16 byte string generated from random values. These values are retrieved from
/dev/urandom(Linux) by default, and hashed with MD5. Checks are performed at session ID creation to ensure that the ID created is unique.
Once verified, the session ID is assigned as part of a cookie, and then returned to the client. This cookie is expected in subsequent client requests and is used to identify the user session.
The cookie passed to the client is a name value pair with several optional attributes. The identifier attribute is called
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.
Say a user attempts to access a web application that is protected with form-based authentication.
FormAuthenticatorcaches 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
FormAuthenticatorthen 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,
FormAuthenticatorretrieves the saved request from the cache and redirects the user to their original request.
The server recognizes form authentication requests only when the URI ends with
/j_security_checkand at least the
2.1.9. Enable Declarative Security
The Java EE security elements that have been covered so far describe the security requirements only from the application's perspective. Because Java EE security elements declare logical roles, the application deployer maps the roles from the application domain onto the deployment environment. The Java EE specifications omit these application server-specific details.
To map application roles onto the deployment environment, you must specify a security manager that implements the Java EE security model using JBoss EAP-specific deployment descriptors. Refer to the custom login module example for details of this security configuration.