Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Mastering Enterprise JavaBeans™ and the Java 2 Platform, Enterprise Edition - Roman E

..pdf
Скачиваний:
41
Добавлен:
24.05.2014
Размер:
6.28 Mб
Скачать

Understanding EJB 1.1 655

<trans-attribute>Required</trans-attribute>

</container-transaction>

<!--

You can also set transaction attributes on individual methods. -->

<container-transaction>

<method> <ejb-name>Employee</ejb-name> <method-name>setName</method-name>

</method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

<!--

You can even set different transaction attributes on methods with the same name that take different parameters.

--> <container-transaction>

<method> <ejb-name>Employee</ejb-name> <method-name>setName</method-name>

<method-param>String</method-param> </method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

</assembly-descriptor>

Source D.5 Declaring Transaction Attributes within an EJB 1.1 Deployment Descriptor (continued).

Security Updates

Next, let’s examine the major changes to security in EJB 1.1.

Security Context Propagation Changes

In Chapter 6, we showed you how to control the propagation of security contexts in an EJB system. For example, let’s say a client is authenticated, and has

Go back to the first page for a quick link to buy this book online!

656 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

Isolation in EJB 1.1

Unfortunately with the isolation changes in EJB 1.1, there is no longer any way to specify isolation for container-managed transactional beans in a portable way. This means if you have written an application, you cannot ship that application with built-in isolation. The deployer now needs to know about transaction isolation when he uses the container’s tools, and the deployer might not know a whole lot about your application’s transactional behavior. This approach is also somewhat error prone, because the bean provider and application assembler need to informally communicate isolation requirements to the deployer, rather than specifying it declaratively in the deployment descriptor.

When I queried Sun on this matter, I got the following response from Mark Hapner, co-author of the EJB specification:

“Isolation was removed because the vendor community found that implementing isolation at the component level was too difficult. Some felt that isolation at the transaction level was the proper solution; however, no consensus was reached on a specific replacement semantics.

This is a difficult problem that unfortunately has no clear solution at this time. We will be examining it again in the context of EJB 2.0 and possibly by then a solution will emerge.

At present, enterprise beans can use JDBC isolation facilities (since databases differ in the isolation facilities they provide, over reliance on this can lead to portability problems) as well as any deployment time isolation control provided by EJB containers. EJB 1.1 does not require that containers provide any specific isolation control.

The best strategy is to develop EJBs that are as tolerant of isolation differences as possible. This is the typical technique used by many optimistic concurrency libraries that have been layered over JDBC and ODBC.”

associated security credentials. That client calls bean A, which calls bean B. Should the client’s security credentials be sent to bean B, or should bean B receive a different principal? By controlling security context propagation, you can specify the exact semantics of credentials streaming from method to method in a distributed system.

In EJB 1.0, you could control security context propagation via the runAsMode and runAsIdentity deployment descriptor settings. runAsMode controls whether your bean runs as the client identity, as the system identity, or as an identity specified in runAsIdentity.

In EJB 1.1, there are no facilities for controlling security context propagation. This has been left as a container-specific feature, and you need to use containerspecific tools to specify propagation semantics.

Go back to the first page for a quick link to buy this book online!

Understanding EJB 1.1 657

Java 2 Security Model Updates

EJB 1.1 has been updated to reflect security changes in the Java 2 platform. The most significant change is that java.security.Identity has been deprecated in Java 2 in favor of the new java.security.Principal.

If you’ll recall from Chapter 6, an EJBContext allows bean developers to access security information at runtime. The EJB 1.0 EJBContext relied on java.security

.Identity, as shown below:

public interface javax.ejb.EJBContext

{

...

public java.security.Identity getCallerIdentity();

public boolean isCallerInRole(java.security.Identity);

...

}

These methods have been updated to reflect the Java 2 security model as follows:

public interface javax.ejb.EJBContext

{

...

public java.security.Principal getCallerPrincipal();

public boolean isCallerInRole(String roleName);

...

}

Notice that isCallerInRole() now takes a String rather than an Identity. As we’re about to see, you define this String in the deployment descriptor under the rolename element. This eliminates the need to provide a custom implementation of java.security.Identity as shown in Chapter 6.

Step by Step: Adding Programmatic Security to an EJB 1.1 System

When programming with EJB 1.1 security, you must define the necessary security policies for your beans. An example of a security policy is, “only bank administrators may delete bank accounts.” You can hard-code security policies into the bean code itself (programmatic security), or you can define method permissions in the deployment descriptor (declarative security). This example shows how to use programmatic security; the next example shows declarative security.

Step 1: Write the Programmatic Security Logic

First, you need to hard-code the security logic into your bean code. Source D.6 demonstrates this.

Go back to the first page for a quick link to buy this book online!

658 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

public class EmployeeBean implements EntityBean {

private EntityContext ctx;

...

public void foo() throws SecurityException { /*

*If the caller is not in the 'sysadmins'

*security role, throw an exception.

*/

if (!ctx.isCallerInRole("sysadmins")) { throw new SecurityException(...);

}

// else, perform operation

...

}

}

Source D.6 Programmatic Security Logic in EJB 1.1.

Step 2: Declare the Abstract Security Roles Your Bean Uses

Next, you must declare all the security roles that your bean code uses, such as a sysadmins role, in your deployment descriptor. This signals to others (such as application assemblers and deployers) that your bean requires a sysadmins security role. That is important information for them to have, because they need to fulfill that role. See Source D.7 for an example deployment descriptor.

...

<enterprise-beans>

<entity>

<ejb-name>EmployeeEJB</ejb-name> <ejb-class>EmployeeBean</ejb-class>

...

<!--

This declares that our bean code relies on

the sysadmins role; we must declare it here

Source D.7 Declaring a Bean’s Required Security Roles within an EJB 1.1 Deployment Descriptor

(continues).

Go back to the first page for a quick link to buy this book online!

Understanding EJB 1.1 659

to inform the application assembler and deployer. -->

<security-role-ref>

<description>

This security role should be assigned to the sysadmins who are responsible for modifying employees in the database.

</description>

<role-name>sysadmins</role-name>

</security-role-ref>

...

</entity>

...

</enterprise-beans>

...

Source D.7 Declaring a Bean’s Required Security Roles within an EJB 1.1 Deployment Descriptor

(continued).

Step 3: Declare the Actual Security Roles

Once you’ve written your bean, you can ship it for resale, build it into an application, or make it a part of your company’s internal library of beans. The consumer of your bean might be combining beans from all sorts of sources, and each source may have declared security roles a bit differently. For example, we used the string sysadmins in our bean above, but another bean provider might use the string administrators, or have completely different security roles.

The consumer of your bean is responsible for generating the real security roles that the final application will use. Source D.8 shows this.

<assembly-descriptor>

...

<!--

This is an example of a real security role used in

the final application.

Source D.8 Declaring Actual Security Roles within an EJB 1.1 Deployment Descriptor (continues).

Go back to the first page for a quick link to buy this book online!

660 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

--> <security-role>

<description>

This role is for personnel authorized to perform employee administration.

</description>

<role-name>admins</role-name> </security-role>

...

</assembly-descriptor>

Source D.8 Declaring Actual Security Roles within an EJB 1.1 Deployment Descriptor (continued).

Step 4: Map Principals to the Actual Roles

Next, the consumer of your bean scans through your deployment descriptor for the security roles you’ve declared with security-role-ref elements (as shown in Step 2). He then maps those abstract roles to real security roles, as shown in Source D.9.

...

<enterprise-beans>

<entity>

<ejb-name>EmployeeEJB</ejb-name> <ejb-class>EmployeeBean</ejb-class>

...

<security-role-ref>

<description>

This security role should be assigned to the sysadmins who are responsible for modifying employees in the database.

</description>

<role-name>sysadmins</role-name>

<!--

Here the application assembler is linking the

Source D.9 Mapping Actual Roles to Abstract Roles within an EJB 1.1 Deployment Descriptor

(continues).

Go back to the first page for a quick link to buy this book online!

Understanding EJB 1.1 661

security-role-ref, called "sysadmins", to a real security-role, called "admins".

-->

<role-link>admins</role-link>

</security-role-ref>

...

</entity>

...

</enterprise-beans>

...

Source D.9 Mapping Actual Roles to Abstract Roles within an EJB 1.1 Deployment Descriptor

(continued).

Once you’ve completed your application, you can deploy it in a wide variety of scenarios. For example, if you write a banking application, you could deploy that same application at different branches of that bank, because you haven’t hard-coded any specific principals into your application. The deployer of your application is responsible for mapping principals to the roles you’ve declared. This mapping is called a security policy descriptor, and is a fancy term for the statement, “every container handles mapping roles to principals differently.” The bottom line: your deployer looks at your security roles, and assigns principals to them using proprietary container APIs and tools.

Step by Step: Adding Declarative Security to an EJB 1.1 System

This example shows how to add declarative security to an EJB 1.1 system. The process is much simpler because there are no security role strings hard-coded in your bean logic, and hence there are no security-role-refs that we need to deal with.

Step 1: Declare Method Permissions

First, you need to declare permissions on the bean methods that you want to secure. Source D.10 demonstrates this.

Step 2: Declare Security Roles

Declaring security roles is the same as for programmatic security. See the previous example.

Go back to the first page for a quick link to buy this book online!

662 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

...

<assembly-descriptor>

...

<!--

This demonstrates allowing a role "sysadmins" to call every method on the bean class.

--> <method-permission>

<role-name>sysadmins</role-name>

<method> <ejb-name>Employee</ejb-name> <method-name>*</method-name> </method>

</method-permission>

<!--

This demonstrates allowing a role "roleA" to only call methods "foo" and "bar".

--> <method-permission>

<role-name>roleA</role-name>

<method> <ejb-name>Employee</ejb-name> <method-name>foo</method-name>

</method>

<method> <ejb-name>Employee</ejb-name> <method-name>bar</method-name>

</method> </method-permission>

<!--

This demonstrates allowing a role "roleB" to only call method "bar" that takes a parameter "String".

--> <method-permission>

<role-name>roleB</role-name>

<method> <ejb-name>Employee</ejb-name>

Source D.10 Declaring a Bean’s Required Security Roles within an EJB 1.1 Deployment Descriptor (continues).

Go back to the first page for a quick link to buy this book online!

Understanding EJB 1.1 663

<method-name>bar</method-name>

<method-params>String</method-params>

</method>

</method-permission>

...

</assembly-descriptor>

...

Source D.10 Declaring a Bean’s Required Security Roles within an EJB 1.1 Deployment Descriptor (continued).

Step 3: Map Abstract Roles to Actual Roles

The consumer of your bean now has the liberty to change around your declared security roles as necessary. If they want to change a security role, they can simply change the assembly descriptor from Source D.10 into Source D.11.

Step 4: Map Principals to the Actual Roles

Again, mapping principals to actual roles is a container-specific process.

<assembly-descriptor>

...

<method-permission>

<role-name>admins</role-name>

<method> <ejb-name>Employee</ejb-name> <method-name>*</method-name>

</method> </method-permission>

...

</assembly-descriptor>

...

Source D.11 Mapping Actual Roles to Abstract Roles within an EJB 1.1 Deployment Descriptor.

Go back to the first page for a quick link to buy this book online!

664 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

New Home Handles

In Chapter 6, we showed you how to use EJB object handles—references to EJB objects that can be persisted and re-used later (the equivalent of CORBA interoperable object references). EJB 1.1 adds a new kind of handle—an EJB home handle. EJB home handles are simply persistent references to home objects, rather than persistent references to EJB objects. Home handles are useful because you can acquire a reference to a home object, persist it, and then use it again later without knowledge of the home object’s JNDI location.

The following code shows how to use home handles.

//First, get the EJB home handle from the home object. javax.ejb.HomeHandle homeHandle = myHomeObject.getHomeHandle();

//Next, serialize the home handle, and then save it in

//permanent storage.

ObjectOutputStream stream = ...; stream.writeObject(homeHandle);

//time passes...

//When we want to use the home object again,

//deserialize the home handle ObjectInputStream stream = ...; javax.ejb.HomeHandle homeHandle =

(HomeHandle) stream.readObject();

//Convert the home object handle into a home object MyHomeInterface myHomeObject = (MyHomeInterface)

javax.rmi.PortableRemoteObject.narrow( homeHandle.getHomeObject(), MyHomeInterface.class);

//Resume using the home object

myHomeObject.create();

Other Important Changes in EJB 1.1

Here are the rest of the major changes in EJB 1.1.

Finder methods can return collections. If you recall from Chapters 7, 8, and 9, an entity bean finder method locates existing entity bean data in an underlying storage. Finder methods can return more than one result, such as when you want to find all employees that are in the same department. In EJB 1.0, a finder method returns multiple results as a java.util.Enumeration. EJB 1.1

Go back to the first page for a quick link to buy this book online!