Propagating identity

In certain situations, the identity of the user may need to be changed to enable a different, possibly more powerful, role. Consider the following analogy:

If you are familiar with the way most operating systems work, a user is not permitted to directly read or write to a file. Low-level access to the file is restricted. When a user needs to read or write to a file, the operating system will verify the individual's access rights to the file and then temporarily grant read/write access privileges to the user. The user assumes a higher level of privilege on a temporary basis.

This is analogous to the use of the @RunAs annotation. It allows a new role to be temporarily assigned to the methods of an EJB.

Getting ready

The steps used to propagate an identity include:

  1. Executing a method of an EJB using one role which invokes a method of a second EJB
  2. Executing the method of the second EJB using a different, more restrictive role as specified by the @RunAs annotation

    When a method of the second EJB is invoked from the first EJB, the identity (principal) is passed with the invocation as part of the security context. The @RunAs annotation is used to temporarily assign a new role to the current principal. When the second class' methods are invoked, the new role is assumed.

    This annotation is applied at the class level. The annotation has a single argument, a string containing the name of the role. Only one role can be assumed at a time.

    @RunAs("manager")
    

    When the @RunAs annotation is used, it is normally used in conjunction with the @DeclareRoles annotation.

How to do it...

We will add another class to the packt package to demonstrate the use of the @RunAs annotation. Let's assume when a voucher is submitted it should be verified. If it fails verification, then an exception can be thrown. In this example, we will not throw an exception so as to keep it simple. An additional restriction, which we will use to illustrate this technique, requires the methods of this verification EJB to run in the manager role.

Add a class to the packt package called VoucherVerification. Annotate the class with the @RunAs annotation using a value of "manager". In the class, inject a SessionContext object using the @Resource annotation. Add a submit method which passes and returns void. In the method, add code to use the SessionContext variable to return a principal object. This principal represents the user who invoked the method. The getCallerPrincipal method returns a Principal object. Follow the call with a println method invoking the getName method of the principal to display the principal's name.

@Stateless
@DeclareRoles("manager")
@RunAs("manager")
public class VoucherVerification {
@Resource
private SessionContext sessionContext;
public void submit() {
Principal principal = sessionContext.getCallerPrincipal();
System.out.println("Principal: " + principal.getName());
// Perform verification checks
}
}

Modify the VoucherManager class to inject an instance of the VerificationManager class. Modify its submit method to call the VerificationVoucher's submit method.

public class VoucherManager {
...
@EJB
VoucherVerification voucherVerification;
...
@RolesAllowed("employee")
public void submit() {
System.out.println("Voucher submitted");
voucherVerification.submit();
}
...
}

Modify the SecurityServlet try block to appear as follows:

out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SecurityServlet</title>");
out.println("</head>");
out.println("<body>");
voucherManager.createVoucher("Susan Billings", "SanFrancisco", BigDecimal.valueOf(2150.75));
voucherManager.submit();
out.println("<h3>Voucher name: " + voucherManager.getName() + "</h3>");
out.println("</body>");
out.println("</html>");

Execute the application using the user, "mary", first and then "sally". The output from the println method reflects the different users.

INFO: Voucher submitted

INFO: Principal: mary

INFO: Voucher submitted

INFO: Principal: sally

Even though the user, "sally", is not a manager, the submit method is still executed.

How it works...

The VoucherManager's submit method executed using the role of employee. However, we decided the VoucherValidation's submit method needed to run in the manager role. Allowing an employee to temporarily use the manager role was achieved using the @RunAs annotation.

The use of the @RunAs annotation should be used with care. Sufficient checks should be made to ensure the selected method is executed only when any restrictions placed on its use have been met. In a sense, we are augmenting declarative security with a set of criteria to meet special conditions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.222.185