Browse Source

Add native hints for basic @PostAuthorize usage

Closes gh-11737
Marcus Da Coregio 3 years ago
parent
commit
38c05ad31c

+ 10 - 0
core/src/main/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHints.java

@@ -25,6 +25,7 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar;
 import org.springframework.aot.hint.TypeReference;
 import org.springframework.aot.hint.TypeReference;
 import org.springframework.security.access.expression.SecurityExpressionOperations;
 import org.springframework.security.access.expression.SecurityExpressionOperations;
 import org.springframework.security.access.expression.SecurityExpressionRoot;
 import org.springframework.security.access.expression.SecurityExpressionRoot;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.AccountExpiredException;
 import org.springframework.security.authentication.AccountExpiredException;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -54,9 +55,18 @@ class CoreSecurityRuntimeHints implements RuntimeHintsRegistrar {
 	public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
 	public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
 		registerExceptionEventsHints(hints);
 		registerExceptionEventsHints(hints);
 		registerExpressionEvaluationHints(hints);
 		registerExpressionEvaluationHints(hints);
+		registerMethodSecurityHints(hints);
 		hints.resources().registerResourceBundle("org.springframework.security.messages");
 		hints.resources().registerResourceBundle("org.springframework.security.messages");
 	}
 	}
 
 
+	private void registerMethodSecurityHints(RuntimeHints hints) {
+		hints.reflection().registerType(
+				TypeReference.of("org.springframework.security.access.expression.method.MethodSecurityExpressionRoot"),
+				(builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
+		hints.reflection().registerType(AbstractAuthenticationToken.class,
+				(builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
+	}
+
 	private void registerExpressionEvaluationHints(RuntimeHints hints) {
 	private void registerExpressionEvaluationHints(RuntimeHints hints) {
 		hints.reflection().registerTypes(
 		hints.reflection().registerTypes(
 				List.of(TypeReference.of(SecurityExpressionOperations.class),
 				List.of(TypeReference.of(SecurityExpressionOperations.class),

+ 16 - 0
core/src/test/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHintsTests.java

@@ -26,10 +26,12 @@ import org.junit.jupiter.params.provider.MethodSource;
 import org.springframework.aot.hint.MemberCategory;
 import org.springframework.aot.hint.MemberCategory;
 import org.springframework.aot.hint.RuntimeHints;
 import org.springframework.aot.hint.RuntimeHints;
 import org.springframework.aot.hint.RuntimeHintsRegistrar;
 import org.springframework.aot.hint.RuntimeHintsRegistrar;
+import org.springframework.aot.hint.TypeReference;
 import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
 import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
 import org.springframework.core.io.support.SpringFactoriesLoader;
 import org.springframework.core.io.support.SpringFactoriesLoader;
 import org.springframework.security.access.expression.SecurityExpressionOperations;
 import org.springframework.security.access.expression.SecurityExpressionOperations;
 import org.springframework.security.access.expression.SecurityExpressionRoot;
 import org.springframework.security.access.expression.SecurityExpressionRoot;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.AccountExpiredException;
 import org.springframework.security.authentication.AccountExpiredException;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -94,6 +96,20 @@ class CoreSecurityRuntimeHintsTests {
 				.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints);
 				.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints);
 	}
 	}
 
 
+	@Test
+	void methodSecurityExpressionRootHasHints() {
+		assertThat(RuntimeHintsPredicates.reflection()
+				.onType(TypeReference
+						.of("org.springframework.security.access.expression.method.MethodSecurityExpressionRoot"))
+				.withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS)).accepts(this.hints);
+	}
+
+	@Test
+	void abstractAuthenticationTokenHasHints() {
+		assertThat(RuntimeHintsPredicates.reflection().onType(AbstractAuthenticationToken.class)
+				.withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS)).accepts(this.hints);
+	}
+
 	private static Stream<Class<? extends AbstractAuthenticationEvent>> getAuthenticationEvents() {
 	private static Stream<Class<? extends AbstractAuthenticationEvent>> getAuthenticationEvents() {
 		return Stream.of(AuthenticationFailureBadCredentialsEvent.class,
 		return Stream.of(AuthenticationFailureBadCredentialsEvent.class,
 				AuthenticationFailureCredentialsExpiredEvent.class, AuthenticationFailureDisabledEvent.class,
 				AuthenticationFailureCredentialsExpiredEvent.class, AuthenticationFailureDisabledEvent.class,