diff --git a/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java b/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java index 135066c618..18307f8b64 100644 --- a/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java +++ b/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java @@ -28,7 +28,6 @@ import org.jspecify.annotations.Nullable; import org.springframework.security.core.AuthenticatedPrincipal; import org.springframework.security.core.Authentication; -import org.springframework.security.core.BuildableAuthentication; import org.springframework.security.core.CredentialsContainer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; @@ -199,15 +198,15 @@ public abstract class AbstractAuthenticationToken implements Authentication, Cre } /** - * A common abstract implementation of {@link BuildableAuthentication.Builder}. It - * implements the builder methods that correspond to the {@link Authentication} - * methods that {@link AbstractAuthenticationToken} implements + * A common abstract implementation of {@link Authentication.Builder}. It implements + * the builder methods that correspond to the {@link Authentication} methods that + * {@link AbstractAuthenticationToken} implements * * @param * @since 7.0 */ protected abstract static class AbstractAuthenticationBuilder> - implements BuildableAuthentication.Builder { + implements Authentication.Builder { private boolean authenticated; diff --git a/core/src/main/java/org/springframework/security/core/Authentication.java b/core/src/main/java/org/springframework/security/core/Authentication.java index c8515b25fc..6439711beb 100644 --- a/core/src/main/java/org/springframework/security/core/Authentication.java +++ b/core/src/main/java/org/springframework/security/core/Authentication.java @@ -19,6 +19,9 @@ package org.springframework.security.core; import java.io.Serializable; import java.security.Principal; import java.util.Collection; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; @@ -136,4 +139,112 @@ public interface Authentication extends Principal, Serializable { */ void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException; + /** + * A builder based on a given {@link BuildableAuthentication} instance + * + * @author Josh Cummings + * @since 7.0 + */ + interface Builder> { + + /** + * Apply this authentication instance + *
+ * By default, merges the authorities in the provided {@code authentication} with + * the authentication being built. Only those authorities that haven't already + * been specified to the builder will be added. + *
+ * @param authentication the {@link Authentication} to appluy + * @return the {@link Builder} for additional configuration + * @see BuildableAuthentication#getAuthorities + */ + default B authentication(Authentication authentication) { + return authorities((a) -> { + Set+ * Note that since a non-empty set of authorities implies an + * {@link Authentication} is authenticated, this method also marks the + * authentication as {@link #authenticated} by default. + *
+ * @param authorities a consumer that receives the full set of authorities + * @return the {@link Builder} for additional configuration + * @see Authentication#getAuthorities + */ + B authorities(Consumer+ * Note that since some credentials are insecure to store, this method is + * implemented as unsupported by default. Only implement or use this method if you + * support secure storage of the credential or if your implementation also + * implements {@link CredentialsContainer} and the credentials are thereby erased. + *
+ * @param credentials the credentials to use + * @return the {@link Builder} for additional configuration + * @see Authentication#getCredentials + */ + default B credentials(@Nullable Object credentials) { + throw new UnsupportedOperationException( + String.format("%s does not store credentials", this.getClass().getSimpleName())); + } + + /** + * Use this details object. + *+ * Implementations may choose to use these {@code details} in combination with any + * principal from the pre-existing {@link Authentication} instance. + *
+ * @param details the details to use + * @return the {@link Builder} for additional configuration + * @see Authentication#getDetails + */ + B details(@Nullable Object details); + + /** + * Use this principal. + *+ * Note that in many cases, the principal is strongly-typed. Implementations may + * choose to do a type check and are not necessarily expected to allow any object + * as a principal. + *
+ *+ * Implementations may choose to use this {@code principal} in combination with + * any principal from the pre-existing {@link Authentication} instance. + *
+ * @param principal the principal to use + * @return the {@link Builder} for additional configuration + * @see Authentication#getPrincipal + */ + B principal(@Nullable Object principal); + + /** + * Mark this authentication as authenticated or not + * @param authenticated whether this is an authenticated {@link Authentication} + * instance + * @return the {@link Builder} for additional configuration + * @see Authentication#isAuthenticated + */ + B authenticated(boolean authenticated); + + /** + * Build an {@link Authentication} instance + * @return the {@link Authentication} instance + */ + Authentication build(); + + } + } diff --git a/core/src/main/java/org/springframework/security/core/BuildableAuthentication.java b/core/src/main/java/org/springframework/security/core/BuildableAuthentication.java index 577c6a9456..f49e9a5974 100644 --- a/core/src/main/java/org/springframework/security/core/BuildableAuthentication.java +++ b/core/src/main/java/org/springframework/security/core/BuildableAuthentication.java @@ -16,42 +16,11 @@ package org.springframework.security.core; -import java.util.Collection; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import org.jspecify.annotations.Nullable; - -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.context.SecurityContextHolder; - /** - * Represents the token for an authentication request or for an authenticated principal - * once the request has been processed by the - * {@link AuthenticationManager#authenticate(Authentication)} method. - *- * Once the request has been authenticated, the Authentication will usually be - * stored in a thread-local SecurityContext managed by the - * {@link SecurityContextHolder} by the authentication mechanism which is being used. An - * explicit authentication can be achieved, without using one of Spring Security's - * authentication mechanisms, by creating an Authentication instance and using - * the code: + * An {@link Authentication} that is also buildable. * - *
- * SecurityContext context = SecurityContextHolder.createEmptyContext(); - * context.setAuthentication(anAuthentication); - * SecurityContextHolder.setContext(context); - *- * - * Note that unless the Authentication has the authenticated property - * set to true, it will still be authenticated by any security interceptor (for - * method or web invocations) which encounters it. - *
- * In most cases, the framework transparently takes care of managing the security context - * and authentication objects for you. - * - * @author Ben Alex + * @author Josh Cummings + * @since 7.0 */ public interface BuildableAuthentication extends Authentication { @@ -69,118 +38,9 @@ public interface BuildableAuthentication extends Authentication { * {@link Authentication} interface and that custom information is often contained in * the {@link Authentication#getPrincipal} value. *
- * @return an {@link Builder} for building a new {@link BuildableAuthentication} based - * on this instance - * @since 7.0 + * @return an {@link Builder} for building a new {@link Authentication} based on this + * instance */ Builder> toBuilder(); - /** - * A builder based on a given {@link BuildableAuthentication} instance - * - * @author Josh Cummings - * @since 7.0 - */ - interface Builder> { - - /** - * Apply this authentication instance - *- * By default, merges the authorities in the provided {@code authentication} with - * the authentication being built. Only those authorities that haven't already - * been specified to the builder will be added. - *
- * @param authentication the {@link Authentication} to appluy - * @return the {@link Builder} for additional configuration - * @see BuildableAuthentication#getAuthorities - */ - default B authentication(Authentication authentication) { - return authorities((a) -> { - Set- * Note that since a non-empty set of authorities implies an - * {@link Authentication} is authenticated, this method also marks the - * authentication as {@link #authenticated} by default. - *
- * @param authorities a consumer that receives the full set of authorities - * @return the {@link Builder} for additional configuration - * @see Authentication#getAuthorities - */ - B authorities(Consumer- * Note that since some credentials are insecure to store, this method is - * implemented as unsupported by default. Only implement or use this method if you - * support secure storage of the credential or if your implementation also - * implements {@link CredentialsContainer} and the credentials are thereby erased. - *
- * @param credentials the credentials to use - * @return the {@link Builder} for additional configuration - * @see Authentication#getCredentials - */ - default B credentials(@Nullable Object credentials) { - throw new UnsupportedOperationException( - String.format("%s does not store credentials", this.getClass().getSimpleName())); - } - - /** - * Use this details object. - *- * Implementations may choose to use these {@code details} in combination with any - * principal from the pre-existing {@link Authentication} instance. - *
- * @param details the details to use - * @return the {@link Builder} for additional configuration - * @see Authentication#getDetails - */ - B details(@Nullable Object details); - - /** - * Use this principal. - *- * Note that in many cases, the principal is strongly-typed. Implementations may - * choose to do a type check and are not necessarily expected to allow any object - * as a principal. - *
- *- * Implementations may choose to use this {@code principal} in combination with - * any principal from the pre-existing {@link Authentication} instance. - *
- * @param principal the principal to use - * @return the {@link Builder} for additional configuration - * @see Authentication#getPrincipal - */ - B principal(@Nullable Object principal); - - /** - * Mark this authentication as authenticated or not - * @param authenticated whether this is an authenticated {@link Authentication} - * instance - * @return the {@link Builder} for additional configuration - * @see Authentication#isAuthenticated - */ - B authenticated(boolean authenticated); - - /** - * Build an {@link Authentication} instance - * @return the {@link Authentication} instance - */ - Authentication build(); - - } - }