为 JMS 侦听器处理 Spring Security 的首选方法是啥?
Posted
技术标签:
【中文标题】为 JMS 侦听器处理 Spring Security 的首选方法是啥?【英文标题】:What's the preferred way to handle Spring Security for JMS Listeners?为 JMS 侦听器处理 Spring Security 的首选方法是什么? 【发布时间】:2019-01-01 14:37:59 【问题描述】:我有一个有点单一的 Java 应用程序,围绕 Spring @Service
bean 构建,用于我的业务服务层。作为一项规则,我的每个业务服务方法都有 Spring Security 注释(例如@PreAuthorize
)来为该操作强制执行适当的授权规则。
在主要的 Web 应用程序流程中,这非常有效;每个 Web 请求都隐含由会话 cookie 等处理的身份验证。
但是,当涉及到与其他“内部”系统的各种集成点时,我并没有明确的解决方案。
例如,我将使用 JMS 队列中的方法,该队列已经在代理中定义了自己的身份验证和授权规则,因此我想隐含地“信任”我收到的消息。然而,就目前的情况而言,像这样一个足够简单的骆驼路线:
WidgetService widgetService = lookup(WidgetService.class);
from("activemq:newWidget")
.unmarshall(...)
.bean(widgetService, "newWidget");
最终抛出AuthenticationCredentialsNotFoundException
。
这告诉我 Camel 正确调用了我的 bean,所有的魔法 AOP 都是从 Spring 中应用的。
对于其他这类事情,我已经求助于在系统入口点周围应用 AOP 建议(例如,围绕 Quartz Job
的 execute
方法),它注入 PreAuthenticatedAuthenticationToken
,但我'不确定这是否真的是最好的方法。
我应该继续将这些“受信任”入口点包装在建议中以添加身份验证上下文,还是应该更改我的服务层以具有某些不需要身份验证的特殊形式的业务方法,并确保我清楚地记录了这一点它们不适用于 web @Controller
方法等?
【问题讨论】:
【参考方案1】:不幸的是,有最好的方法来做到这一点。这取决于应用程序,根据我的经验,所有解决方案都有效,但有一些缺点。
第一个解决方案是将@PreAuthorize 移至网络级别。这样,您就可以在内部随意使用您的服务。我认为这是更简单的解决方案,更容易理解。您想保护您的网络用户吗?为什么不在 web 层中应用安全性。它的问题是 Web 层比业务层更频繁地更改,如果您不仔细开发控制器和端点,则更容易留下安全漏洞。对于大多数应用程序,我仍然会采用这种方法,让服务层只处理业务规则而不是安全性(这也是一种业务规则吗?)。当然,您仍然可以向控制器组和其他东西添加一些默认的安全逻辑,这样您就不必到处重复自己了。
第二种方法是您采用的方法。在您生成的经过身份验证的上下文中运行此类方法。这有点反逻辑——当没有经过身份验证的用户时,为什么要在经过身份验证的上下文中运行?你不应该这样做,但不幸的是,如果你想获得安全的服务,这是唯一的方法。这种方法不太容易出现安全错误,并且您可以更轻松地维护安全性。如果你坚持这一点,你可以使用模板模式或创建一些在上下文中运行东西的执行器类。
我想不出第三种方法:)
【讨论】:
谢谢,我很高兴没有一个简单的答案。 :) 如果您有任何示例说明您如何专门使用 Camel 处理第二个解决方案,我将不胜感激。我的想法是,我基本上只是继续使用 Spring AOP,并在 Camel 中使用.bean
路由在全连接 bean 上?
我没有使用过 Camel,但在我当前的项目中,我们创建了一个名为“AuthenticatedContextExecutor”或类似名称的 bean,当我们需要在 webcontext 之外运行某些东西时,我们称之为 executor.execute(任务,作为用户);不完全相同但相似;)问题在于您还需要传递某种系统用户,特别是如果您在系统中跟踪谁修改了什么以上是关于为 JMS 侦听器处理 Spring Security 的首选方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章