浏览代码

Configure CurrentSecurityContextArgumentResolver BeanResolver

Closes gh-9331
happier233 4 年之前
父节点
当前提交
873b9bdbca

+ 1 - 0
web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java

@@ -98,6 +98,7 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth
 			StandardEvaluationContext context = new StandardEvaluationContext();
 			context.setRootObject(securityContext);
 			context.setVariable("this", securityContext);
+			context.setBeanResolver(this.beanResolver);
 			Expression expression = this.parser.parseExpression(expressionToParse);
 			securityContextResult = expression.getValue(context);
 		}

+ 27 - 0
web/src/test/java/org/springframework/security/web/method/annotation/AuthenticationPrincipalArgumentResolverTests.java

@@ -21,12 +21,15 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.lang.reflect.Method;
+import java.util.function.Function;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
 import org.springframework.core.MethodParameter;
+import org.springframework.expression.AccessException;
+import org.springframework.expression.BeanResolver;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.security.core.authority.AuthorityUtils;
@@ -44,6 +47,13 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
  */
 public class AuthenticationPrincipalArgumentResolverTests {
 
+	private final BeanResolver beanResolver = ((context, beanName) -> {
+		if (!"test".equals(beanName)) {
+			throw new AccessException("Could not resolve bean reference against BeanFactory");
+		}
+		return (Function<CustomUserPrincipal, String>) (principal) -> principal.property;
+	});
+
 	private Object expectedPrincipal;
 
 	private AuthenticationPrincipalArgumentResolver resolver;
@@ -51,6 +61,7 @@ public class AuthenticationPrincipalArgumentResolverTests {
 	@Before
 	public void setup() {
 		this.resolver = new AuthenticationPrincipalArgumentResolver();
+		this.resolver.setBeanResolver(this.beanResolver);
 	}
 
 	@After
@@ -127,6 +138,14 @@ public class AuthenticationPrincipalArgumentResolverTests {
 		assertThat(this.resolver.resolveArgument(showUserSpel(), null, null, null)).isEqualTo(this.expectedPrincipal);
 	}
 
+	@Test
+	public void resolveArgumentSpelBean() throws Exception {
+		CustomUserPrincipal principal = new CustomUserPrincipal();
+		setAuthenticationPrincipal(principal);
+		this.expectedPrincipal = principal.property;
+		assertThat(this.resolver.resolveArgument(showUserSpelBean(), null, null, null)).isEqualTo(this.expectedPrincipal);
+	}
+
 	@Test
 	public void resolveArgumentSpelCopy() throws Exception {
 		CopyUserPrincipal principal = new CopyUserPrincipal("property");
@@ -195,6 +214,10 @@ public class AuthenticationPrincipalArgumentResolverTests {
 		return getMethodParameter("showUserSpel", String.class);
 	}
 
+	private MethodParameter showUserSpelBean() {
+		return getMethodParameter("showUserSpelBean", String.class);
+	}
+
 	private MethodParameter showUserSpelCopy() {
 		return getMethodParameter("showUserSpelCopy", CopyUserPrincipal.class);
 	}
@@ -258,6 +281,10 @@ public class AuthenticationPrincipalArgumentResolverTests {
 		public void showUserSpel(@AuthenticationPrincipal(expression = "property") String user) {
 		}
 
+		public void showUserSpelBean(@AuthenticationPrincipal(
+				expression = "@test.apply(#this)") String user) {
+		}
+
 		public void showUserSpelCopy(@AuthenticationPrincipal(
 				expression = "new org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolverTests$CopyUserPrincipal(#this)") CopyUserPrincipal user) {
 		}

+ 28 - 0
web/src/test/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolverTests.java

@@ -21,12 +21,15 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.lang.reflect.Method;
+import java.util.function.Function;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
 import org.springframework.core.MethodParameter;
+import org.springframework.expression.AccessException;
+import org.springframework.expression.BeanResolver;
 import org.springframework.expression.spel.SpelEvaluationException;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -47,11 +50,19 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
  */
 public class CurrentSecurityContextArgumentResolverTests {
 
+	private final BeanResolver beanResolver = ((context, beanName) -> {
+		if (!"test".equals(beanName)) {
+			throw new AccessException("Could not resolve bean reference against BeanFactory");
+		}
+		return (Function<SecurityContext, Authentication>) SecurityContext::getAuthentication;
+	});
+
 	private CurrentSecurityContextArgumentResolver resolver;
 
 	@Before
 	public void setup() {
 		this.resolver = new CurrentSecurityContextArgumentResolver();
+		this.resolver.setBeanResolver(this.beanResolver);
 	}
 
 	@After
@@ -106,6 +117,15 @@ public class CurrentSecurityContextArgumentResolverTests {
 		assertThat(auth1.getPrincipal()).isEqualTo(principal);
 	}
 
+	@Test
+	public void resolveArgumentWithAuthenticationWithBean() {
+		String principal = "john";
+		setAuthenticationPrincipal(principal);
+		Authentication auth1 = (Authentication) this.resolver
+				.resolveArgument(showSecurityContextAuthenticationWithBean(), null, null, null);
+		assertThat(auth1.getPrincipal()).isEqualTo(principal);
+	}
+
 	@Test
 	public void resolveArgumentWithNullAuthentication() {
 		SecurityContext context = SecurityContextHolder.getContext();
@@ -213,6 +233,10 @@ public class CurrentSecurityContextArgumentResolverTests {
 		return getMethodParameter("showSecurityContextAuthenticationAnnotation", Authentication.class);
 	}
 
+	public MethodParameter showSecurityContextAuthenticationWithBean() {
+		return getMethodParameter("showSecurityContextAuthenticationWithBean", Authentication.class);
+	}
+
 	private MethodParameter showSecurityContextAuthenticationWithOptionalPrincipal() {
 		return getMethodParameter("showSecurityContextAuthenticationWithOptionalPrincipal", Object.class);
 	}
@@ -294,6 +318,10 @@ public class CurrentSecurityContextArgumentResolverTests {
 				@CurrentSecurityContext(expression = "authentication") Authentication authentication) {
 		}
 
+		public void showSecurityContextAuthenticationWithBean(
+				@CurrentSecurityContext(expression = "@test.apply(#this)") Authentication authentication) {
+		}
+
 		public void showSecurityContextAuthenticationWithOptionalPrincipal(
 				@CurrentSecurityContext(expression = "authentication?.principal") Object principal) {
 		}