So far, all of our security discussion has been on details that are specific to the Geronimo server. This is only half of the security equation. The other half is how to use the security realm within your applications. Your applications need the ability to leverage your server-side security so that it can control access to your application resources. This is done with a combination of different descriptor files, depending on the type of components you are deploying.
Protecting your Web applications is a mix of editing your web.xml file as well as your geronimo- web.xml plan file with the proper configuration. The web.xml will require one or more <security- constraint> declaration protecting specific URL patterns. It will require a <login-config> section to provide for the actual login and error pages. It will also require one or more <security-role> blocks that declare the roles that will access the Web application. Assuming that you have set up a security realm called my-new-realm, as was done in the last section, an example web.xml might look like the following:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <!--servlets and mappings and normal web.xml stuff here --> <security-constraint> <web-resource-collection> <web-resource-name>Protected</web-resource-name> <url-pattern>/protected/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>superuser</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>This is not used for FORM login</realm-name> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/loginerror.jsp</form-error-page> </form-login-config> </login-config> <security-role> <role-name>superuser</role-name> </security-role> </web-app>
In this example, the security constraints are set up so that any URL containing /protected must require the superuser role to access the URL. This handles the web.xml component. The geronimo-web.xml plan minimally just requires a <security-realm-name> element that references the name of the security realm, which in this case is my-new-realm. This will enable full JAAS authentication and authorization. If you are to do this, the role that is referenced in the web.xml must match the roles in your LoginModule’s groups. Therefore, in this example, if you strictly wanted to use JAAS, then all references to <role-name> elements in the web.xml would need to contain admin, since that is the role specified in the groups.properties file. But you will notice that here, the file does not contain admin; it contains superuser.
This is where the security descriptor block is used to leverage the Geronimo JACC support to enable principal/role mapping to form a more sophisticated security arrangement. The principal/role mapping will allow you to create declarative role hierarchies based on user and JAAS role membership. The security descriptor will set up a default principal for those users who do not fit in a particular declared role, and set up the specific declared principal/role mappings. The geronimo-web.xml plan for this example may look as follows:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://geronimo.apache.org/xml/ns/web" xmlns:naming="http://geronimo.apache.org/xml/ns/naming" > <context-root>/SecureWebApp </context-root> <context-priority-classloader>false</context-priority-classloader> <security-realm-name>my-new-realm</security-realm-name> <!-- BEGIN SECURITY DESCRIPTOR --> <security> <default-principal> <principal name="anonymous" /> </default-principal> <role-mappings> <role role-name="superuser"> <principal name="admin" designated-run-as="true" /> <principal name="system" /> </role> </role-mappings> </security> <!-- END SECURITY DESCRIPTOR --> </web-app>
In the security descriptor in this plan file, a principal named anonymous is declared and set as the default-principal. By doing this, any user who does not fit within any defined role will be viewed as this anonymous user and be referenced with the anonymous principal. The <role-mappings> section is the tie between the web.xml and this plan file. This is where the role referenced in the web.xml <security-role> matches up with the plan file.
In this example, the role admin is made up of two different kinds of principals: anyone who is in the admin group, and the system user. Therefore, if someone is in the admin group or is the system user, they will fall into the superuser role and will have access to the /protected URLs. If the client is does not fall into this category, then the user carries the anonymous principal and is not granted access to the /protected URLs. The designated-run-as attribute means that if a servlet in the web.xml had the <run-as> element declared with the superuser role, it will use the admin principal.
Important | Other than a geronimo-web.xml file for a WAR archive, the <web-app> element may appear as a module inside of a geronimo-application.xml that is deployed with an EAR. |
EJB security is very similar to the Web configuration. However, instead of a web.xml and geronimo-web.xml file, EJBs will use the ejb-jar.xml file and the geronimo-application.xml file. First, it’s important to note that the EJB container’s access will not require declaring the <security- realm-name> as was done for the Web, since at the point of the EJB using the credentials, the authentication would have already occurred. Authentication would have been handled by a Web interface or remote client login; the realm declaration would have occurred at that point. By the time the EJB calls would occur, the principals would have been populated in the subject.
The ejb-jar.xml (like the web.xml) requires <security-role> declarations with the list of roles being used. Additional security may be imposed on the ability to call specific methods on an EJB, such as those shown here:
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"; version="2.1"> <enterprise-beans> ... <session> <ejb-name>MyStatelessBean</ejb-name> ... <security-identity> <use-caller-identity/> </security-identity> </session> </enterprise-beans> <assembly-descriptor> <security-role> <role-name>superuser</role-name> </security-role> <method-permission> <description>The description</description> <role-name>superuser</role-name> <method> <ejb-name>MyStatelessBean</ejb-name> <method-intf>Remote</method-intf> <method-name>secureMethod</method-name> </method> </method-permission> ... </assembly-descriptor> </ejb-jar>
The Geronimo security descriptor is nearly identical to the Web’s. In fact, the geronimo-application .xml can contain a Geronimo Web descriptor, EJB descriptor, and security descriptor. Notice in the following example, geronimo-application.xml, that the security descriptor is the same as the Web example but has been placed on its own in this plan file, while modularizing the Web and EJB code:
<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1" config parent> <moduleId> <groupId></groupId> <artifactId>MyEJBWebApplication</artifactId> <version></version> <type>car</type> </moduleId> <!-- OpenEJB Configuration Here --> <module> <ejb>my-ejbs.jar</ejb> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1"> ... </openejb-jar> </module> ... <!-- Web descriptor here" no need for a geronimo-web.xml now --> <module> <web>SecureWebApp.war</web> <web-app xmlns="http://geronimo.apache.org/xml/ns/web/tomcat-1.1"> <context-prioerty-classloader>false</context-priority-classloader> <context-root>/SecureWebApp </context-root> <context-priority-classloader>false</context-priority-classloader> <security-realm-name>my-new-realm</security-realm-name> </web-app> </module> <!-- BEGIN SECURITY DESCRIPTOR --> <security> <default-principal> <principal name="anonymous" /> </default-principal> <role-mappings> <role role-name="superuser"> <principal name="admin" designated-run-as="true" /> <principal name="system" /> </role> </role-mappings> </security> <!-- END SECURITY DESCRIPTOR --> </application>
The Web module still contains the reference to the <security-realm-name>, since it will handle the authentication. The ejb-jar.xml file then handles the roles mapped from the geronimo-application .xml for the authorization to the roles and method execution permissions.
Both the Web and EJB security configurations are very similar from a configuration perspective with respect to the security descriptor. Each of the specification-compliant deployment descriptors (web.xml and ejb-jar.xml) has many more options that you can configure that are beyond the scope of this book. Material on specification security handling can be obtained from books on EJB and servlets.
The security descriptor is a schema that allows you to control the application side of security to be used in conjunction with security realms and configurations that have been set up on the server side. As shown in the previous section, the security descriptor can be placed in just about any plan, but typically it is used in a Web’s geronimo-web.xml plan or an EAR file’s geronimo-application.xml plan. This section provides a reference for the security descriptor, and each element is listed in alphabetical order. The security descriptor begins with the <security> element
Portions of this section’s table descriptions are taken directly from the geronimo-securiy-1.1.xsd, Copyright 2004-2005, The Apache Software Foundation.
This is the principal to use for unauthenticated access of resources.
Elements | Description |
---|---|
<principal> | Required only if the <login-domain-principal> or <realm-principal> is not used. Represents the principal to use for all unauthenticated access to resources. |
<login-domain-principal> |
Required only if the <principal> or <realmprincipal> is not used. Represents the principal to use for all unauthenticated access to resources. |
<realm-principal> | Required only if the <login-domain-principal> or <principal> is not used. Represents the principal to use for all unauthenticated access to resources. |
<description> | Optional. May have one or more of these elements. Represents the text-based description of the default principal. |
<named-username-password-credential> | Optional. Allows you to create a named username/credential that can be carried along with the default principal. This can give your applications access to these credentials if needed. |
This is an optional element in all cases that allows for free-form text to annotate and describe the element section.
This provides the ability to match the distinguished name (DN) on a SSL certificate, with a presented client certificate. If the DN matches the certificate, the user is considered a part of the role.
Attributes | Description |
---|---|
name | Required. The fully qualified distinguished name that matches the SSL certificate. |
designated-run-as | Optional. May be true or false. Defaults to false. Set this attribute to “true” if this principal is to be used as the run-as principal for this role. |
Elements | Description |
---|---|
<description> | Optional. May have one or more of these elements. Represents the text-based description of the distinguished name. |
This ensures that the referenced principal is associated with a particular login domain.
Attributes | Description |
---|---|
class | Required. Class for the principal. May be just about any principal-based class. Geronimo’s JACC typically will use org.apache.geronimo.security.realm.providers .GeronimoUserPrincipal for users and org.apache .geronimo.security.realm.providers.Geronimo UserPrincipal for groups. |
name | Required. Principal name. |
designated-run-as | Optional. May be true or false. Defaults to false. Set this attribute to true if this principal is to be used as the run-as principal for this role. |
domain-name | Required. Login domain name. |
Elements | Description |
---|---|
<description> | Optional. May have one or more of these elements. Represents the text-based description of the principal. |
This allows you to create a named username/credential that can be carried along with the default principal. This can give your applications access to these credentials if needed.
Elements | Description |
---|---|
<name> | Required. The name associated with the username/password grouping. |
<username> | Required. Username. |
<password> | Required. Password. |
This is the principal representation for the authenticated user.
Attributes | Description |
---|---|
class | Required. Class for the principal. May be just about any principal-based class. Geronimo’s JACC typically will use org.apache.geronimo.security.realm.providers .GeronimoUserPrincipal for users and org.apache .geronimo.security.realm.providers.Geronimo UserPrincipal for groups. |
name | Required. Principal name. |
designated-run-as | Optional. May be true or false. Defaults to false. Set this attribute to true if this principal is to be used as the run-as principal for this role. |
Elements | Description |
---|---|
<description> | Optional. Text-based description of the principal. |
This ensures that the referenced principal is associated with a particular realm and login domain.
Attributes | Description |
---|---|
class | Required. Class for the principal. May be just about any principal-based class. Geronimo’s JACC typically will use org.apache.geronimo.security.realm.providers .GeronimoUserPrincipal for users and org.apache .geronimo.security.realm.providers.Geronimo UserPrincipal for groups. |
name | Required. Principal name. |
designated-run-as | Optional. May be true or false. Defaults to false. Set this attribute to true if this principal is to be used as the run-as principal for this role. |
domain-name | Required. Login domain name. |
realm-name | Required. Realm name. |
Elements | Description |
---|---|
<description> | Optional. Text-based description of the principal. |
This element makes up the different principals to constitute the role. This element may contain any number of principal types.
Attributes | Description |
---|---|
role-name | Required. Unique name to identify the role. |
Elements | Description |
---|---|
<description> | Optional. May contain more than one of these elements. Text-based description of the role. |
<realm-principal> | Optional. May contain more than one of these elements. One or more realm principals to constitute the role. |
<login-domain-principal> | Optional. May contain more than one of these elements. One or more login domain principals to constitute the role. |
<principal> | Optional. May contain more than one of these elements. One or more principals to constitute the role. |
<distinguished-name> | Optional. May contain more than one of these elements. One or more distinguished names to constitute the role. Provides the ability to match the distinguished name (DN) on a SSL certificate, with a presented client certificate. If the DN matches the certificate, the user is considered a part of the role. |
This element contains the roles that will be created from the principals within each role.
Elements | Description |
---|---|
<role> | Required. One or more role elements make up the list of roles that map the principals to each role. |
The <security> element denotes to the deployer that there is a security configuration. Existence of this element forces the EJB and Web containers to set up and implement JACC within their authorization handlers.
Attributes | Description |
---|---|
do-as-currentcaller | Optional. Default is false. If set to true, all work within the Web or EJB containers will be performed by the calling subject. |
use-context-handler | Optional. Default is false. If set to true, JACC policies will use PolicyContextHandlers. |
default-role | Optional. Used by the deployer to assign method permissions for all of the unspecified methods, either by assigning them to security roles or by marking them as unchecked. If the value of default-role is empty, then the unspecified methods are marked unchecked. |
Elements | Description |
---|---|
<description> | Optional. Text-based description of the security. |
<default-principal> | Required. Principal to use for unauthenticated access of resources. |
<role-mapping> | Optional. Enables mapping of principals to roles. |
Listing 15-4: geronimo-security-1.1 XML Schema
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:geronimo="http://geronimo.apache.org/xml/ns/security-1.1" targetNamespace="http://geronimo.apache.org/xml/ns/security-1.1" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <xsd:element name="security" type="geronimo:securityType"/> <xsd:element name="default-principal" type="geronimo:default-principalType"/> <xsd:complexType name="securityType"> <xsd:annotation> <xsd:documentation> Security entries If this element is present, all web and EJB modules MUST make the appropriate access checks as outlined in the JACC spec. </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="description" type="geronimo:descriptionType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="default-principal" type="geronimo:default-principalType"/> <xsd:element name="role-mappings" type="geronimo:role-mappingsType" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="doas-current-caller" type="xsd:boolean" default="false"> <xsd:annotation> <xsd:documentation> Set this attribute to "true" if the work is to be performed as the calling Subject. </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="use-context-handler" type="xsd:boolean" default="false"> <xsd:annotation> <xsd:documentation> Set this attribute to "true" if the installed JACC policy contexts will use PolicyContextHandlers. </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="default-role" type="xsd:string"> <xsd:annotation> <xsd:documentation> Used by the Deployer to assign method permissions for all of the unspecified methods, either by assigning them to security roles, or by marking them as unchecked. If the value of default-role is empty, then the unspecified methods are marked unchecked </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:complexType name="descriptionType"> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute ref="xml:lang"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> <xsd:complexType name="default-principalType"> <xsd:sequence> <xsd:element name="description" type="geronimo:descriptionType" minOccurs="0" maxOccurs="unbounded"/> <xsd:choice> <xsd:element name="principal" type="geronimo:principalType"/> <xsd:element name="login-domain-principal" type="geronimo:loginDomainPrincipalType"/> <xsd:element name="realm-principal" type="geronimo:realmPrincipalType"/> </xsd:choice> <xsd:element name="named-username-password-credential" type="geronimo:named-username-password-credentialType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="named-username-password-credentialType"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="username" type="xsd:string"/> <xsd:element name="password" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="role-mappingsType"> <xsd:sequence> <xsd:element name="role" type="geronimo:roleType" minOccurs="1" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="roleType"> <xsd:sequence> <xsd:element name="description" type="geronimo:descriptionType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="realm-principal" type="geronimo:realmPrincipalType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="login-domain-principal" type="geronimo:loginDomainPrincipalType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="principal" type="geronimo:principalType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="distinguished-name" type="geronimo:distinguishedNameType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="role-name" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="realmPrincipalType"> <xsd:complexContent> <xsd:extension base="geronimo:loginDomainPrincipalType"> <xsd:attribute name="realm-name" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="loginDomainPrincipalType"> <xsd:complexContent> <xsd:extension base="geronimo:principalType"> <xsd:attribute name="domain-name" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="principalType"> <xsd:sequence> <xsd:element name="description" type="geronimo:descriptionType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="class" type="xsd:string" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="designated-run-as" type="xsd:boolean" default="false"> <xsd:annotation> <xsd:documentation> Set this attribute to "true" if this principal is to be used as the run-as principal for this role. </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:complexType name="distinguishedNameType"> <xsd:sequence> <xsd:element name="description" type="geronimo:descriptionType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="designated-run-as" type="xsd:boolean" default="false"> <xsd:annotation> <xsd:documentation> Set this attribute to "true" if this principal is to be used as the run-as principal for this role. </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:schema>
A final advanced technique covered here is the ability to override the authorization GBean used by the Geronimo server.
The Geronimo server JACC component is handled and set up by default with the SecurityService GBean using the SecurityServiceImpl class. Geronimo supports the ability to allow for pluggable policy implementation and configuration factory classes. Geronimo currently comes preconfigured to work with its own default implementation, with the org.apache.geronimo.jacc.GeronimoPolicy and org.apache.geronimo.jacc.GeronimoPolicyConfigurationFactory. These work with the deployers to allow you to declare advanced JACC principal-role mappings and permissions in your plans. These are already configured in Geronimo and are set with the policyConfigurationFactory and policyProvider attributes in the SecurityService GBean, as shown here:
<gbean name="SecurityService" > <reference name="ServerInfo"> <module>geronimo/j2ee-system/1.1/car</module> <name>ServerInfo</name> </reference> <attribute name="policyConfigurationFactory"> org.apache.geronimo.security.jacc.GeronimoPolicyConfigurationFactory</attribute> <attribute name="policyProvider"> org.apache.geronimo.security.jacc.GeronimoPolicy</attribute> </gbean>
You may create your own policy or factory to do enhanced policy handling, or possibly to log all security access to your applications, and plug them in by changing the SecurityService attributes to use your own versions. In addition, you can override the GBean’s attributes by setting system properties when you launch Geronimo. This means that if you set the system property on the command line, the GBean will ignore its own attributes. For example, if you created your own policy and policy configuration factory, called com.example.MyPolicy and com.example.MyPolicyConfigurationFactory, you could use these by running Geronimo with the following command (all on one line):
java –jar bin/server.jar -Djavax.security.jacc.policy.provide=com.example.MyPolicy -Djavax.security.jacc.PolicyConfigurationFactory.provider= com.example.MyPolicyConfigurationFactory
You may also set up SSL configurations with the SecurityService GBean or command-line parameters, such as the key store, the trust store, and their passwords. Thus, SecurityServiceImpl is the JACC Service handler and allows for setting container-wide SSL properties. Table 15-16 shows the system properties and the GBean attributes they override.
Type | Name | Req | Description |
---|---|---|---|
A | policy Configuration factory | No | The class name for the provider configuration to use. May be also set or overridden Factory with the javax.security.jacc.Policy ConfigurationFactory.provider system property. |
A | policyProvider | No | The class name for the policy provider to use. May be also set or overridden with the javax.security.jacc.policy.provider system property. |
A | keyStore | No | The path and filename of the key store file. Relative paths will be relative to $GERONIMO_HOME. May be also set or overridden with the javax .net.ssl.keyStore system property. |
A | keyStorePassword | No | The password of the server certificate that is stored in the key store file. May be also set or overridden with the javax.net.ssl.key-StorePassword system property. |
A | trustStore | No | The path and filename of the key store file. Relative paths will be relative to $GERONIMO_HOME. May be also set or overridden with the javax.net.ssl.trustStore system property. |
A | trustStorePassword | No | The password of the server certificate that is stored in the trust store file. May be also set or overridden with the javax.net.ssl.trust-StorePassword system property. |
R | ServerInfo | Yes | Reference to a ServerInfo GBean. |
Legend Type: (A) - Attribute, (R) - Reference to GBean Req: (Yes) - parameter is required, (No) - not required |