我有一个关于身份验证和TimerService @Timeout注释的问题:
在我们的应用程序中,用户可以安排以给定间隔执行的任务。他们从任务列表中选择,每个任务都与应用程序中的特定EJB相关联。当用户按下保存按钮时,会向Timer服务添加一个新的计时器,当调用@Timeout方法时,使用@Timeout方法调用用户指定的EJB上的方法
当Timerservice假定超时方法时,当前主体是“ANONYMOUS”。如果您需要从timout方法中调用任何受保护的EJB,则会出现问题。是否可以将当前主体和角色更改为与创建计时器的用户相同的主体和角色?
@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);
}
}
答案 0 :(得分:1)
答案 1 :(得分:1)
我们在Glassfish中做到了这一点。在我们的例子中,我们有一个通用的Timer bean,它可以运行任何一个任务,而不是像你一样在每个任务中运行bean,但概念是相同的。
我们最终做的是在提交任务时记录用户,然后我们利用Glassfish特定的ProgramaticLogin工具在计时器启动时将用户重新登录。这样就可以为用户和任务正确设置整个EJB安全上下文。
答案 2 :(得分:0)
因为您正在使用3.1有状态会话Bean支持定时器。尝试使用@Stateful
而不是@Singleton
来注释您的bean。然后尝试使用createScheduledTimer
方法获取用户名。将其存储为私有字段,然后在@Timeout方法中访问它。