Revert "Merge branch 'builder-enhancements'"
This reverts commit95644fb73c, reversing changes made tofbf7bb3be1. Reverting this commit will allow us more time to consider the ideal way to add this support to the public API.
This commit is contained in:
+1
-2
@@ -20,7 +20,6 @@ import java.util.Collection;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.BuildableAuthentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -33,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
* @author Ben Alex
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class RememberMeAuthenticationToken extends AbstractAuthenticationToken implements BuildableAuthentication {
|
||||
public class RememberMeAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 620L;
|
||||
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.BuildableAuthentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -35,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class TestingAuthenticationToken extends AbstractAuthenticationToken implements BuildableAuthentication {
|
||||
public class TestingAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
+1
-3
@@ -20,7 +20,6 @@ import java.util.Collection;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.BuildableAuthentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -36,8 +35,7 @@ import org.springframework.util.Assert;
|
||||
* @author Ben Alex
|
||||
* @author Norbert Nowak
|
||||
*/
|
||||
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken
|
||||
implements BuildableAuthentication {
|
||||
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 620L;
|
||||
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ import java.util.Collection;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.BuildableAuthentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -32,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
* @author Josh Cummings
|
||||
* @since 7.0
|
||||
*/
|
||||
public class OneTimeTokenAuthentication extends AbstractAuthenticationToken implements BuildableAuthentication {
|
||||
public class OneTimeTokenAuthentication extends AbstractAuthenticationToken {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1195893764725073959L;
|
||||
|
||||
@@ -19,9 +19,7 @@ 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;
|
||||
|
||||
@@ -140,37 +138,35 @@ public interface Authentication extends Principal, Serializable {
|
||||
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* A builder based on a given {@link BuildableAuthentication} instance
|
||||
* Return an {@link Builder} based on this instance. By default, returns a builder
|
||||
* that builds a {@link SimpleAuthentication}.
|
||||
* <p>
|
||||
* Although a {@code default} method, all {@link Authentication} implementations
|
||||
* should implement this. The reason is to ensure that the {@link Authentication} type
|
||||
* is preserved when {@link Builder#build} is invoked. This is especially important in
|
||||
* the event that your authentication implementation contains custom fields.
|
||||
* </p>
|
||||
* <p>
|
||||
* This isn't strictly necessary since it is recommended that applications code to the
|
||||
* {@link Authentication} interface and that custom information is often contained in
|
||||
* the {@link Authentication#getPrincipal} value.
|
||||
* </p>
|
||||
* @return an {@link Builder} for building a new {@link Authentication} based on this
|
||||
* instance
|
||||
* @since 7.0
|
||||
*/
|
||||
default Builder<?> toBuilder() {
|
||||
return new SimpleAuthentication.Builder(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder based on a given {@link Authentication} instance
|
||||
*
|
||||
* @author Josh Cummings
|
||||
* @since 7.0
|
||||
*/
|
||||
interface Builder<B extends Builder<B>> {
|
||||
|
||||
/**
|
||||
* Apply this authentication instance
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
* @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<String> newAuthorities = a.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
for (GrantedAuthority currentAuthority : authentication.getAuthorities()) {
|
||||
if (!newAuthorities.contains(currentAuthority.getAuthority())) {
|
||||
a.add(currentAuthority);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutate the authorities with this {@link Consumer}.
|
||||
* <p>
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.core;
|
||||
|
||||
/**
|
||||
* An {@link Authentication} that is also buildable.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
* @since 7.0
|
||||
*/
|
||||
public interface BuildableAuthentication extends Authentication {
|
||||
|
||||
/**
|
||||
* Return an {@link Builder} based on this instance.
|
||||
* <p>
|
||||
* Although a {@code default} method, all {@link BuildableAuthentication}
|
||||
* implementations should implement this. The reason is to ensure that the
|
||||
* {@link BuildableAuthentication} type is preserved when {@link Builder#build} is
|
||||
* invoked. This is especially important in the event that your authentication
|
||||
* implementation contains custom fields.
|
||||
* </p>
|
||||
* <p>
|
||||
* This isn't strictly necessary since it is recommended that applications code to the
|
||||
* {@link Authentication} interface and that custom information is often contained in
|
||||
* the {@link Authentication#getPrincipal} value.
|
||||
* </p>
|
||||
* @return an {@link Builder} for building a new {@link Authentication} based on this
|
||||
* instance
|
||||
*/
|
||||
Builder<?> toBuilder();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.core;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@Transient
|
||||
final class SimpleAuthentication implements Authentication {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 3194696462184782814L;
|
||||
|
||||
private final @Nullable Object principal;
|
||||
|
||||
private final @Nullable Object credentials;
|
||||
|
||||
private final Collection<GrantedAuthority> authorities;
|
||||
|
||||
private final @Nullable Object details;
|
||||
|
||||
private final boolean authenticated;
|
||||
|
||||
private SimpleAuthentication(Builder builder) {
|
||||
this.principal = builder.principal;
|
||||
this.credentials = builder.credentials;
|
||||
this.authorities = builder.authorities;
|
||||
this.details = builder.details;
|
||||
this.authenticated = builder.authenticated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object getCredentials() {
|
||||
return this.credentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object getDetails() {
|
||||
return this.details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object getPrincipal() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return this.authenticated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(
|
||||
"Instead of calling this setter, please call toBuilder to create a new instance");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return (this.principal == null) ? "" : this.principal.toString();
|
||||
}
|
||||
|
||||
static final class Builder implements Authentication.Builder<Builder> {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Collection<GrantedAuthority> authorities = new LinkedHashSet<>();
|
||||
|
||||
private @Nullable Object principal;
|
||||
|
||||
private @Nullable Object credentials;
|
||||
|
||||
private @Nullable Object details;
|
||||
|
||||
private boolean authenticated;
|
||||
|
||||
Builder(Authentication authentication) {
|
||||
this.logger.debug("Creating a builder which will result in exchanging an authentication of type "
|
||||
+ authentication.getClass() + " for " + SimpleAuthentication.class.getSimpleName() + ";"
|
||||
+ " consider implementing " + authentication.getClass().getSimpleName() + "#toBuilder");
|
||||
this.authorities.addAll(authentication.getAuthorities());
|
||||
this.principal = authentication.getPrincipal();
|
||||
this.credentials = authentication.getCredentials();
|
||||
this.details = authentication.getDetails();
|
||||
this.authenticated = authentication.isAuthenticated();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder authorities(Consumer<Collection<GrantedAuthority>> authorities) {
|
||||
authorities.accept(this.authorities);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder details(@Nullable Object details) {
|
||||
this.details = details;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder principal(@Nullable Object principal) {
|
||||
this.principal = principal;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder credentials(@Nullable Object credentials) {
|
||||
this.credentials = credentials;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder authenticated(boolean authenticated) {
|
||||
this.authenticated = authenticated;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication build() {
|
||||
return new SimpleAuthentication(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-10
@@ -37,16 +37,6 @@ class AbstractAuthenticationBuilderTests {
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
@Test
|
||||
void authenticationWhenAuthoritiesThenAdds() {
|
||||
TestingAuthenticationToken factorOne = new TestingAuthenticationToken("user", "pass", "FACTOR_ONE");
|
||||
TestingAuthenticationToken factorTwo = new TestingAuthenticationToken("user", "pass", "FACTOR_TWO");
|
||||
TestAbstractAuthenticationBuilder builder = new TestAbstractAuthenticationBuilder(factorOne);
|
||||
Authentication result = builder.authentication(factorTwo).build();
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(result.getAuthorities());
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
private static final class TestAbstractAuthenticationBuilder
|
||||
extends TestingAuthenticationToken.Builder<TestAbstractAuthenticationBuilder> {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user