36.1 DelegatingSecurityContextRunnable委托安全上下文可运行

Spring Security并发支持中最基本的构件之一是delegatingsecuritycontextrunable。它包装一个可运行的委托,以便用为该委托指定的安全上下文SecurityContext 来初始化安全上下文容器SecurityContextHolder 。然后,它调用委托Runnable,确保随后清除SecurityContextHolder。delegatingsecuritycontextrunable看起来像这样:

1 public void run() {
2 try {
3     SecurityContextHolder.setContext(securityContext);
4     delegate.run();
5 } finally {
6     SecurityContextHolder.clearContext();
7 }
8 }

虽然非常简单,但它可以无缝地将安全上下文从一个线程转移到另一个线程。这一点很重要,因为在大多数情况下,安全上下文持有者基于每个线程进行操作。例如,您可能使用了Spring Security的第41.4.1节“<global-method-security>”支持来保护您的一项服务。现在,您可以轻松地将当前线程的安全上下文转移到调用安全服务的线程。您可以在下面找到这样做的示例:

 1 Runnable originalRunnable = new Runnable() {
 2     public void run() {
 3      // invoke secured service
 4    }
 5 };
 6 
 7 SecurityContext context = SecurityContextHolder.getContext();
 8 DelegatingSecurityContextRunnable wrappedRunnable = new DelegatingSecurityContextRunnable(originalRunnable, context);
10 new Thread(wrappedRunnable).start();

上面的代码执行以下步骤:

  创建一个将调用我们的安全服务的Runnable。请注意,它不知道Spring安全性

  从SecurityContextHolder获取我们希望使用的安全上下文,并初始化delegatingsecuritycontextrunable

  使用delegatingsecuritycontextrunable创建一个线程

  启动我们创建的线程

由于从SecurityContextHolder创建一个带有SecurityContext的delegatingsecuritycritycontextranable是很常见的,所以有一个快捷构造函数。以下代码与上面的代码相同:

 1 Runnable originalRunnable = new Runnable() {
 2   public void run() {
 3     // invoke secured service
 4   }
 5 };
 6 
 7 DelegatingSecurityContextRunnable wrappedRunnable =   new DelegatingSecurityContextRunnable(originalRunnable);
 8 new Thread(wrappedRunnable).start();

我们拥有的代码使用起来很简单,但是仍然需要知道我们正在使用Spring Security。在下一节中,我们将了解如何利用delegatingsecuritytycontextexecutor来隐藏我们正在使用Spring Security的事实。

原文地址:https://www.cnblogs.com/jrkl/p/13510055.html