diff --git a/config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt b/config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt index f77dc2f27d..f8c5db5f45 100644 --- a/config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt @@ -235,13 +235,13 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl { * Specify that URLs are allowed by anyone. */ val permitAll: AuthorizationManager = - AuthorizationManager { _: Supplier, _: RequestAuthorizationContext -> AuthorizationDecision(true) } + AuthorizationManager { _: Supplier, _: RequestAuthorizationContext -> AuthorizationDecision(true) } /** * Specify that URLs are not allowed by anyone. */ val denyAll: AuthorizationManager = - AuthorizationManager { _: Supplier, _: RequestAuthorizationContext -> AuthorizationDecision(false) } + AuthorizationManager { _: Supplier, _: RequestAuthorizationContext -> AuthorizationDecision(false) } /** * Specify that URLs are allowed by any authenticated user. diff --git a/config/src/test/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDslTests.kt index e014a29c8a..249ea5a991 100644 --- a/config/src/test/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDslTests.kt @@ -193,7 +193,7 @@ class AuthorizeHttpRequestsDslTests { open class MvcMatcherPathVariablesConfig { @Bean open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { - val access = AuthorizationManager { _: Supplier, context: RequestAuthorizationContext -> + val access = AuthorizationManager { _: Supplier, context: RequestAuthorizationContext -> AuthorizationDecision(context.variables["userName"] == "user") } http { diff --git a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java index e710d9442c..2c84bf6e91 100644 --- a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java @@ -70,7 +70,7 @@ public abstract class AbstractSecurityExpressionHandler * suitable root object. */ @Override - public final EvaluationContext createEvaluationContext(Authentication authentication, T invocation) { + public final EvaluationContext createEvaluationContext(@Nullable Authentication authentication, T invocation) { SecurityExpressionOperations root = createSecurityExpressionRoot(authentication, invocation); StandardEvaluationContext ctx = createEvaluationContextInternal(authentication, invocation); if (this.beanResolver != null) { @@ -91,7 +91,8 @@ public abstract class AbstractSecurityExpressionHandler * @return A {@code StandardEvaluationContext} or potentially a custom subclass if * overridden. */ - protected StandardEvaluationContext createEvaluationContextInternal(Authentication authentication, T invocation) { + protected StandardEvaluationContext createEvaluationContextInternal(@Nullable Authentication authentication, + T invocation) { return new StandardEvaluationContext(); } @@ -102,8 +103,8 @@ public abstract class AbstractSecurityExpressionHandler * @param invocation the invocation (filter, method, channel) * @return the object */ - protected abstract SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, - T invocation); + protected abstract SecurityExpressionOperations createSecurityExpressionRoot( + @Nullable Authentication authentication, T invocation); protected @Nullable RoleHierarchy getRoleHierarchy() { return this.roleHierarchy; diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionHandler.java index 01a38c7b6b..981c947201 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionHandler.java @@ -18,6 +18,8 @@ package org.springframework.security.access.expression; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.aop.framework.AopInfrastructureBean; import org.springframework.expression.EvaluationContext; import org.springframework.expression.ExpressionParser; @@ -42,7 +44,7 @@ public interface SecurityExpressionHandler extends AopInfrastructureBean { * Provides an evaluation context in which to evaluate security expressions for the * invocation type. */ - EvaluationContext createEvaluationContext(Authentication authentication, T invocation); + EvaluationContext createEvaluationContext(@Nullable Authentication authentication, T invocation); /** * Provides an evaluation context in which to evaluate security expressions for the @@ -55,7 +57,7 @@ public interface SecurityExpressionHandler extends AopInfrastructureBean { * @return the {@link EvaluationContext} to use * @since 5.8 */ - default EvaluationContext createEvaluationContext(Supplier authentication, T invocation) { + default EvaluationContext createEvaluationContext(Supplier<@Nullable Authentication> authentication, T invocation) { return createEvaluationContext(authentication.get(), invocation); } diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java index c16faece85..483cdbee07 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java @@ -78,7 +78,7 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat * Creates a new instance * @param authentication the {@link Authentication} to use. Cannot be null. */ - public SecurityExpressionRoot(Authentication authentication) { + public SecurityExpressionRoot(@Nullable Authentication authentication) { this(() -> authentication); } @@ -89,7 +89,7 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat * Cannot be null. * @since 5.8 */ - public SecurityExpressionRoot(Supplier authentication) { + public SecurityExpressionRoot(Supplier<@Nullable Authentication> authentication) { this.authentication = SingletonSupplier.of(() -> { Authentication value = authentication.get(); Assert.notNull(value, "Authentication object cannot be null"); diff --git a/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java index 4450aae48d..1237aef743 100644 --- a/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java @@ -79,12 +79,14 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr * implementation. */ @Override - public StandardEvaluationContext createEvaluationContextInternal(Authentication auth, MethodInvocation mi) { + public StandardEvaluationContext createEvaluationContextInternal(@Nullable Authentication auth, + MethodInvocation mi) { return new MethodSecurityEvaluationContext(auth, mi, getParameterNameDiscoverer()); } @Override - public EvaluationContext createEvaluationContext(Supplier authentication, MethodInvocation mi) { + public EvaluationContext createEvaluationContext(Supplier<@Nullable Authentication> authentication, + MethodInvocation mi) { MethodSecurityExpressionOperations root = createSecurityExpressionRoot(authentication, mi); MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(root, mi, getParameterNameDiscoverer()); @@ -96,13 +98,13 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr * Creates the root object for expression evaluation. */ @Override - protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, + protected MethodSecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication, MethodInvocation invocation) { return createSecurityExpressionRoot(() -> authentication, invocation); } - private MethodSecurityExpressionOperations createSecurityExpressionRoot(Supplier authentication, - MethodInvocation invocation) { + private MethodSecurityExpressionOperations createSecurityExpressionRoot( + Supplier<@Nullable Authentication> authentication, MethodInvocation invocation) { MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication); root.setThis(invocation.getThis()); root.setPermissionEvaluator(getPermissionEvaluator()); diff --git a/core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRoot.java index 1aba5ba84f..70fe7824a7 100644 --- a/core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRoot.java @@ -38,11 +38,11 @@ class MethodSecurityExpressionRoot extends SecurityExpressionRoot implements Met private @Nullable Object target; - MethodSecurityExpressionRoot(Authentication a) { + MethodSecurityExpressionRoot(@Nullable Authentication a) { super(a); } - MethodSecurityExpressionRoot(Supplier authentication) { + MethodSecurityExpressionRoot(Supplier<@Nullable Authentication> authentication) { super(authentication); } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthenticatedAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthenticatedAuthorizationManager.java index 7114ade6c0..b1e96afcf7 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthenticatedAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthenticatedAuthorizationManager.java @@ -18,6 +18,8 @@ package org.springframework.security.authorization; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.core.Authentication; @@ -111,7 +113,7 @@ public final class AuthenticatedAuthorizationManager implements Authorization * @return an {@link AuthorizationDecision} */ @Override - public AuthorizationResult authorize(Supplier authentication, T object) { + public AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, T object) { boolean granted = this.authorizationStrategy.isGranted(authentication.get()); return new AuthorizationDecision(granted); } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthoritiesAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthoritiesAuthorizationManager.java index c70d67c332..346fce7494 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthoritiesAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthoritiesAuthorizationManager.java @@ -19,6 +19,8 @@ package org.springframework.security.authorization; import java.util.Collection; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.core.Authentication; @@ -55,7 +57,8 @@ public final class AuthoritiesAuthorizationManager implements AuthorizationManag * @return an {@link AuthorityAuthorizationDecision} */ @Override - public AuthorizationResult authorize(Supplier authentication, Collection authorities) { + public AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, + Collection authorities) { boolean granted = isGranted(authentication.get(), authorities); return new AuthorityAuthorizationDecision(granted, AuthorityUtils.createAuthorityList(authorities)); } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java index 754c07663f..7530019be6 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java @@ -19,6 +19,8 @@ package org.springframework.security.authorization; import java.util.Set; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.core.Authentication; @@ -137,7 +139,7 @@ public final class AuthorityAuthorizationManager implements AuthorizationMana * {@inheritDoc} */ @Override - public AuthorizationResult authorize(Supplier authentication, T object) { + public AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, T object) { return this.delegate.authorize(authentication, this.authorities); } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthorizationManager.java index de7523e614..3688bb7dbb 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorizationManager.java @@ -39,7 +39,7 @@ public interface AuthorizationManager { * @param object the {@link T} object to check * @throws AccessDeniedException if access is not granted */ - default void verify(Supplier authentication, T object) { + default void verify(Supplier<@Nullable Authentication> authentication, T object) { AuthorizationResult result = authorize(authentication, object); if (result != null && !result.isGranted()) { throw new AuthorizationDeniedException("Access Denied", result); @@ -54,6 +54,6 @@ public interface AuthorizationManager { * @return an {@link AuthorizationResult} * @since 6.4 */ - @Nullable AuthorizationResult authorize(Supplier authentication, T object); + @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, T object); } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorizationManagers.java b/core/src/main/java/org/springframework/security/authorization/AuthorizationManagers.java index a1808557ca..3723d0a64b 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorizationManagers.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorizationManagers.java @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.security.core.Authentication; /** @@ -58,7 +60,7 @@ public final class AuthorizationManagers { @SafeVarargs public static AuthorizationManager anyOf(AuthorizationDecision allAbstainDefaultDecision, AuthorizationManager... managers) { - return (AuthorizationManagerCheckAdapter) (authentication, object) -> { + return (AuthorizationManagerCheckAdapter) (Supplier<@Nullable Authentication> authentication, T object) -> { List results = new ArrayList<>(); for (AuthorizationManager manager : managers) { AuthorizationResult result = manager.authorize(authentication, object); @@ -104,7 +106,7 @@ public final class AuthorizationManagers { @SafeVarargs public static AuthorizationManager allOf(AuthorizationDecision allAbstainDefaultDecision, AuthorizationManager... managers) { - return (AuthorizationManagerCheckAdapter) (authentication, object) -> { + return (AuthorizationManagerCheckAdapter) (Supplier<@Nullable Authentication> authentication, T object) -> { List results = new ArrayList<>(); for (AuthorizationManager manager : managers) { AuthorizationResult result = manager.authorize(authentication, object); @@ -133,7 +135,7 @@ public final class AuthorizationManagers { * @since 6.3 */ public static AuthorizationManager not(AuthorizationManager manager) { - return (authentication, object) -> { + return (Supplier<@Nullable Authentication> authentication, T object) -> { AuthorizationResult result = manager.authorize(authentication, object); if (result == null) { return null; @@ -182,7 +184,7 @@ public final class AuthorizationManagers { private interface AuthorizationManagerCheckAdapter extends AuthorizationManager { @Override - AuthorizationResult authorize(Supplier authentication, T object); + AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, T object); } diff --git a/core/src/main/java/org/springframework/security/authorization/ObservationAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/ObservationAuthorizationManager.java index b890a55959..67dfaeb743 100644 --- a/core/src/main/java/org/springframework/security/authorization/ObservationAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/ObservationAuthorizationManager.java @@ -63,9 +63,9 @@ public final class ObservationAuthorizationManager } @Override - public @Nullable AuthorizationResult authorize(Supplier authentication, T object) { + public @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, T object) { AuthorizationObservationContext context = new AuthorizationObservationContext<>(object); - Supplier wrapped = () -> { + Supplier<@Nullable Authentication> wrapped = () -> { context.setAuthentication(authentication.get()); return context.getAuthentication(); }; diff --git a/core/src/main/java/org/springframework/security/authorization/SingleResultAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/SingleResultAuthorizationManager.java index 3fa55f3b2b..cc9ee0e5df 100644 --- a/core/src/main/java/org/springframework/security/authorization/SingleResultAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/SingleResultAuthorizationManager.java @@ -18,6 +18,8 @@ package org.springframework.security.authorization; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + import org.springframework.security.core.Authentication; import org.springframework.util.Assert; @@ -44,7 +46,7 @@ public final class SingleResultAuthorizationManager implements AuthorizationM } @Override - public AuthorizationResult authorize(Supplier authentication, C object) { + public AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, C object) { if (!(this.result instanceof AuthorizationDecision)) { throw new IllegalArgumentException("result should be AuthorizationDecision"); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java index ecabec4d04..4cdbed200d 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java @@ -83,7 +83,7 @@ public final class Jsr250AuthorizationManager implements AuthorizationManager authentication, + public @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, MethodInvocation methodInvocation) { AuthorizationManager delegate = this.registry.getManager(methodInvocation); return delegate.authorize(authentication, methodInvocation); @@ -104,8 +104,9 @@ public final class Jsr250AuthorizationManager implements AuthorizationManager Jsr250AuthorizationManager.this.authoritiesAuthorizationManager.authorize(a, - getAllowedRolesWithPrefix(rolesAllowed)); + return (Supplier<@Nullable Authentication> a, + MethodInvocation o) -> Jsr250AuthorizationManager.this.authoritiesAuthorizationManager + .authorize(a, getAllowedRolesWithPrefix(rolesAllowed)); } return NULL_MANAGER; } diff --git a/core/src/main/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManager.java index c5b4363088..18593a4994 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManager.java @@ -19,6 +19,7 @@ package org.springframework.security.authorization.method; import java.util.function.Supplier; import org.aopalliance.intercept.MethodInvocation; +import org.jspecify.annotations.Nullable; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; @@ -73,7 +74,7 @@ public final class MethodExpressionAuthorizationManager implements Authorization * expression */ @Override - public AuthorizationResult authorize(Supplier authentication, MethodInvocation context) { + public AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, MethodInvocation context) { EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, context); boolean granted = ExpressionUtils.evaluateAsBoolean(this.expression, ctx); return new ExpressionAuthorizationDecision(granted, this.expression); diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java index 4fc553335f..902d8f1d57 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java @@ -86,7 +86,8 @@ public final class PostAuthorizeAuthorizationManager * {@link PostAuthorize} annotation is not present */ @Override - public @Nullable AuthorizationResult authorize(Supplier authentication, MethodInvocationResult mi) { + public @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, + MethodInvocationResult mi) { ExpressionAttribute attribute = this.registry.getAttribute(mi.getMethodInvocation()); if (attribute == null) { return null; diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java index 800fbbbc63..a1a01908a7 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java @@ -78,7 +78,8 @@ public final class PreAuthorizeAuthorizationManager * {@link PreAuthorize} annotation is not present */ @Override - public @Nullable AuthorizationResult authorize(Supplier authentication, MethodInvocation mi) { + public @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, + MethodInvocation mi) { ExpressionAttribute attribute = this.registry.getAttribute(mi); if (attribute == null) { return null; diff --git a/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java index 7bc48bcf74..abff18ff16 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java @@ -68,7 +68,8 @@ public final class SecuredAuthorizationManager implements AuthorizationManager authentication, MethodInvocation mi) { + public @Nullable AuthorizationResult authorize(Supplier<@Nullable Authentication> authentication, + MethodInvocation mi) { Set authorities = getAuthorities(mi); return authorities.isEmpty() ? null : this.authoritiesAuthorizationManager.authorize(authentication, authorities);