Also arbeite ich an dieser Spring MVC-Anwendung mit Spring Security. Ich habe ein Leistungsproblem in einigen Fällen, wo mein Controller viel zu lange dauert, um zu reagieren. Dies ist auf eine Verarbeitungsmethode zurückzuführen, die aufgrund von Benutzereingaben eine große Menge an Daten verarbeiten kann.Spring Security Child Thread Kontext
Jetzt habe ich den Code ein wenig in und um diese Verarbeitungsmethode mit meinem Team optimiert und ich denke nicht, dass wir viel bessere Leistung daraus bekommen können, ohne es zu schneiden und jede Scheibe asynchron auszuführen.
Das Problem ist, wenn ich versuche, es zu zerlegen und die Arbeit an untergeordnete Threads zu verteilen, mit einem Threadpool von java.util.concurrent, bekomme ich Fehlermeldungen über den Sicherheitskontext, wenn diese ausgeführt werden. Hier
ist ein Extrakt aus der Stacktrace:
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)
Ich weiß es nicht gute Praxis ist Fäden von einer Anfrage zum Laichen ... aber wir haben an dieser Stelle der Ideen laufen und jeder Arbeitsthread shouldn Nach unseren Messungen brauchen wir nicht mehr als eine Handvoll Sekunden. Es wird auch erwartet, dass diese Funktion nur einmal pro Woche von 1 oder 2 dedizierten Benutzern verwendet wird.
Gibt es eine Möglichkeit, den securityContext an die untergeordneten Threads oder ähnliches zu übergeben, damit diese Threads ausgeführt werden können?
Dank
gut beschrieben. Wenn Sie einen 'TaskExecutor' verwenden, können Sie ihn in einen 'DelegatingSecurityContextTaskExecutor' einfügen, der sich um all das kümmert. All dies ist im [Referenzhandbuch] (https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#concurrency) erläutert. –