EJB3.1 TimerService @Timeout current principal
I have a question regarding authentication and the TimerService @Timeout annotation :
In our application users can schedule tasks to be performed at a given interval, They select from a list of tasks, each task is associated to a specific EJB in the application. When the user presses the save button a new timer is added to the Timer service, when the @Timeout method is invoked, a method on the EJB that the user specified is invoked from with the @Timeout method
When the timeout method is ivoked by the Timerservice, the current principal is "ANONYMOUS". This is problematic if you need to invoke any protected EJB's from within the timout method. Is it pos开发者_如何学运维sible to change the current principal and role to the same principal and role as user that created the timer?
@Singleton
@LocalBean
public class TestEJB
{
@Resource
SessionContext context;
@Resource
TimerService timerService;
@Timeout
public void execute(Timer timer) throws Exception {
//Get the current username
System.out.println(context.getCallerPrincipal().getName());
}
public void createScheduledTimer(ScheduleExpression e,String timerId) throws IllegalArgumentException, IllegalStateException, EJBException {
TimerConfig tc = new TimerConfig();
tc.setInfo(timerId);
tc.setPersistent(true);
timerService.createCalendarTimer(e, tc);
}
}
We did this in Glassfish. In our case we have a generic Timer bean that can run any of several tasks, rather than a bean per task as you are doing, but the concept is the same.
What we ended up doing is we record the user when the task is submitted, then we leverage Glassfish's specific ProgramaticLogin facility to log the user back in when the timer starts. That way the entire EJB security context is setup appropriately for the user and the task.
try to use @RunAs. check the example here: http://www.shareyourwork.org/roller/ralphsjavablog/entry/using_runas_in_ejb_3
Since you are using 3.1 Stateful Session Beans are supported for Timers. Try annotating your bean with @Stateful
rather than @Singleton
. Then try getting the username in your createScheduledTimer
method. Store it as a private field, and then access it in the @Timeout method.
精彩评论