Prefer dispatcher context for authorize tag beans

Signed-off-by: wonderfulrosemari <whwlsgur1419@naver.com>
This commit is contained in:
wonderfulrosemari 2026-02-28 03:44:11 +09:00 committed by Josh Cummings
parent c000477c37
commit 846794d31b
2 changed files with 31 additions and 6 deletions

View File

@ -62,6 +62,8 @@ import org.springframework.util.StringUtils;
*/
public abstract class AbstractAuthorizeTag {
private static final String DISPATCHER_SERVLET_CONTEXT_ATTRIBUTE = "org.springframework.web.servlet.DispatcherServlet.CONTEXT";
@SuppressWarnings("NullAway.Init")
private @Nullable String access;
@ -184,8 +186,7 @@ public abstract class AbstractAuthorizeTag {
}
private SecurityContext getContext() {
ApplicationContext appContext = SecurityWebApplicationContextUtils
.findRequiredWebApplicationContext(getServletContext());
ApplicationContext appContext = getApplicationContext();
String[] names = appContext.getBeanNamesForType(SecurityContextHolderStrategy.class);
if (names.length == 1) {
SecurityContextHolderStrategy strategy = appContext.getBean(SecurityContextHolderStrategy.class);
@ -196,8 +197,7 @@ public abstract class AbstractAuthorizeTag {
@SuppressWarnings({ "unchecked", "rawtypes" })
private SecurityExpressionHandler<FilterInvocation> getExpressionHandler() throws IOException {
ApplicationContext appContext = SecurityWebApplicationContextUtils
.findRequiredWebApplicationContext(getServletContext());
ApplicationContext appContext = getApplicationContext();
Map<String, SecurityExpressionHandler> handlers = appContext.getBeansOfType(SecurityExpressionHandler.class);
for (SecurityExpressionHandler handler : handlers.values()) {
if (FilterInvocation.class
@ -215,8 +215,7 @@ public abstract class AbstractAuthorizeTag {
if (privEvaluatorFromRequest != null) {
return privEvaluatorFromRequest;
}
ApplicationContext ctx = SecurityWebApplicationContextUtils
.findRequiredWebApplicationContext(getServletContext());
ApplicationContext ctx = getApplicationContext();
Map<String, WebInvocationPrivilegeEvaluator> wipes = ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
if (wipes.isEmpty()) {
throw new IOException(
@ -226,4 +225,12 @@ public abstract class AbstractAuthorizeTag {
return (WebInvocationPrivilegeEvaluator) wipes.values().toArray()[0];
}
private ApplicationContext getApplicationContext() {
Object dispatcherContext = getRequest().getAttribute(DISPATCHER_SERVLET_CONTEXT_ATTRIBUTE);
if (dispatcherContext instanceof ApplicationContext applicationContext) {
return applicationContext;
}
return SecurityWebApplicationContextUtils.findRequiredWebApplicationContext(getServletContext());
}
}

View File

@ -134,6 +134,24 @@ public class AbstractAuthorizeTagTests {
assertThat(this.tag.authorize()).isTrue();
}
@Test
@SuppressWarnings("rawtypes")
public void expressionFromDispatcherContextWhenRootContextPresent() throws IOException {
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "pass", "USER"));
WebApplicationContext root = mock(WebApplicationContext.class);
given(root.getBeansOfType(SecurityExpressionHandler.class)).willReturn(Collections.emptyMap());
given(root.getBeanNamesForType(SecurityContextHolderStrategy.class)).willReturn(new String[0]);
this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, root);
DefaultWebSecurityExpressionHandler expected = new DefaultWebSecurityExpressionHandler();
WebApplicationContext dispatcher = mock(WebApplicationContext.class);
given(dispatcher.getBeansOfType(SecurityExpressionHandler.class))
.willReturn(Collections.<String, SecurityExpressionHandler>singletonMap("wipe", expected));
given(dispatcher.getBeanNamesForType(SecurityContextHolderStrategy.class)).willReturn(new String[0]);
this.request.setAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", dispatcher);
this.tag.setAccess("permitAll");
assertThat(this.tag.authorize()).isTrue();
}
private class AuthzTag extends AbstractAuthorizeTag {
@Override