Spring 集成中的安全性
安全性是任何现代企业(或云)应用程序的重要功能之一。
此外,它对于分布式系统(例如构建在 Enterprise Integration Patterns 上的系统)至关重要。
消息独立性和松散耦合使目标系统能够与消息中的任何类型的数据相互通信payload
.
我们可以信任所有这些消息,也可以保护我们的服务免受 “感染” 消息的侵害。
从 version 开始6.3 整体spring-integration-security 模块被删除,以支持更常见的spring-security-messaging 图书馆。 |
保护通道
为了保护集成流中的消息通道,可以使用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>
有关更多信息,请参见 Global Channel Interceptor Configuration 。
安全上下文传播
为了确保我们与应用程序的交互是安全的,根据其安全系统规则,我们应该为一些安全上下文提供一个身份验证 (principal) 对象。
Spring Security 项目提供了一种灵活的规范机制,可以通过 HTTP、WebSocket 或 SOAP 协议对我们的应用程序客户端进行身份验证(对于具有简单 Spring Security 扩展的任何其他集成协议,可以这样做)。
它还提供了一个SecurityContext
对 Application 对象(如消息通道)进行进一步的授权检查。
默认情况下,SecurityContext
与当前Thread
通过使用 (ThreadLocalSecurityContextHolderStrategy
).
它由安全方法上的 AOP(面向方面编程)拦截器访问,以检查(例如)该principal
具有足够的权限来调用该方法。
这与当前线程配合得很好。
但是,通常可以在另一个线程、多个线程甚至外部系统上执行处理 logic 。
如果我们的应用程序构建在 Spring 集成组件及其消息通道之上,那么标准的线程绑定行为很容易配置。
在这种情况下,受保护的对象可以是任何服务激活器或转换器,使用MethodSecurityInterceptor
在他们的<request-handler-advice-chain>
(请参阅向终端节点添加行为)甚至MessageChannel
(请参阅前面的 保护通道 )。
使用DirectChannel
通信、SecurityContext
自动可用,因为下游流在当前线程上运行。
但是,在QueueChannel
,ExecutorChannel
和PublishSubscribeChannel
替换为Executor
,则根据这些通道的性质,消息从一个线程传输到另一个线程(或多个线程)。
为了支持此类方案,我们有两种选择:
-
传输
Authentication
对象,并在安全对象访问之前在另一端提取和验证它。 -
传播
SecurityContext
发送到接收传输消息的线程。
这是作为org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor
在spring-security-messaging
模块,该模块可以添加到任何MessageChannel
或配置为@GlobalChannelInterceptor
.
这个拦截器的逻辑基于SecurityContext
从当前线程中提取(从preSend()
方法),并将其从postReceive()
(beforeHandle()
) 方法。
请参阅SecurityContextPropagationChannelInterceptor
Javadocs 了解更多信息。
的繁殖和种群SecurityContext
只是作品的一半。
由于消息不是消息流中线程的所有者,并且系统应确保它免受任何传入消息的影响,因此SecurityContext
必须从ThreadLocal
.
这SecurityContextPropagationChannelInterceptor
提供afterMessageHandled()
interceptor 方法实现。
它通过在调用结束时从该传播的主体中释放线程来清理作。
这意味着,当处理已传递消息的线程完成对消息的处理(成功或其他)时,将清除上下文,以便在处理另一条消息时不会无意中使用它。
使用异步网关时,您应该使用适当的
|