|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
Spring Integration 安全性
安全性是任何现代企业(或云)应用程序的重要功能之一。
此外,对于分布式系统(例如基于企业集成模式构建的系统)而言,安全性至关重要。
消息独立性和松耦合允许目标系统通过消息的 payload 以任意类型的数据相互通信。
我们可以选择信任所有此类消息,也可以保护我们的服务免受“感染性”消息的攻击。
从版本 6.3 开始,整个 spring-integration-security 模块已被移除,转而采用更常用的 spring-security-messaging 库所提出的 API。 |
安全通道
为了在集成流程中保护消息通道,必须向这些通道添加一个AuthorizationChannelInterceptor,或者将其配置为具有相应模式的全局通道拦截器:
-
Java
-
XML
@Bean
@GlobalChannelInterceptor(patterns = "secured*")
AuthorizationChannelInterceptor authorizationChannelInterceptor() {
return new AuthorizationChannelInterceptor(AuthorityAuthorizationManager.hasAnyRole("ADMIN", "PRESIDENT"));
}
<channel-interceptor pattern="securedChannel*">
<beans:bean class="org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.authorization.AuthorityAuthorizationManager"
factory-method="hasAnyRole">
<beans:constructor-arg>
<beans:array>
<beans:value>ADMIN</beans:value>
<beans:value>PRESIDENT</beans:value>
</beans:array>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</channel-interceptor>
有关更多信息,请参阅全局通道拦截器配置。
安全上下文传播
为确保我们与应用程序的交互符合其安全系统规则且安全可靠,我们需要提供包含认证(主体)对象的安全上下文。Spring Security 项目提供了一种灵活且标准的机制,用于通过 HTTP、WebSocket 或 SOAP 协议(也可通过简单的 Spring Security 扩展支持任何其他集成协议)对我们的应用程序客户端进行身份验证。它还为应用程序对象(如消息通道)提供进一步的授权检查,并返回 SecurityContext。默认情况下,SecurityContext 通过 (ThreadLocalSecurityContextHolderStrategy) 与当前 Thread 的执行状态绑定。它通过一个在安全方法上应用的 AOP(面向切面编程)拦截器来访问,用于检查(例如)该调用的 principal 是否具有调用该方法的足够权限。这与当前线程配合良好。不过,处理逻辑可以在另一个线程上执行,也可以在多个线程上执行,甚至可以在外部系统上执行。
如果我们的应用程序构建在 Spring Integration 组件及其消息通道之上,那么配置标准线程绑定行为非常简单。
在这种情况下,被保护的对象可以是任何服务激活器或转换器,它们在其 MethodSecurityInterceptor(参见 向端点添加行为)中使用 <request-handler-advice-chain> 进行保护,甚至是 MessageChannel(参见前文的 保护通道)。
在使用 DirectChannel 通信时,SecurityContext 会自动可用,因为下游流程运行在当前线程上。
然而,对于 QueueChannel、ExecutorChannel 和 PublishSubscribeChannel 的情况,若配合 Executor 使用,消息会通过这些通道的特性从一个线程转移到另一个(或多个)线程。
为了支持此类场景,我们有两个选择:
-
在消息头中传输
Authentication对象,并在另一侧提取和验证该对象后,再进行安全对象访问。 -
将
SecurityContext传播到接收已传输消息的线程。
这实现在 org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor 模块中作为 org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor,可以添加到任何 MessageChannel 或配置为 @GlobalChannelInterceptor。
该拦截器的逻辑基于从当前线程(来自 preSend() 方法)提取的 SecurityContext,并将其填充到来自 postReceive() (beforeHandle()) 方法的另一个线程中。
有关更多信息,请参阅 SecurityContextPropagationChannelInterceptor Javadocs。
传播和填充SecurityContext只是工作的一半。
由于消息不是消息流中线程的所有者,且系统必须确保能防御任何传入的消息,因此必须从ThreadLocal中清理SecurityContext。
SecurityContextPropagationChannelInterceptor提供了afterMessageHandled()拦截器方法的实现。
它通过在执行结束时释放由该传播主体(principal)所关联的线程来完成清理操作。
这意味着,当处理移交消息的线程完成消息处理(无论成功与否)时,上下文将被清除,以防止在处理其他消息时意外使用它。
|
在使用 异步网关 时,您应使用 Spring Security 并发支持 中适当的
|