gpt4 book ai didi

java - Spring Security 子线程上下文

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:19:40 25 4
gpt4 key购买 nike

所以我正在使用 Spring Security 开发这个 Spring MVC 应用程序。在某些情况下,我的 Controller 响应时间太长,我一直遇到性能问题。这是由于一种处理方法可以根据某些用户输入处理大量数据。

现在,我一直在与我的团队一起围绕该处理方法对代码进行一些调整,我认为如果不对其进行切片并异步执行每个切片,我们就无法从中获得更好的性能。

问题是,当我尝试使用 java.util.concurrent 中的线程池将其切片并将工作分配给子线程时,我会在这些线程执行时收到有关安全上下文的错误消息。

这是堆栈跟踪的摘录:

Exception in thread "pool-1-thread-3" org.springframework.security.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)
at org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:63)
Exception in thread "pool-1-thread-4" at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy63.batchSaveCampaignpayment(Unknown Source)
at com.fim.pnp.controller.PaymentForm$1.run(PaymentForm.java:224)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
org.springframework.security.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)
at org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:63)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy63.batchSaveCampaignPayment(Unknown Source)
at com.fim.pnp.controller.PaymentForm$1.run(PaymentForm.java:224)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
Exception in thread "pool-1-thread-5" org.springframework.security.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)
at org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:63)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy63.batchSaveCampaignPayment(Unknown Source)
at com.fim.pnp.controller.PaymentForm$1.run(PaymentForm.java:224)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)

我知道从请求中生成线程不是好的做法...但我们此时已无​​计可施,根据我们的测量,每个工作线程所花的时间不应超过几秒钟。此外,预计该功能每周仅供 1 或 2 名专用用户使用一次。

有没有办法将 securityContext 传递给子线程或任何允许这些线程执行的类似方法?

谢谢

最佳答案

当我遇到类似问题时,我找到了两个解决方案:

解决方案 1将 SecurityContextHolder 的策略更改为 MODE_INHERITABLETHREADLOCAL

你可以这样做

<beans:bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<beans:property name="targetClass"
value="org.springframework.security.core.context.SecurityContextHolder"/>
<beans:property name="targetMethod" value="setStrategyName"/>
<beans:property name="arguments" value="MODE_INHERITABLETHREADLOCAL"/>
</beans:bean>

解决方案 2 使用 DelegatingSecurityContextRunnableDelegatingSecurityContextExecutorDelegatingSecurityContextExecutorSpring Concurrency Support Documentation 中详细描述了此解决方案

关于java - Spring Security 子线程上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1381965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com