阅读新的Servlet 3.0规范,我发现了HttpServletRequest的startAsynch方法,该方法声称以异步方式将正确的上下文信息传播到传递的可运行信息。
我在servlet的doGet方法中编写了以下代码:
@EJB
private EJBManagerLocal manager;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
if(request.getUserPrincipal() != null && request.isUserInRole("admin"))
//Method protected by @RolesAllowes("admin") annotation EJB-side
manager.verify();
final AsyncContext ctx = request.startAsync(request,response);
ctx.start(new Runnable(){
HttpServletRequest = (HttpServletRequest)ctx.getRequest();
if(request.getUserPrincipal() != null && request.isUserInRole("admin"))
//Method protected by @RolesAllowes("admin") annotation EJB-side
manager.verify();
});
}
第一次调用 manager.verify() 时,在 AsyncContext 之外一切正常,但是在调试中进入 Runnable 内部时,我可以看到,即使是"if"也被成功传递(因此主体已正确传播到 AsyncContext 中的 Runnable),当调用受@RolesAllowed注保护的 EJB 方法时,JBoss 会抛出一个异常,指出不允许"方法验证的调用"。
谁能帮我?
平台: JBoss EAP 6.2.0
编辑:JBoss EAP 6.3.0 中的相同行为
声称以异步方式传播权利 传递的可运行的上下文信息。
满足可运行传播的要求,您可以访问主体及其角色。
if(request.getUserPrincipal() != null && request.isUserInRole("admin"))
我认为 ejb 异步调用的最佳方法是使用@Asynchronous注释。
另请参阅:异步方法调用
编辑:
根据 Java™ Servlet 规范 3.0 版:
Java 企业版功能,例如第 15.2.2 节 "Web 应用程序环境",第 15-174 页和第 15.3.1 节, 第 15-176 页上的"EJB™ 调用中安全身份的传播"是 仅适用于执行初始请求的线程或当 请求通过
AsyncContext.dispatch
调度到容器 方法。 Java 企业版功能可能可用于其他 线程通过AsyncContext.start(Runnable)
方法。
在 jboss 论坛中看到这个线程,是一个类似的问题:从 servlet 中的线程调用 EJB 时匿名主体。