阅读新的Servlet 3.0规范,我找到了HttpServletRequest的startAsynch方法,它声称以异步方式将正确的上下文信息传播给传递的runnable。
我在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中的相同行为
答案 0 :(得分:0)
声称以异步方式传播正确的东西 传递的runnable的上下文信息。
满足传播到runnable,您可以访问主体及其角色。
if(request.getUserPrincipal() != null && request.isUserInRole("admin"))
我认为ejb异步调用的最佳方法是使用@Asynchronous注释。
另请参阅:Asynchronous Method Invocation
编辑:
根据Java™ Servlet Specification Version 3.0:
Java Enterprise Edition的功能,例如第15.2.2节“Web “应用环境”,第15-174页和第15.3.1节, 第15-176页的“EJB™调用中的安全标识的传播”是 仅适用于执行初始请求的线程或何时执行 请求通过
AsyncContext.dispatch
发送到容器 方法。 Java Enterprise Edition功能可能可供其他人使用 线程直接在响应对象上运行AsyncContext.start(Runnable)
方法。
在jboss论坛中查看此主题,是一个类似的问题:Anonymous principal when invoking EJB from a thread inside a servlet。