处理JMS监听器的Spring Security的首选方法是什么?

pio*_*oto 7 java activemq-classic jms spring-security apache-camel

我有一个单一的Java应用程序,围绕@Service我的业务服务层的Spring bean 构建.通常,我的每个业务服务方法都有Spring Security注释(例如@PreAuthorize)来为该操作强制执行适当的授权规则.

在主Web应用程序流程中,这非常有效; 每个Web请求隐式地具有由会话cookie等处理的认证.

但是,当涉及到与其他"内部"系统的各种集成点时,我没有看到清晰的解决方案.

例如,我将从JMS队列中消耗方法,该队列已经在代理中定义了自己的身份验证和授权规则,因此我想隐含地"信任"我得到的消息.但是,就像现在的情况一样,一个简单的Camel路线如下:

WidgetService widgetService = lookup(WidgetService.class);
from("activemq:newWidget")
    .unmarshall(...)
    .bean(widgetService, "newWidget");
Run Code Online (Sandbox Code Playgroud)

最后扔了一个AuthenticationCredentialsNotFoundException.

这告诉我Camel正在正确地调用我的bean,并且从Spring应用了所有神奇的AOP.

对于其他类似的事情,我已经围绕系统的入口点(例如,围绕Quartz Jobexecute方法)应用AOP建议,这注入了一个PreAuthenticatedAuthenticationToken,但我不确定这是否真的是最好的方法.

我是否应该继续在建议中包含这些"可信"入口点以添加身份验证上下文,或者我是否应该更改我的服务层以使某些业务方法的特殊形式不需要身份验证,并确保我明确记录他们不是用于网络@Controller方法等?

Ves*_*dov 1

不幸的是,有最好的方法可以做到这一点。这取决于应用程序,根据我的经验,所有解决方案都有效,但都有一些缺点。

第一个解决方案是将 @PreAuthorize 移至 Web 级别。这样您就可以在内部随意使用您的服务。我认为这是更简单的解决方案并且更容易理解。您想保护您的网络用户吗?为什么不在 Web 层应用安全性。它的问题是,Web 层比业务层变化更频繁,如果不仔细开发控制器和端点,更容易留下安全漏洞。对于大多数应用程序,我仍然会采用这种方法,让服务层只处理业务规则而不是安全性(这也是一种业务规则?)。当然,您仍然可以向控制器组和其他内容添加一些默认的安全逻辑,这样您就不必到处重复。

第二种方法是您所采用的方法。在您生成的经过身份验证的上下文中运行此类方法。这有点反逻辑 - 当没有经过身份验证的用户时,为什么要在经过身份验证的上下文中运行?您不必这样做,但不幸的是,如果您想获得安全的服务,这是唯一的方法。这种方法不太容易出现安全错误,并且您可以更轻松地维护安全性。如果您坚持这样做,您可以使用模板模式或创建一些在上下文中运行内容的执行器类。

我想不出第三种方法:)