我想在从Java Web应用程序(Wicket)调用方法时将身份验证信息传递给EJB无状态会话bean。该信息由用户ID和身份验证类型(记住cookie或用户/密码)组成,并存储在http会话中。一个显而易见的解决方案是将其作为参数添加到所有EJB方法中,但这很麻烦,我希望存在另一种解决方案。
EJB bean的JNDI查找是通过Web层中的javax.naming.InitialContext#lookup(String)完成的。
是否有可移植的方法将身份验证信息添加到调用上下文中,以便bean可以使用?我需要这个过程可用于EJB层(对于最终的Web服务端点)和Web层中的调用者。
我正在使用Java EE 6.不使用CDI,我宁愿避免实现它。
身份验证由Web层处理,无状态bean验证记住cookie和用户/密码组合。当访问者首次访问该站点时,将尝试使用remember cookie进行身份验证。最终需要时,系统会要求用户使用用户名和密码登录。如上所述,身份验证状态存储在http会话中。我没有使用基于领域的Java EE安全模型,因为我无法弄清楚如何正确集成此身份验证流程。
授权方案基于动态角色,类似于Facebook根据2个用户和某些偏好之间的链接确定授权的方式。某些操作还会考虑身份验证类型。例如,修改帐户设置需要用户/密码,而cookie是不够的。根据我的理解,Java EE标准组和角色不适合这一要求。
EJB3 & How JAAS subject/principal is propagated to EJB Tier from servlet container?
Controlling the security Principle passed on a EJB call
Binding a User entity and a GlassFish Principal
Accessing the clients principal inside an ejb method
dynamic roles on a Java EE server
我希望我的问题足够明确。如果需要更多信息,我很乐意提供。
固定链接。添加关于CDI的说明。
答案 0 :(得分:9)
我认为你应该考虑:
为授权过程创建拦截器。尽管从哪个层进行了调用,它仍然会为您提供一个共同的授权位置。您可以检查是否允许调用者调用该方法或者他的会话是否仍处于活动状态(即在数据库中检查)。
在拦截器中,您可以使用InvocationContext#getContextData().put("user-related-data-name", someObj)
传递一些与用户相关的数据。在调用者EJB中,您可以使用SessionContext#getContextData()
获取此数据。
可以找到使用SessionContext
传递上下文数据的示例here
最后(也是最有趣的部分)是如何获取EJB层上的用户凭据。如果你说的是WebServices端点而不是我想你需要提供某种边界类或指定一个方法,它会为每次调用带来一些sessionId。
如果是将HttpSession
数据从Servlet传播到EJB ......这可能是一个很长的镜头,但我会考虑使用CDI。您的Servlet可能使用保存用户凭据的@SessionScoped
bean,并在拦截器中注入相同的@SessionScoped
bean。
我不确定它是否可行(在拦截器中注入CDI bean或在Servlet和EJB层之间共享@SessionScoped
。)