Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Security Most Java EE applications need to provide identity to users who access them and security for that access. Applications may want to prevent hostile.

Similar presentations


Presentation on theme: "1 Security Most Java EE applications need to provide identity to users who access them and security for that access. Applications may want to prevent hostile."— Presentation transcript:

1 1 Security Most Java EE applications need to provide identity to users who access them and security for that access. Applications may want to prevent hostile users from logging into their systems. They might also want to restrict the actions of the individuals using their systems. The Java EE and EJB specifications provide a core set of security services that application developers can integrate declaratively and programmatically. These include: Authentication Authorization Confidentiality and integrity protection

2 2 Security Although a small programmatic API is available for interacting with Java EE security services, users rarely have to write any code to secure their applications because setting up security is usually a static declarative process. Only session beans can be secured in EJB land. Java Persistence does not yet have a mechanism to secure access, but it is possible - depending on the RDBMS system you are using - to assign privileges at the database level. This lesson focuses on how to set up authentication and authorization for your session beans.

3 3 Authentication and Identity In a secure EJB application, authentication involves verifying that a user is who she says she is. When a remote client logs on to the EJB system, it is associated with a security identity for the duration of that session. Once a remote client application has been associated with a security identity, it is ready to use beans to accomplish some task. When a client invokes a method on a bean, the EJB server implicitly passes the client's identity with the method invocation. When the EJB object receives the method invocation, it checks the identity to ensure that the client is valid and is allowed to invoke that method.

4 4 Authentication and Identity Unfortunately the EJB specification does not specify how authentication happens. It also does not define how the application server stores and retrieves authentication information. The vendor must decide how to package and provide these services on the client and server. When invoking on a remote EJB, many application servers accomplish authentication by using the JNDI API. For example, a client using JNDI can provide authenticating information using the JNDI API to access a server or resource in the server. This information is frequently passed when the client attempts to initiate a JNDI connection on the EJB server.

5 5 Authentication and Identity The following code shows how a client's password and username can be added to the connection properties for obtaining a JNDI connection to the EJB server: properties.put(Context.SECURITY_PRINCIPAL, userName); properties.put(Context.SECURITY_CREDENTIALS, userPassword); InitialContext ctx = new InitialContext(properties); Object ref = jndiContext.lookup("TravelAgent"); TravelAgentRemote remote = (TravelAgentRemote) PortableRemoteObject.narrow(ref, TravelAgentRemote.class);

6 6 Authentication and Identity In this example, the user is authenticated with the connection to the JNDI InitialContext. The username and password are associated with the client thread and propagated to the server internally when calls are made to remote EJBs. Many application servers provide a mechanism other than JNDI with which to authenticate. For instance, the JBoss application server uses the JAAS specification, which provides a rich API for performing authentication.

7 7 Authorization Once a user is authenticated by a vendor-specific mechanism, he must be checked to see if he is allowed to invoke a particular EJB method. Authorization is performed in Java EE and EJB by associating one or more roles with a given user and then assigning method permissions based on that role. While an example of a user might be "Scott" or "Gavin," roles are used to identify a group of users—for instance, "administrator," "manager," or "employee." In EJB, you assign access control on a per-method basis. You do not assign these permissions on a per-user basis, but rather, on a per-role basis.

8 8 Authorization Unlike authentication, authorization is something that the EJB specification clearly defines. You begin by declaring the roles that are accessed programmatically in your code base. Then you assign permissions for each method in your class. This is done declaratively through Java annotations or through the ejb-jar.xml deployment descriptor. To illustrate, let's secure access to the ProcessPayment EJB defined in Lesson 11.

9 9 Assigning Method Permissions To assign method permissions to an EJB's methods, use the @javax.annotation.security.RolesAllowed annotation: package javax.annotation.security; @Target({TYPE, METHOD}) @Retention(RUNTIME) public @interface RolesAllowed { String[] value( ); } The @javax.annotation.security.PermitAll annotation specifies that any authenticated user is permitted to invoke the method.

10 10 Assigning Method Permissions As with @RolesAllowed, you can use this annotation on the bean class to define the default for the entire bean class, or you can use it on a per-method basis. @PermitAll is also the default value if no default or explicit security metadata is provided for a method. This means that if you do not use any security annotations on your bean class, every user is granted unlimited access. Let's apply these annotations to ProcessPaymentBean using the permissions we discussed earlier: package com.titan.processpayment; import com.titan.domain.*; import javax.ejb.*; import javax.annotation.Resource; import javax.annotation.security.*;

11 11 Assigning Method Permissions @Stateless @RolesAllowed("AUTHORIZED_MERCHANT") public class ProcessPaymentBean implements ProcessPaymentRemote, ProcessPaymentLocal {... @PermitAll public boolean byCash(Customer customer, double amount) throws PaymentException {... } @RolesAllowed("CHECK_FRAUD_ENABLED") public boolean byCheck(Customer customer, CheckDO check, double amount) throws PaymentException {... }

12 12 Assigning Method Permissions public boolean byCredit(Customer customer, CreditCardDO card, double amount) throws PaymentException {... } private boolean process(int customerID, double amount, String type, String checkBarCode, int checkNumber, String creditNumber, java.sql.Date creditExpDate) throws PaymentException {... } Let's apply this security metadata with XML instead:

13 13 Assigning Method Permissions This role represents an authorized merchant AUTHORIZED_MERCHANT This role represents a merchant that has check fraud enabled CHECK_FRAUD_ENABLED AUTHORIZED_MERCHANT ProcessPaymentBean byCredit

14 14 Assigning Method Permissions CHECK_FRAUD_ENABLED ProcessPaymentBean byCheck ProcessPaymentBean byCheck

15 15 Wildcard declarations The method name in a element can be a simple wildcard ( * ). A wildcard applies to all methods of the bean's home and remote interfaces. For example: ProcessPaymentBean * Although it's tempting to combine the wildcard with other characters, don't do this. The value get*, for example, is illegal. The asterisk character can only be used by itself.

16 16 Named method declarations Named declarations apply to all methods defined in the bean's remote and local interfaces that have the specified name. For example: ProcessPaymentBean byCheck This declaration applies to all methods with the given name in any business interface. It does not distinguish between overloaded methods.

17 17 Specific method declarations Specific method declarations use the element to pinpoint a method by listing its parameters, which allows you to differentiate between overloaded methods. The element contains zero or more elements that correspond, in order, to each parameter type (including multidimensional arrays) declared in the method. For example, let's look again at our ProcessPayment EJB, to which we have added some overloaded byCheck( ) methods. Here are three elements, each of which unambiguously specifies one of the methods by listing its parameters:

18 18 Specific method declarations ProcessPaymentBean byCheck com.titan.domain.Customer com.titan.processpayment.CheckDO double ProcessPaymentBean byCheck ProcessPaymentBean byCheck double[]

19 19 Remote/home/local differentiation There's one problem left. The same method name can be used in the remote interface and the local interface. To resolve this ambiguity, add the element to a method declaration as a modifier. Five values are allowed for a element: Remote, Home, LocalHome, Local, and ServiceEndpoint. All of these styles of method declarations can be used in any combination and within any element that uses the element. The elements are combined to form a union of role-to-method permissions.

20 20 Remote/home/local differentiation For example, in the following code, the first element declares that only administrators have access to the remote methods of the ProcessPayment EJB: administrator ProcessPaymentBean * Remote

21 21 Excluded Methods EJB security metadata has a rarely used feature that allows you to forbid access to one or more methods. Excluded methods are identified with the @javax.annotation.security.DenyAll annotation or with the element. Denying access to a particular method with an annotation isn't a very useful proposition. Why would you write a bean class method, add it to the business interface, and then annotate it so that it couldn't be used? Using this feature in XML, though, does have some uses. What if the ProcessPayment EJB was part of a third-party vendor library?

22 22 Excluded Methods The element could be used to turn off various features of the API per deployment. Let's look at an example: ProcessPaymentBean byCash This example disallows all access to the ProcessPaymentBean.byCash( ) method. The element can take one or more method signatures.

23 23 The RunAs Security Identity In addition to specifying the roles that have access to an enterprise bean's methods, the deployer can also specify the runAs role for the entire enterprise bean. While the @RolesAllowed annotation and elements specify which roles have access to the bean's methods, runAs specifies the role under which the method will run. The @javax.annotation.security.RunAs annotation is used to specify this special role. Although they are not allowed to use method permissions, message-driven beans can use the @RunsAs feature:

24 24 The RunAs Security Identity package javax.annotation.security; public @interface RunAs { String value( ); } @RunAs could be used to simplify our role mapping for the ProcessPayment EJB. Let's look at how TravelAgentBean would use the @RunAs annotation: package com.titan.travelagent; import javax.ejb.*; import javax.annotation.security.*;

25 25 The RunAs Security Identity @Stateful @RunAs("AUTHORIZED_MERCHANT") public class TravelAgentBean implements TravelAgentRemote {... } This can also be expressed in ejb-jar.xml: TravelAgentBean AUTHORIZED_MERCHANT

26 26 The RunAs Security Identity To specify that an enterprise bean will execute under the caller's identity rather than a propagated run-as identity, the role contains a single empty element,. The following declarations specify that the EmployeeService EJB should always execute under the caller's identity: EmployeeService The use of applies to session beans. Message-driven beans have only a runAs identity; they never execute under the caller identity because there is no "caller."

27 27 Programmatic Security Most of the security features in this chapter have focused solely on declarative security metadata, or metadata that is statically defined before an application even runs. EJB also has a small programmatic API for gathering information about a secured session. Specifically, the javax.ejb.EJBContext interface has a method for determining the concrete user that is invoking on the EJB. It also has a method that allows you to check whether the current user belongs to a certain role: package javax.ejb; public interface EJBContext { javax.security.Principal getCallerPrincipal( ); boolean isCallerInRole (String roleName); }

28 28 Programmatic Security The getCallerPrincipal( ) method returns a standard Java SE javax.security.Principal security interface. A Principal object represents the individual user that is currently invoking on the EJB. We can expand our ProcessPayment EJB to store the travel agent that logged the payment for a customer as well. This addition allows us to audit the payment if there are any problems with the transaction. package com.titan.processpayment; import javax.security.Principal; import javax.ejb.*; import javax.annotation.*;

29 29 Programmatic Security @Stateless public class ProcessPaymentBean implements ProcessPaymentLocal { @Resource SessionContext ctx;... private boolean process(int customerID, double amount, String type, String checkBarCode, int checkNumber, String creditNumber, java.sql.Date creditExpDate) throws PaymentException { Principal caller = ctx.getCallerPrincipal( ); String travelAgent = caller.getName( ); // add travelAgent to payment record... } The EJBContext.isCallerInRole( ) method allows you to determine whether the current calling user belongs to a certain role. For instance, we might want to forbid large payment transactions above a certain dollar amount for junior travel agents.

30 30 Programmatic Security To make the EJB container's job easier, you must declare all programmatic role access using the @javax.annotation.security.DeclareRoles annotation: package javax.annotation.security; @Target(TYPE) @Retention(RUNTIME) public @interface DeclareRoles { String[] value( ); } Let's use isCallerInRole( ) with the ProcessBean EJB: package com.titan.processpayment; import javax.security.Principal; import javax.ejb.*; import javax.annotation.*; import javax.annotation.security.*;

31 31 Programmatic Security @Stateless @DeclareRoles ("JUNIOR_TRAVEL_AGENT") public class ProcessPaymentBean implements ProcessPaymentLocal { @Resource SessionContext ctx; @Resource double maximumJuniorTrade = 10000.0;... private boolean process(int customerID, double amount, String type, String checkBarCode, int checkNumber, String creditNumber, java.sql.Date creditExpDate) throws PaymentException { if (amount > maximumJuniorTrade && ctx.isCallerInRole("JUNIOR_TRAVEL_AGENT")) throw new PaymentException("Travel agent is not authorized to make such a large purchase. Manager approval is required.");... }

32 32 Programmatic Security If you do not use the @DeclareRoles annotation, then you must use the element within the session bean's declaration: ProcessPaymentBean JUNIOR_TRAVEL_AGENT The element is defined within a or element. It has one subelement,, which names the role that is being referenced.


Download ppt "1 Security Most Java EE applications need to provide identity to users who access them and security for that access. Applications may want to prevent hostile."

Similar presentations


Ads by Google