2

我们目前正在使用 JBoss EAP 6.4/7.0 采用 JAAS 和 JACC。只是对我们如何应用事物的简要说明:

  • 我们HttpServletRequest.login(...)用来验证
  • 随后,我们使用HttpServletRequest.logout()注销。
  • 我们有一个 LoginModule 来验证凭据并准备角色。

一切都很好,但是,我的应用程序的一部分必须允许某些用户能够:

  • 撤销其他人登录系统的角色,以及
  • 将他们踢出任何当前活动的会话。

第一部分很简单,但我很难弄清楚如何使某人的会话无效。有没有办法让我以某种方式获取其他用户的主题/会话并使其无效?

非常感激

4

1 回答 1

1

术语说明:

  • 此处的身份验证机制 (AM)指的是负责在 Java EE 运行时中生成与/在/中的身份验证的调用方实体相关的身份验证语句,并因此注册/建立身份的任何组件。此类组件可能特定于 Application Server (AS) 或 Java EE 标准;Java EE 应用程序开发人员用于扩展的 AS 实现细节或类型;作为 Java EE 应用程序的一部分或作为 AS 的一部分部署。您的JAAS LoginModule (LM)就是这样一个组件。虽然现在Identity Store (IS)似乎是(半)规范性术语,用于指代(除其他外)LM,但我想将其保留用于特定于应用程序的持久层(例如JPA @Entity) 类型代表您的用户,因此必须建立这种(定义不明确的)区别。“你为什么含糊不清?”,你可能会问,“你不能把 LM 称为 LM 吗?”。因为我对 JBoss LM 一无所知!事实上,我既不是 JBoss 用户,也不是在 Java EE 中使用 JAAS 的人。尽管如此,我觉得我可以提供一个适用于一般情况的答案,因此不可避免的含糊不清。
  • 停用用户指的是您的“即将被踢出的用户”,即,其权限(组、角色、权限——无论在那里调用什么)已被撤销的用户。 IS级别的某种方式。


首先,没有标准的 Java EE API 可以将任意用户的Subjector暴露给您的代码。HttpSession理论上,您可以自己记录该信息,例如在身份验证期间,但我会假设这不是您想要的。此外,Subject具体而言,虽然没有标准明确禁止在代表Principal的请求服务期间对其(/凭据集合)进行修改,但Subject没有声明必须这样做。实际上,甚至不清楚当前经过身份验证的调用者(在身份验证期间填充并可以通过JACC检索的调用者)是否必须Subject"javax.security.auth.Subject.container" PolicyContextHandler与运行Policy时在做出授权决策时查询的数据结构一致;也就是说,运行时可能只为您提供一个副本,在内部使用经过身份验证的调用者的完全不同的表示,或者介于两者之间。因此,即使您能够修改Subject,这样做也不一定会影响有效的安全上下文。

继续可以做的事情。您的需求可以在身份验证和/或授权方面得到解决,前一种方法比后一种方法更容易使用。由于您没有回答我的评论,因此我将简要介绍其两个可能的答案。

禁止呼叫者重新认证

一旦应用程序停用了用户,它必须以某种方式指示 AM 在他们发出的后续请求中停止重新验证他们。为了减少耦合,应用程序通常不会直接与 AM 通信,而是满足后者评估的某些条件。例如,应用程序可能会为用户分配一些特殊的“locked_out”权限,或者设置一个HttpSession属性。当被要求重新验证停用的用户时,AM 将确认停用并拒绝重新验证他们。随后它将使用户的会话无效。它将如何完成这取决于它的种类和实施。为此,您的 LM 可能不得不利用"javax.servlet.http.HttpServletRequest"JACC PolicyContextHandler贾斯皮克_ ServerAuthModule将立即访问请求实例,并将其作为validateRequest参数接收。其他一些组件可能不得不求助于使用 AS 内部,或者让应用程序承担会话失效的责任(一些调用拦截组件,例如Servlet Filter,必须第二次查询 IS 并采取相应措施)。

上述方法显然需要能够修改 AM 的功能。此外,缓存 AM 需要在重新使用其先前建立的身份验证结果之前评估所述停用条件。最后,如评论中所述,如果在用户的 IS 访问撤销时,代表该用户的请求正在接受服务(在访问撤销事件发生之前已到达/已通过身份验证) ,该请求的服务正常完成(除非应用程序请求重新验证该用户,例如通过HttpServletRequest#login| authenticate)。

禁止来电重新授权

虽然,正如我在开始时提到的,用户的Subjects 不容易检索/修改,但Policy在符合 JACC 的 Java EE 运行时上,那些获得授权的支持实际上是。不幸的是,默认的 AS 提供的 JACC 提供程序 ( PolicyConfiguration+ Policy) 有一个严重的限制:它只允许您对 Java EE角色进行操作,而不是对映射到Principal的调用者进行操作,即“拥有”这些角色。例如,默认提供程序允许您扩展映射到“admin”角色的 s ;它允许您删除“管理员”角色及其所有角色;但它不允许你决定PermissionPrincipalPermission成为“管理员”——至少不是以标准方式。

就 JACC 而言,这个限制基本上给您留下了两种选择:或者让 AM为每个调用者添加一个“虚拟” ,与相应调用者的名称相同。然后,在用户停用时,添加(通过)与“虚拟”组有关的自定义。最后,从“应用程序空间”代码中检查(例如,通过 AccessController#checkPermission)用户是否有,如果有,将他们踢出。但是等等,这完全没有意义——如果它不能自己处理授权,为什么还要费心使用呢?另一种方法是编写和安装您自己的 JACC 提供程序。这样做可以让您完全控制PrincipalSubjectPrincipalPolicyConfiguration#addToRolePermissionPermissionPolicyPrincipal-/group-to-role 映射,使您能够随心所欲地采取行动,授权明智的,从那时起使用该信息。不过,编写一个新的提供者并非易事,特别是因为它必须适应JRE范围内的授权需求,而不仅仅是在单个应用程序的范围内。我怀疑您的要求是否证明了如此高的工作量是合理的。如果您仍然想走这条路,那么 Arjan Tijms博客上与 JACC 相关的文章是一个很好的起点。

于 2016-11-06T11:04:20.833 回答