The J2EE Security Model


The WebSphere security system is built around the J2EE Security Model. The model is composed of several elements, establishing trust in the user (authentication), and protecting J2EE resources (authorization). The J2EE security model, in turn, is built on the J2SE security. We will discuss all of these in this section.

Establishing Trust in the User

There are several points of entry to a WebSphere-based network. J2EE primarily addresses declarative control for web-based entry to the system – particularly from a web browser. Entry from a traditional browser is primarily controlled with deployment information in the application you are targeting. Establishing trust in the end-user, or authenticating the end user is important for determining whether the end user is who they claim to be.

Since web sites may contain a variety of different kinds of information – not all of which is necessarily sensitive – the J2EE model only requires authentication if the end-user attempts to access a web component that is classified as a protected resource. This is sometimes referred to as lazy-authentication – only authenticate when you need to. If a resource is sensitive, it should be identified in a web application security constraint – a deployment descriptor that contains a URL pattern definition and one or more HTTP-methods. The security constraint is discussed further in the section Protecting J2EE Resources. If the end user attempts to access a resource that is covered by one of the security constraints, and if the end user has not already been authenticated in their session with the application server, then they will be challenged to authenticate themselves.

You can specify what type of authentication is required using the <login-config> deployment descriptor in your web application. The DTD fragment for the <login-config> deployment descriptor is:

<!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)> <!ELEMENT auth-method (#PCDATA)> <!ELEMENT realm-name (#PCDATA)> <!ELEMENT form-login-config (form-login-page, form-error-page)> <!ELEMENT form-login-page (#PCDATA)> <!ELEMENT form-error-page (#PCDATA)>

The <login-config> element is included within the <web-app> tag. Only one <login-config> element can be specified per web application thus the same web application cannot support multiple types of authentication challenge.

The auth-method defines the authentication method that should be used for the web application and can be one of BASIC, FORM, CLIENT-CERT, or DIGEST. However, WebSphere does not support the DIGEST form of authentication challenge.

Fortunately, you don't have to worry about the specific form of the deployment descriptor – WebSphere gives you a graphical way of specifying this information in the Application Assembly Tool (AAT). For example, if you want to require basic authentication to the Plants-By-WebSphere site, you can specify this policy in the Plants-By-WebSphere web application:

click to expand

Notice that you have to specify the realm name for the login configuration. It is present here to allow you to select different registries for different applications. However, WebSphere constrains you to only using one realm per cell installation in version 5.0, and so this value is largely ignored in the web application. For clarity, you should set it to a consistent value for all of your applications.

J2EE presumes a reactive model for authenticating users to web applications. The login policy you set for a web application will actually only be executed in response to a user attempting to access a protected resource in the web application. This requires that you set the Security Constraint for one or more components of your web application, including defining the roles that are relevant to your application. Of course, you will want to grant some of your users authority to access the protected resources, and, you will have to enable and configure the security service in the application server that is hosting your application. These tasks are all described later in this chapter.

BASIC Authentication

BASIC indicates basic-auth authentication – that is, prompt the user for their user ID and password via a "401 Response code". When this option is enabled, if the user has not already been authenticated in this session, WebSphere will generate a 401 response back to the browser. If the browser does not already have a user ID and password of the current user for the domain in which the application is running, the browser will typically present a login dialog prompt similar to:

click to expand

Having acquired the user ID and information for the user in this prompt, the browser will forward that information back to the web site in the basic-auth field of the HTTP header.

Important

Note that this is sent in clear text, so unless transport-level security is enabled (SSL/TLS) usernames and passwords are vulnerable to packet sniffers.

WebSphere automatically extracts the information from the HTTP message and use it to authenticate the user. If the authentication fails, WebSphere will automatically re-prompt the user, continuing to do so until either the user authenticates properly, or the user cancels the authentication attempt.

When using this form of authentication, you should also specify the <realm-name> tag to indicate the realm in which the user will be authenticated. This is usually the name of the user registry that you will use in your enterprise.

You should also note that the password is filled into this header in clear-text, and so you should also enable secure HTTP (HTTPS) to protect this information when it flows over the network.

FORM Authentication

FORM indicates a forms-based login – that is, the application will supply a web form that is designed to prompt the user for a user ID and password that will be used to authenticate the user. This allows you to tailor the window that is presented to the user when a login is needed – you can, for example, customize it with your company logo, links to registration pages, help pages, and so forth, to make the login experience for the end user more to your preference. You do need to provide a login form – a servlet or JSP that lays out the form that you want presented.

You will have to specify the <form-login-config> tag containing the <form-login-page> and <form-error-page> sub-tags if you select the FORM type of authentication challenge. The <form-login-page> tag is used to specify the web page that you want presented containing the login form, and the <form-error-page> is used to specify the page that will be presented if the authentication performed in response to the login form fails.

Again, this can be done through the Application Assembly Tool:

click to expand

These forms should be implemented to specify a user ID field with the name of j_username and a password field of j_password. The form should be set to post the j_security_check action. The post action and user ID and password fields are highlighted in bold:

 <table cellpadding="20" cellspacing="0" border="1">   <tr>     <td valign="top">      <form  name="existingcustomer"              action="j_security_check" method="POST"> <table cellpadding="5" cellspacing="0" border="0">   <tr>      <td  align="center" colspan="2"><b>Yes.</b></td>   </tr>      <tr>     <td  align="right"><b>User Name:</b></td>     <td >       <input  type="text"               size="15" name="j_username" value="j2ee"></td>   </tr>   <tr>     <td  align="right"><b>Password:</b></td>     <td ><input           type="password" size="15" name="j_password" value="j2ee"></td>   </tr>    <tr>     <td align="center" colspan="2"><input          name="submit" type="submit" value="Sign In"></td>   </tr> </table> </form> </td>   <td valign="top">     <form  name="newcustomer" action="createuser.do"            method="POST">     <table cellpadding="5" cellspacing="0" border="0">   <tr>     <td  align="center" colspan="2">     <b>No. I would like to    sign up for an account.</b></td>   </tr>   <tr>     <td  align="right"><b>User Name:</b></td>     <td ><input  type="text"         size="15" name="j_username"></td>   </tr>   <tr>     <td  align="right"><b>Password:</b></td>     <td ><input          type="password" size="15" name="j_password"></td>   </tr>   <tr>     <td  align="right"><b>Password (Repeat):</b></td>     <td ><input            type="password" size="15" name="j_password_2"></td>   </tr>   <tr>     <td align="center" colspan="2"><input           name="submit" type="submit" value="Create New Account"></td>   </tr>   </table>  </form> </td> </tr> </table> 

Notice that this page also allows the user to create a new account for themselves.

CLIENT-CERT Authentication

CLIENT-CERT in the <auth-method> indicates that the principal should be authenticated with their X.509 client certificate. This presumes that a client-certificate has been registered for the principal in their browser certificate database.

Protecting J2EE Resources

J2EE resources: JSP pages, servlets, and EJBs are protected in the J2EE model with the declarative Roles-based Authorization Model. The following diagram depicts the overall relationship of J2EE roles in the system:

click to expand

The web and bean developer(s) create their components. They may or may not make explicit reference to role names within their code. If they do, they should declare role references for their components. The application assembler or deployer is then responsible for mapping these references to declared roles in the application. Likewise, the application assembler is responsible for defining security constraints (for web applications), and method-permissions (for EJBs) that define the permissions for their application. There are two ways of granting individual users or groups the roles declared in the application – either through security-role bindings declared in the application itself, or through an external security provider authorization repository. A qualified security administrator should do the granting of authority.

This separation of responsibilities ensures that security policies are kept out of the actual implementation of the application. At the same time it gives the application assembler and/or deployer the opportunity to express security constraints of their application definition. And yet, it enables the enterprise security administrator the flexibility they need to ensure their enterprise policies are being properly enforced and monitored. This model will be discussed in further detail in the following sections.

The Roles-Based Authorization Model

All authorization policies in J2EE are defined in terms of Security Roles. Generally, the application assembler declares roles in enterprise applications through deployment descriptors. Security Roles are represented simply as labels in the descriptor. The DTD for a Security Role is:

<!ELEMENT security-role (description?, role-name)> <!ELEMENT role-name (#PCDATA)>

Security Roles should represent relevant actors in the business scenarios supported by the application and for which a security policy may be applied. The assembler may introduce a security role based on hints they get from the developer, and from the business model itself. However, this does not assume the assembler is a security expert. The process itself allows security administrators to adapt the information – the roles and other constraints – to the security policy of the system. You can define the security roles for your web application in the AAT:

click to expand

Likewise, you can also define the security roles for your EJB modules in the AAT:

click to expand

All of the roles defined for both the web application and EJB components in the application will be rolled up to the enterprise application level:

click to expand

Doing so enables the assembler to resolve any potential conflicts that may have been introduced by any of the components that were assembled in the application. Likewise, they can resolve any similarity that may exist between disparate roles. This becomes particularly useful when an application is assembled from a set of previously defined components – perhaps reused from other applications. Notice, for example, the similarity between 'Account Holder' (introduced by the Customer EJB component), and the 'Customer' (introduced by the web-tier web application component). Having noticed the similarity, the application assembler can then fix up the corresponding components to factor their respective roles down to a common role.

Once the security roles have been defined for the application, the assembler can begin grouping methods and objects and associating those with security roles. The deployment descriptor mechanism for doing this differs between web components and EJB components.

Defining Security Constraints for Web Application Components

The grouping mechanism for web components is the security constraint. The DTD for the security constraint descriptor is:

<!ELEMENT security-constraint (display-name?, web-resourcecollection+,            auth-constraint?, user-data-constraint?)> <!ELEMENT web-resource-collection (web-resource-name, description?,            url-pattern*, http-method*)> <!ELEMENT auth-constraint (description?, role-name*)> <!ELEMENT user-data-constraint (description?, transport-guarantee)> <!ELEMENT web-resource-name (#PCDATA)> <!ELEMENT url-pattern (#PCDATA)> <!ELEMENT http-method (#PCDATA)> <!ELEMENT role-name (#PCDATA)> <!ELEMENT transport-guarantee (#PCDATA)>

You can enter this information for your web application in the WebSphere AAT in two parts. In the first part, you create the security constraint and give it a name and indicate what roles are associated with the constraint – that is, what role a requesting principal must possess in order to use any of the resources represented in that constraint. The user must possess at least one of the listed roles. In addition, you specify the data constraint, if any, which must be satisfied. Specifying a data constraint establishes two things.

The first is that secure HTTP must be used to connect to the resource. In fact, WebSphere will automatically redirect a request to an HTTPS port if the request comes in first on an unprotected communication transport and the targeted component is protect by a security constraint that requires integrity or confidentiality. The second is that the HTTPS connection must have been configured to satisfy the constraint – either with integrity or confidentiality, depending on the data constraint setting:

click to expand

Once you've created the security constraint, you can then create the resource collection for that constraint. This will define which web resources are covered by this constraint. The resource collection is defined as a combination of the URL pattern that represents the web resource, and the HTTP operations governed by that collection.

click to expand

The same resource can be covered by multiple resource collections. If you configure your application in this way then the requesting user must satisfy all of the constraints that govern that resource – the user must be granted at least one role listed in each of the security constraints.

The following rules are taken from the Servlet 2.3 specification to describe the URL patterns that you can define in your web resource collection:

  • A string beginning with a '/' character and ending with a '/*' postfix is used for path mapping.

  • A string beginning with a '*.' prefix is used as an extension mapping.

  • A string containing only the '/' character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.

  • All other strings are used for exact matches only.

Defining Method Permissions for EJB Components

Associating security roles with EJBs is done with method permission deployment descriptors for EJB components. The DTD for the method permission is:

<!ELEMENT method-permission (description?, role-name+, method+)> <!ELEMENT role-name (#PCDATA)> <!ELEMENT method (description?, ejb-name, method-intf?, method-name,            method-params?)> <!ELEMENT ejb-name (#PCDATA)> <!ELEMENT method-intf (#PCDATA)> <!ELEMENT method-name (#PCDATA)> <!ELEMENT method-params (method-param*)> <!ELEMENT method-param (#PCDATA)>

Method permissions are a way of stating the role that a user must be granted to invoke the methods on the EJBs listed in the method-permission. The method permission can list multiple roles – meaning that the user must possess at least one of the specified roles to access the listed resources. The method permission can also list multiple methods and EJBs – all of which are included in the permission.

The method-name can contain the actual name of the intended method, or an asterisk (*). An asterisk is taken to mean all the methods defined in the EJB. A common use of the wildcard is to establish a default. For example, you can specify a method permission for * – this will be the default permission for the bean(s) represented in the permission – and then set more specific overriding permissions for individual methods.

The method-params descriptor is used to differentiate between overloaded methods. This element is optional unless the method is overloaded. The roles referenced in the method permission are linked to roles defined in the EJB module. As with web applications, any roles specified for the EJB module are rolled up to the enterprise application level by the AAT.

The method permissions for an EJB can be defined using the AAT.

click to expand

The assembler is expected to provide the deployment information for the application assembly. However, the deployer must ensure the assembler has completed their job. The application installation tool used by WebSphere application deployers will not allow an application to be deployed with incomplete method permissions. That is, if any of the methods in an application are protected with a method permission, then all of the methods must be assigned a method permission.

The AAT simplifies this task in two ways. First, as we stated above, the method permission can specify a method-name with an asterisk to mean include all methods of the EJB in the method permission. This makes it easy to include all of the methods of an EJB without having to call out each method individually. Secondly, AAT includes a list of all unspecified methods – that is, all of the methods on any EJB in the module.

The same EJB or method can be included in multiple method permissions. If you define multiple method permissions that collect the same EJB or method then the caller must posses one of the roles listed in any of the method permissions that collect that EJB/method.

You can also indicate that a method is unchecked – that is, no authorization check should be performed on the method. In other words, any principal can access the method, regardless of whether they've been granted any roles:

click to expand

Finally, it is also possible for you to completely prevent access of any sort to a method. This can be done by including the method in an exclude-list deployment descriptor. The DTD for the exclude list is:

<!ELEMENT exclude-list (description?, method+)>

This can be specified in the AAT.

click to expand

Granting Principals to Roles

For both web application and EJB module components, the process of assigning a user to a specified role is the same. It is possible to specify the users and groups that are assigned to a role in the AAT. This information will be carried in extended deployment information in your application.

click to expand

However, this is not the preferred approach as setting these mappings at assembly time is far too static. You can assign users and groups to roles through the security mappings of your enterprise application in the admin console as well. This allows you to grant and revoke access to roles as often as your user community and organization changes – without having to re-deploy your application:

click to expand

You can get to this panel by selecting your application from the Enterprise Applications collection, scrolling down to Map security roles to users/groups, selecting the role in question, and then pressing the Lookup users or Lookup groups button.

The most efficient model is to assign a user group to a role. In this way you can allow a user access to a role simply by virtue of their inclusion in or exclusion from that user group. You can control that group membership entirely from your user registry administration tools.

Creating and managing users and other principals is performed entirely through your user registry tools. See User Registry for more information on this topic.

J2EE Programming Interface

We've stated a couple of times in this chapter that it is generally not a good idea to program security policy into your application. We'll state that one more time before we launch into this section – describing to you how to program security into your application based on the J2EE security interfaces. Programming security into your application reduces the flexibility of the security administrator to set and control policies for your enterprise based on the evolving concerns of your business. Generally security policies evolve more rapidly than the main stream of business processes. Tying security policy to your application implementation means that you have to change and redeploy your application every time a security policy changes. This is not good.

OK, that's out of the way. There are times where you just won't be able to help yourself. This is due in part to security features that may be missing from the WebSphere hosting environment – special circumstances that go beyond the general security system. It could also be the result of a deliberate merger between the business model and the security model of your information system – most often in the form of evaluating the outcome of security policy within the business model.

J2EE provides a short list of interfaces that can be helpful in these circumstances.

Web Application Interfaces

The programming model for servlets in the Servlet 2.3 specification introduces four methods (getAuthType, getRemoteUser, isUserInRole, and getUserPrincipal) for use in servlets. All of these methods are provided on the javax.servlet.http.HTTPServletRequest object. None of these methods are new in J2EE 1.3 or WebSphere version 5.0. They are discussed here only for completeness.

getAuthType

The getAuthType() method indicates the type of authentication used to access this servlet. This can be "BASIC", meaning BasicAuth or user ID and password based authentication; "SSL", meaning client-certificate based authentication; or null, meaning that the user was not authenticated.

getRemoteUser

The getRemoteUser() method returns a String containing the principal identity of the user for which the Servlet is being invoked.

isUserInRole(java.lang.String roleName)

The isUserInRole() method indicates whether the requesting principal has been granted the specified role; the role label is included as an argument to the call. Because the Servlet developer does not know what roles will actually be used in the application assembly, the role label specified with this method is treated as a symbolic label.

This label must be declared in the deployment descriptors for the component as a role-ref. The DTD for the security-role-ref element is:

<!ELEMENT security-role-ref (description?, role-name, role-link)> <!ELEMENT role-link (#PCDATA)>

The role-name of the security-role-ref will contain the symbolic label used within the servlet's implementation – in the isUserInRole() call. The role-link then must be mapped by the assembler to a role declared in a security role element elsewhere in the application deployment information. You can specify the security-role-ref mapping in AAT.

The following snippet shows testing whether the calling principal is in the Consumer role:

 boolean inConsumerRole = req.isUserInRole("Consumer"); 

Notice that the role referenced here is not the same as the roles created (later) for the application. However, Consumer as specified here by the programmer can be taken to be the same thing as a Customer in the application deployment. At assembly time, the assembler (or later the deployer) would be expected to map the Consumer reference to the Customer role in a roleReference deployment statement:

click to expand

Note that because all referenced roles used in the isUserInRole must be declared in the deployment descriptor, the application cannot use variables in this call that would result in a role symbolic label that is not declared in the descriptor. If you manufacture a symbolic role label in your code that is not declared in a corresponding deployment descriptor, then the call to isUserInRole will necessarily return false.

getUserPrincipal

The getUserPrincipal() method returns a Java 2 Security Principal object representing the user associated with this Servlet request.

Using this operation is fairly straightforward from within your servlet:

 java.security.Principal principal =  req.getUserPrincipal (); String principalName = null; if ( principal != null ) {  principalName =  principal.getName (); } 

In the above snippet, req is the HTTPServletRequest passed to your servlet. GetUserPrincipal returns the Principal associated with the request. You can get the principal's name in a string form with the getName() operation.

EJB Application Interfaces

The EJB programming model introduces two methods (getCallerPrincipal() and isCallerInRole()) in the javax.ejb.EJBContext interface. As with servlets, these methods are not new to J2EE 1.3 or WebSphere version 5.0.




Professional IBM WebSphere 5. 0 Applicationa Server
Professional IBM WebSphere 5. 0 Applicationa Server
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 135

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