我对 Spring Integration 中的 SecurityContext 传播有一些困惑。
这是文档的要点:
http://docs.spring.io/spring-integration/reference/htmlsingle/#security-context-propagation http://docs.spring.io/spring-integration/reference/htmlsingle/#security-context-propagation
我的困惑如下:
(1)为了确保我们与应用程序的交互是安全的,
根据其安全系统规则,我们应该提供一些安全保障
具有身份验证(主体)对象的上下文。春天
安全项目提供了一种灵活的、规范的机制
通过 HTTP、WebSocket 或 SOAP 对我们的应用程序客户端进行身份验证
协议(可以对任何其他带有
简单的 Spring Security 扩展),它提供了一个 SecurityContext
对应用程序对象进行进一步的授权检查,例如
消息渠道。默认情况下,SecurityContext 与
当前线程的执行状态使用
(ThreadLocalSecurityContextHolderStrategy)。它是通过 AOP 访问的
安全方法上的拦截器来检查该主体是否
例如,调用有足够的权限来调用该方法。这适用于当前线程, 但经常、处理逻辑可以执行在另一个线程上,甚至在多个线程上,或者在到某些外部系统.
这意味着 SecurityContext(通常)只能由当前线程访问。正确的?
那么,如何使其可供另一个应用程序的另一个线程访问(与 Spring Integration 集成)?
(2)如果我们的应用程序构建在 Spring Integration 组件及其之上,则标准线程绑定行为很容易配置
消息渠道。在这种情况下,受保护的对象可以是任何
服务激活器或变压器,用一个固定MethodSecurityInterceptor
在他们的
(参见第 8.8 节,“向端点添加行为”)或者甚至MessageChannel
(参见上文 D.2 节“保护通道”)。什么时候
使用 DirectChannel 通信,SecurityContext 可用
自动,因为下游流在当前线程上运行。
但对于 QueueChannel、ExecutorChannel 和
带有Executor的PublishSubscribeChannel,消息传输
根据这些线程的性质从一个线程到另一个(或多个)线程
渠道。为了支持此类场景,我们可以转移
消息头中的 Authentication 对象并提取和
在安全对象访问之前在另一端对其进行身份验证.
或者,我们可以将 SecurityContext 传播到接收该消息的线程
传送的消息.
这意味着我们必须手动提取Principal?如果是,怎么办?
或者从 4.2 版本开始使用传播方面就足够了?
(3)从4.2版本开始安全上下文传播已经
介绍了。它被实现为SecurityContextPropagationChannelInterceptor
, 这可以简单地是
添加到任何MessageChannel
或配置为@GlobalChannelInterceptor
。该拦截器的逻辑基于
从当前线程中提取SecurityContextpreSend()
方法,并将其填充到另一个线程postReceive()
(beforeHandle()) 方法。其实这个拦截器
是更通用的扩展
ThreadStatePropagationChannelInterceptor,它包装了
消息发送与内部传播状态一起
消息扩展 - MessageWithThreadState, - 在一侧,并且
提取原始消息并将其状态传播到另一个消息上。
ThreadStatePropagationChannelInterceptor 可以扩展为任何
上下文传播用例和
SecurityContextPropagationChannelInterceptor 是一个很好的示例
事情。
“从版本 4.2 开始,引入了 SecurityContext 传播。”=> 好的,很好。
But: “它是作为 SecurityContextPropagationChannelInterceptor 实现的,可以简单地添加到任何 MessageChannel 或配置为 @GlobalChannelInterceptor。”
这是什么意思?我必须实现一个扩展“SecurityContextPropagationChannelInterceptor”的拦截器?
我必须在我的中“添加”什么<int:channel>
配置?
如果我使用<int:channel-interceptor>
(与@GlobalChannelInterceptor相同),它与使用不同<int:interceptors>
?
其他困惑:
“该拦截器的逻辑基于通过 preSend() 方法从当前线程提取 SecurityContext,并通过 postReceive() 填充到另一个线程
(beforeHandle()) 方法。”
但为什么有一个"obtainPropagatingContext"
方法和一个"populatePropagatedContext"
方法中的SecurityContextPropagationChannelInterceptor
班级?
在哪里进行传播?在 preSent() / post Receive() 方法中,还是在这两个方法中?
此外,我尝试将 SecurityContext 传播到外部应用程序,但没有成功......
关于这一论点的任何解释将不胜感激。