Spring Integration:SecurityContext传播

时间:2016-07-18 15:48:02

标签: spring spring-security spring-integration

我对Spring Integration中的SecurityContext传播感到困惑。

以下是文档的要点:

http://docs.spring.io/spring-integration/reference/htmlsingle/#security-context-propagation

我的困惑如下:

  

(1)为确保我们与应用程序的互动安全,   根据其安全系统规则,我们应该提供一些安全保障   具有身份验证(主体)对象的上下文。春天   安全项目提供了灵活的规范机制   通过HTTP,WebSocket或SOAP验证我们的应用程序客户端   协议(可以用于任何其他集成协议   简单的Spring Security扩展)并且它提供了一个SecurityContext   进一步授权检查应用程序对象,例如   消息频道。默认情况下,SecurityContext与   当前线程的执行状态使用   (ThreadLocalSecurityContextHolderStrategy)。它由AOP访问   拦截器上的安全方法来检查是否存在该主体   例如,调用具有足够的权限来调用该方法。     这适用于当前线程但经常,处理逻辑   可以在另一个线程上执行,甚至可以在多个线程上执行   到某些外部系统

这意味着SecurityContext(通常)只能由当前Thread访问。正确?

那么,如何使其可以访问另一个应用程序的另一个线程(与Spring Integration集成)?

  

(2)如果我们的应用程序是在Spring Integration组件上构建的,那么标准的线程绑定行为很容易配置   消息频道。 在这种情况下,安全对象可以是任何对象   服务激活器或变压器,用   他们的MethodSecurityInterceptor     (参见第8.8节“向端点添加行为”)或甚至   MessageChannel(参见上文第D.2节“保护渠道”)。什么时候   使用DirectChannel通信,SecurityContext可用   自动,因为下游流在当前线程上运行。     但是在QueueChannel,ExecutorChannel和   PublishSubscribeChannel与Executor一起传输消息   从一个线程到另一个线程(或几个)的性质   通道。为了支持这种情况,我们可以转移   消息头中的身份验证对象并提取和   在安全对象访问之前在另一端验证它。     或者,我们可以将SecurityContext传播到接收的线程   已转移的消息

这意味着我们必须手动提取Principal?如果是,怎么样?

或者它足以使用传播方面,从4.2版本?

  

(3)从版本4.2开始 SecurityContext传播已经   介绍。它被实现为   SecurityContextPropagationChannelInterceptor,可以简单地说   添加到任何MessageChannel或配置为   @GlobalChannelInterceptor 即可。这个拦截器的逻辑是基于   从当前线程中提取SecurityContext   preSend()方法,并将其填充到另一个线程中   postReceive()(beforeHandle())方法。实际上,这个拦截器   是更通用的扩展   ThreadStatePropagationChannelInterceptor,它包装了   message-to-send与state-to-propagate一起发送到内部   消息扩展 - MessageWithThreadState, - 一边和   提取原始消息并在另一个消息上传播状态。     ThreadStatePropagationChannelInterceptor可以扩展为任何   上下文传播用例和   SecurityContextPropagationChannelInterceptor是一个很好的示例   物质

"从版本4.2开始,已经引入了SecurityContext传播。" =>好的,非常好。

但是:"它是作为SecurityContextPropagationChannelInterceptor实现的,可以简单地添加到任何MessageChannel或配置为@GlobalChannelInterceptor。"

这是什么意思?我必须实现一个扩展" SecurityContextPropagationChannelInterceptor" ?

我必须&#34;添加&#34;在我的<int:channel>配置中?

如果我使用<int:channel-interceptor>(与@GlobalChannelInterceptor相同),它与使用<int:interceptors>不同?

其他困惑:

&#34;此拦截器的逻辑基于来自preSend()方法的当前线程的SecurityContext提取,并从postReceive()填充到另一个线程     (beforeHandle())方法。&#34;

但为什么"obtainPropagatingContext"类中有 "populatePropagatedContext" 方法和 SecurityContextPropagationChannelInterceptor 方法? 传播在哪里?在preSend()/ postReceive()方法中,还是在这两种方法中?

此外,我尝试将SecurityContext传播到外部应用程序,但没有成功......

对此论点的任何解释都将不胜感激。

1 个答案:

答案 0 :(得分:3)

这里有很多问题,但让我试着回答一下。

  1. 这是什么意思?我必须实现一个扩展“SecurityContextPropagationChannelInterceptor”的拦截器?
  2. 不,框架中有这样的拦截器开箱即用。您需要做些什么来了解如何将拦截器添加到MessageChannelhttp://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#channel-configuration-interceptors

    或者像这样:

    @Bean
    @GlobalChannelInterceptor(patterns = {
            "#{'queueChannel'}",
            "${security.channel:executorChannel}",
            "publishSubscribeChannel" })
    public ChannelInterceptor securityContextPropagationInterceptor() {
        return new SecurityContextPropagationChannelInterceptor();
    }
    

    有关更多信息,请参阅他们的JavaDocs。

    1. 但是为什么SecurityContextPropagationChannelInterceptor类中有“obtainPropagatingContext”方法和“populatePropagatedContext”方法?
    2. SecurityContextPropagationChannelInterceptor extends ThreadStatePropagationChannelInterceptor<Authentication>,其中obtainPropagatingContextpopulatePropagatedContext只是在State(在线程上)中提取一些当前preSend()的通用方法,并提供State 1}}用于postReceive()中的填充/操作,这可能发生在不同的线程中。

      1. 是的,SecurityContext在Spring Security中是线程绑定的,并且确保我们可以执行安全功能的逻辑完全基于ThreadLocal变量。这就是为什么我们必须以这种方式转移它。 “传播”是一个不是状态的过程。
      2. 不确定您对“外部应用程序”的意思,但只有一种机制可以做到这一点:将凭据与请求一起发送到该应用程序。