春季安全和@Async [英] Spring Security and @Async

查看:232
本文介绍了春季安全和@Async的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我异步调用方法与Spring,使用@ Async.This方法调用与@ preAuthorize,Spring Security的注解另一种方法。为了使授权的作品我必须设置 SecurityContextHolder中模式 MODE_INHERITABLETHREADLOCAL ,使身份验证信息传递到异步调用。一切工作正常为止。

I asynchronously invoke method with Spring, using @Async.This method invokes other method annotated with @PreAuthorize, Spring Security Annotation. To make authorization works I have to set SecurityContextHolder mode to MODE_INHERITABLETHREADLOCAL, so that authentication info is passed to the asynchronous call. Everything works fine so far.

Hovewer当我注销并登录为不同的用户,在老用户的异步方法SecurityContextHolder里店鉴别信息,有蜂注销。它会导致不必要的五言存取遭拒例外。没有与同步调用没有这样的问题。

Hovewer when I logout and login as a different user, in asynchronous method SecurityContextHolder stores authentication info of the old user, that has bee logged out. It causes of cource unwanted AccessDenied exception. There is no such problem with synchronous calls.

我已经定义了<任务:执行者ID =执行人池大小=10/> ,所以可能不会是一次线程中存在的问题遗嘱执行人池已被初始化,则无法覆盖认证信息?

I have defined <task:executor id="executors" pool-size="10"/>, so may it be a problem that once thread in executors pool has been initialized it will not override authentication information?

提前感谢帮助!

干杯,
卢卡斯

Cheers, Lukasz

推荐答案

我猜 MODE_INHERITABLETHREADLOCAL 不与线程池正常工作。

I guess MODE_INHERITABLETHREADLOCAL doesn't work correctly with thread pool.

作为一个可能的解决方案,你可以尝试继承<一个href=\"http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html\"><$c$c>ThreadPoolTaskExecutor并覆盖其方法传递 SecurityContext的手动,然后宣布遗嘱执行人,而不是&LT;任务:执行者&GT; 的东西像这样的:

As a possible solution you can try to subclass ThreadPoolTaskExecutor and override its methods to propagate SecurityContext manually, and then declare that executor instead of <task:executor>, something like this:

public void execute(final Runnable r) {
    final Authentication a = SecurityContextHolder.getContext().getAuthentication();

    super.execute(new Runnable() {
        public void run() {
            try {
                SecurityContext ctx = SecurityContextHolder.createEmptyContext();
                ctx.setAuthentication(a);
                SecurityContextHolder.setContext(ctx);
                r.run();
            } finally {
                SecurityContextHolder.clearContext();
            }
        }
    });
}

这篇关于春季安全和@Async的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆