在Grails 2中这不是问题,而且现在只出现在Grails 3中。任何调用异步任务的控制器都无法访问SecurityContextHolder以获取登录的用户信息,同时呈现视图....在Grails 3.2.6中,异步控制器操作失去对SecurityContextHolder的访问
看起来,在SecurityContextPersistenceFilter中,SecurityContextHolder.clearContext()被调用之前DispatcherServlet.processDispatchResult能够呈现,使渲染代码无法访问登录存储在SecurityContextHolder中的用户信息:
try {
SecurityContextHolder.setContext(contextBeforeChainExecution);
chain.doFilter(holder.getRequest(), holder.getResponse());
}
finally {
SecurityContext contextAfterChainExecution = SecurityContextHolder
.getContext();
// Crucial removal of SecurityContextHolder contents - do this before anything
// else.
SecurityContextHolder.clearContext();
repo.saveContext(contextAfterChainExecution, holder.getRequest(),
holder.getResponse());
request.removeAttribute(FILTER_APPLIED);
if (debug) {
logger.debug("SecurityContextHolder now cleared, as request processing completed");
}
}
在f我首先认为这个问题与安全上下文没有被传递给Promise的runnable(或者其他某些东西)有关,并且将springsecurity.sch.strategyName =“MODE_INHERITABLETHREADLOCAL”设置为无效。
下面是表示调试器的一些截图:
1)尚未执行这条线的DispatcherServlet。关注声明在图像的底部显示.getAuthentication = NULL返回true
2)之前SecurityContextHolder的在SecurityContextPersistenceFilter被清除出去!
3)从ha.handle,.getAuthentication回国后()现在是空
4)getAuthentication()现在呈现视图之前空/导致
为了澄清,我试图从正在呈现我的网页标题中布局中的自定义标签库中访问springSecurityService.currentUser。
所以,在layout.gsp类型的文件:
<header id="header" class="md-whiteframe-1dp">
<g:renderHeader/></header>
与renderHeader定义,如:
def renderHeader = { attrs, body ->
SecUser currentUser = (SecUser) accountService.activeUser
log.info("About to render header, session.id=" + session.id +
(currentUser?.userLogLabel ?: " user=not_logged_in"))
out << render(template: "/header", model: [currentUser : currentUser])
}
我开始觉得有东西的时候的sitemesh正在执行办和异步涉及的是的sitemesh已经失去了手柄上SecurityContextHolder中.... –