Spring 集成中的安全性

春季集成中的安全性

安全是任何现代企业(或云)应用中的重要职能之一。 此外,对于分布式系统(如基于企业集成模式构建的系统)尤为关键。 消息独立性和松耦合使目标系统能够通过消息中的任何类型的数据相互通信有效载荷. 我们可以选择信任所有这些消息,或者保护我们的服务免受“感染”消息的侵害。spring-doc.cadn.net.cn

Spring Integration与Spring Security共同提供一种简单且全面的方式来保护消息通道以及集成解决方案的其他部分。 从6.0版本开始,通道安全拦截器以及其结构通过以下方式@SecuredChannel注释与XML<安全通道>被淘汰以支持使用授权通道拦截者来自Spring-安全-消息模块。 各自授权管理器基础设施完全覆盖了之前支持的角色认证,并且允许配置任何其他可能的授权策略。spring-doc.cadn.net.cn

Spring 集成中唯一剩下的功能是安全上下文传播通道拦截器该职位可晋升为上述Spring-安全-消息未来也会有模块。spring-doc.cadn.net.cn

你需要把这种依赖性纳入你的项目中:spring-doc.cadn.net.cn

梅文
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-security</artifactId>
    <version>6.0.9</version>
</dependency>
格拉德勒
compile "org.springframework.integration:spring-integration-security:6.0.9"

保护通道

为了在集成流程中保护消息通道,需要授权通道拦截者必须添加到这些信道中,或者可以配置为具有相应模式的全局信道拦截器:spring-doc.cadn.net.cn

Java
@Bean
@GlobalChannelInterceptor(patterns = "secured*")
AuthorizationChannelInterceptor authorizationChannelInterceptor() {
    return new AuthorizationChannelInterceptor(AuthorityAuthorizationManager.hasAnyRole("ADMIN", "PRESIDENT"));
}
XML
<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 扩展即可实现)。 它还提供了安全上下文用于对应用对象(如消息通道)进行进一步授权检查。默认情况下,安全上下文与当前的执行状态相关联线通过使用(线程本地安全上下文持有者策略). 它通过AOP(面向切面编程)拦截器通过安全方法访问,以检查(例如)是否主要调用有足够的权限调用该方法。这在当前线程中运行良好。不过,处理逻辑通常可以在另一个线程、多个线程上,甚至外部系统上执行。spring-doc.cadn.net.cn

如果我们的应用基于 Spring Integration 组件及其消息通道构建,标准线程绑定行为很容易配置。在这种情况下,受保护对象可以是任何服务激活器或变换器,并通过方法安全拦截者在他们的<请求-处理-建议链>(参见“向端点添加行为”)甚至消息频道(参见前文“保护通道”)使用直达频道通信,以及安全上下文是自动可用的,因为下游流运行在当前线程上。然而,在队列通道,执行者频道发布订阅频道带有执行者消息会根据这些通道的特性从一个线程传输到另一个线程(或多个线程)。为了支持此类情景,我们有两个选择:spring-doc.cadn.net.cn

引入版本4.2安全上下文增殖。 它被实现为安全上下文传播通道拦截器,你可以将它添加到任意消息频道或配置为@GlobalChannelInterceptor. 该拦截器的逻辑基于安全上下文从当前线程中提取(从preSend()方法)并且从另一个线程中填充到另一个线程。postReceive() (beforeHandle())方法。实际上,这款拦截器是更通用的线程状态传播通道拦截器,它将要发送的消息包裹在内部传播的状态中留言<?>扩展(MessageWithThreadState<S>一侧提取原始消息和另一侧传播的状态。你可以扩展线程状态传播通道拦截器对于任何上下文传播的用例,安全上下文传播通道拦截器是这样做的一个好例子。spring-doc.cadn.net.cn

逻辑线程状态传播通道拦截器基于消息修改(它返回内部MessageWithThreadState发送对象)。因此,在将该拦截器与其他也能修改消息的拦截器结合使用时,应当谨慎(例如,通过MessageBuilder.withPayload[...] …​ build()). 传播的状态可能会丢失。在大多数情况下,为了解决这个问题,你可以订购该通道的拦截器并确保线程状态传播通道拦截器是堆栈中的最后一个。

繁殖与种群安全上下文只是工作的一半。由于消息不是消息流中线程的所有者,我们应确保对任何来消息都有安全防护,因此必须清理安全上下文ThreadLocal. 这安全上下文传播通道拦截器提供afterMessageHandled()拦截方法的实现。它通过在调用结束时释放线程,从而清理作,使其不再受该传播主体控制。这意味着,当处理交接消息的线程完成消息处理(无论是否成功)时,上下文会被清除,避免在处理其他消息时被误用。spring-doc.cadn.net.cn

使用异步网关时,应使用合适的摘要委托安全上下文支持通过 Spring Security 并发支持实现,确保安全上下文传播通过网关调用实现。以下示例展示了如何实现:spring-doc.cadn.net.cn

@Configuration
@EnableIntegration
@IntegrationComponentScan
public class ContextConfiguration {

    @Bean
    public AsyncTaskExecutor securityContextExecutor() {
        return new DelegatingSecurityContextAsyncTaskExecutor(
                         new SimpleAsyncTaskExecutor());
    }

}

@MessagingGateway(asyncExecutor = "securityContextExecutor")
public interface SecuredGateway {

    @Gateway(requestChannel = "queueChannel")
    Future<String> send(String payload);

}