Get user that runs an asynchronous method

前端 未结 3 2051
遥遥无期
遥遥无期 2021-01-17 18:11

I\'m trying to get the user from spring context in an application spring as follows:

Authentication auth = SecurityContextHolder.getContext().getAuthenticati         


        
相关标签:
3条回答
  • 2021-01-17 18:35

    Maybe this helps to get execute-method called (worked in my case):

    @Override
    @Bean(name = "asyncExecutor")
    public Executor getAsyncExecutor() {
    
        CustomThreadPoolTaskExecutor executor = new CustomThreadPoolTaskExecutor();
    
        executor.setMaxPoolSize(1);
        executor.setThreadGroupName("MyCustomExecutor");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setBeanName("asyncExecutor");
        executor.initialize();
    
        return new DelegatingSecurityContextAsyncTaskExecutor(executor);
    }
    
    0 讨论(0)
  • 2021-01-17 18:40

    Spring support for sending asynchronous requests with propagated SecurityContext. From a programming model perspective, the new capabilities appear deceptively simple. You can access to user info in async methods by setting security content strategy name in your security configurer class:

    @Configuration
    @EnableAsync
    public class SpringAsyncConfig implements AsyncConfigurer {
    
        public SpringAsyncConfig() {
            SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
        }
    
    }
    
    0 讨论(0)
  • 2021-01-17 18:40

    This is my implementation, I've used TaskDecorator to copy the SecurityContext in the new thread, the new thread runs with this new SecurityContext even the user logout during the execution of the async task.

    Xml declaration for executor

    <bean id="securityContextCopyingDecorator" class="com.myapp.task.SecurityContextCopyingDecorator"/>
    
    <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="1"/>
        <property name="maxPoolSize" value="5"/>
        <property name="queueCapacity" value="100"/> 
        <property name="taskDecorator" ref="securityContextCopyingDecorator"/>   
    </bean>
    
    <task:annotation-driven executor="threadPoolTaskExecutor"/>
    

    this is the class SecurityContextCopyingDecorator

    package com.myapp.task;
    
    import org.springframework.core.task.TaskDecorator;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;
    
    public class SecurityContextCopyingDecorator implements TaskDecorator {
    
        @Override
          public Runnable decorate(Runnable runnable) {
            final Authentication a = SecurityContextHolder.getContext().getAuthentication();
            return () -> {
              try {
                  SecurityContext ctx = SecurityContextHolder.createEmptyContext();
                  ctx.setAuthentication(a);
                  SecurityContextHolder.setContext(ctx);
                runnable.run();
              } finally {
                  SecurityContextHolder.clearContext();
              }
            };
          }
    
    
    }
    

    finally annotate some method to use threadPoolTaskExecutor in async mode

    @Async
    public void myAsyncMethod() {
    
    }
    
    0 讨论(0)
提交回复
热议问题