【问题标题】:Adding custom context information to EJB method calls将自定义上下文信息添加到 EJB 方法调用
【发布时间】:2011-12-22 11:12:27
【问题描述】:

我想在从 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 和用户/密码组合。当访问者第一次访问该站点时,会尝试使用记忆 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 的注释。

【问题讨论】:

标签: security authentication jakarta-ee ejb-3.0 java-ee-6


【解决方案1】:

我认为你应该考虑:

  1. 为授权过程创建拦截器。无论调用来自哪个层,它都会为您提供一个通用的授权位置。您可以检查调用者是否被允许调用该方法,或者他的会话是否仍然处于活动状态(即在数据库中检查)。

  2. 在拦截器中,您可以使用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)。

【讨论】:

  • (不得不将我的回复分成 3...)关于 2,这是一个好主意,特别是如果我可以在没有方法参数的情况下传递上下文信息。否则,我将不得不在参数列表上使用反射来查找哪个包含身份验证信息。
  • 关于 1,虽然拦截器存在一个问题,但有一个方法签名,如 removeTransaction(AuthenticationInfo authInfo, long personId, long transactionId)。在这种情况下,授权依赖于personId,但拦截器不获取参数名称,而只获取参数类型。因此,知道是使用参数#2 还是#3 的唯一方法是在可能与方法声明不同步的地方添加元数据。如果授权是在removeTransaction 的主体中作为方法调用完成的,则情况并非如此。
  • 至于 CDI,我目前不使用它,而且我认为它不够成熟,尤其是在与我的 Web 框架 (Wicket) 的集成方面,并没有让我想要制作转变。不过我可能是错的。然而,你的想法当然是一个有趣的想法。它让我找到了stackoverflow.com/questions/2607019/…,这让我有了更多的了解。
  • AD 2. 是 - AFAIR - 无需指定其他方法参数即可添加。 AD 1. 好吧,如果您担心我可以考虑使用自定义注释,例如@AuthorizationData;与拦截器相比,您可以使用 InvocationContext#getMethod()#getParameterAnnotations(),然后搜索分配了@AuthorizationData 的参数,这将是您要获取的参数的编号。
  • @Bernie,我添加了指向我展示了如何使用 contextData 的页面的链接。希望对你有所帮助。
猜你喜欢
  • 1970-01-01
  • 2013-05-09
  • 2018-07-12
  • 2013-12-01
  • 2015-09-11
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多