安全上

我刚刚宣布了新消息学习春天安全课程,包括完整的材料集中在新的OAuth2堆栈在Spring Security 5:

>>看看这个课程

1.介绍

在本教程中,我们将重点放在Spring Security主体的传播@Async

默认情况下,Spring安全身份验证被绑定到ThreadLocal-所以,当执行流运行在一个新的线程@Async,这将不是一个验证上下文。

这不理想,我们来解决它。

2.Maven的依赖关系

为了在Spring Security中使用异步集成,我们需要在依赖关系我们的pom.xml

<依赖> < groupId > org.springframework。安全< / groupId > < artifactId > spring-security-config < / artifactId > <版本> 5.2.3。依赖版本< / > < / >

可以找到Spring Security依赖项的最新版本这里

3.Spring安全传播@Async

让我们先写一个简单的例子:

@RequestMapping(方法= RequestMethod。GET,值= "/async") @ResponseBody公共对象standardProcessing()抛出异常{log.info("在async调用之前@Async逻辑之外:" + SecurityContextHolder.getContext().getAuthentication().getPrincipal());asyncService.asyncCall ();log.info("内部的@Async逻辑-之后的async调用:" + securitycontexthholder . getcontext ().getAuthentication().getPrincipal());.getPrincipal .getAuthentication返回SecurityContextHolder.getContext () () ();}

我们想检查一下SpringSecurityContext.传播到新线程。首先,在异步调用之前记录上下文,然后运行异步方法,最后再次记录上下文。的asynccall()方法具有以下实现:

@Async @Override public void asyncall () {log.info("内部的@Async逻辑:" + SecurityContextHolder.getContext().getAuthentication().getPrincipal());}

正如我们所看到的,只有一行代码将在异步方法的新线程中输出上下文。

4.默认配置

类内部的安全上下文默认为@Async方法将有一个价值。

特别是,如果我们将运行异步逻辑,我们将能够记录身份验证主程序中的对象,但是当我们将其登录时@Async,它将是。这是一个日志输出的示例:

web - 2016-12-30 22:41:58,916 [http-nio-8081-exec-3] INFO o.金宝搏188体育baeldung.web.service.AsyncService -外部的@Async逻辑-在异步调用之前:[电子邮件受保护]7楼:用户名:暂时的;...[http-nio-8081-exec-3] INFO o.baeldung.web.service.AsyncServ金宝搏188体育ice -内部的@Async逻辑-在async调用后:[电子邮件受保护]:用户名:暂时的;...网页 -  2016-12-30 22:41:58,926 [simpleoSynctaskexecutor-1]错误o.s.a.i.simpleasyncuncyAckexceptionHandler  - 调用Async方法'public void com.baeldung.web.service.asyncserviceimpl.asyncpa金宝搏188体育ll()'中出现意外错误。java.lang.nullpointerexception:null.

因此,正如您所看到的,在executor线程中,我们的调用以NPE失败,正如预期的那样——因为那里没有可用的主体。

5.异步安全上下文配置

如果我们希望访问异步线程内的主体,就像我们在外面访问它一样,我们需要创建DelegatingSecurityContextAsyncTaskExecutor豆:

@Bean public DelegatingSecurityContextAsyncTaskExecutor taskExecutor(ThreadPoolTaskExecutor delegate) {return new DelegatingSecurityContextAsyncTaskExecutor(delegate);}

通过这样做,Spring将使用当前SecurityContext.在每个@Async调用。

现在,让我们再次运行应用程序,并查看日志记录信息以确保该情况:

Web  -  2016-12-30 22:45:18,013 [http-nio-8081-exec-3]信息o.ba金宝搏188体育eldung.web.service.asyncservice  -  @async逻辑外 - 在异步呼叫之前:[电子邮件受保护]:用户名:暂时的;...网页 -  2016-12-30 22:45:18,018 [http-nio-8081-exec-3]信息o.baeld金宝搏188体育ung.web.service.asyncservice  -  @async逻辑 - 在异步呼叫之后:[电子邮件受保护]:用户名:暂时的;...[simpleasyncctaskexecuter -1] INFO o.baeldung.web.service.AsyncSe金宝搏188体育rvice -内部@Async逻辑:[电子邮件受保护]:用户名:暂时的;...

就像我们期望的那样,我们在异步执行器线程中看到了相同的主体。

6.用例

我们可能希望确保有一些有趣的用例SecurityContext.像这样传播:

  • 我们希望发出多个外部请求,这些请求可以并行运行,并且可能需要大量时间执行
  • 我们在本地有一些重要的处理,我们的外部请求可以与此并行执行
  • 其他则代表“开了就忘了”的情况,比如发送电子邮件

7.结论

在本快速教程中,我们介绍了使用propagated发送异步请求的Spring支持SecurityContext。从编程模型的角度来看,新功能看起来很简单。

请注意,如果多个方法调用以前以同步方式链接在一起,那么转换为异步方法可能需要同步结果。

这个示例也可以作为Maven项目使用在Github

安全底部

我刚刚宣布了新消息学习春天安全课程,包括完整的材料集中在新的OAuth2堆栈在Spring Security 5:

>>看看这个课程
3.注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!