Add Authentication.Builder
This commit adds a new default method to Authentication for the purposes of creating a Builder based on the current authentication, allowing other authentications to be applied to it as a composite. It also adds Builders for each one of the authentication result classes. Issue gh-17861
This commit is contained in:
+42
@@ -85,4 +85,46 @@ public class OAuth2AuthenticationToken extends AbstractAuthenticationToken {
|
||||
return this.authorizedClientRegistrationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new Builder().apply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder preserving the concrete {@link Authentication} type
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public static final class Builder extends AbstractAuthenticationBuilder<OAuth2AuthenticationToken, Builder> {
|
||||
|
||||
private OAuth2User principal;
|
||||
|
||||
private String authorizedClientRegistrationId;
|
||||
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder apply(OAuth2AuthenticationToken authentication) {
|
||||
return super.apply(authentication).principal(authentication.getPrincipal())
|
||||
.authorizedClientRegistrationId(authentication.authorizedClientRegistrationId);
|
||||
}
|
||||
|
||||
public Builder principal(OAuth2User principal) {
|
||||
this.principal = principal;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder authorizedClientRegistrationId(String authorizedClientRegistrationId) {
|
||||
this.authorizedClientRegistrationId = authorizedClientRegistrationId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2AuthenticationToken build(Collection<GrantedAuthority> authorities) {
|
||||
return new OAuth2AuthenticationToken(this.principal, authorities, this.authorizedClientRegistrationId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
@@ -18,12 +18,15 @@ package org.springframework.security.oauth2.client.authentication;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.security.oauth2.core.user.TestOAuth2Users;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
@@ -82,4 +85,17 @@ public class OAuth2AuthenticationTokenTests {
|
||||
assertThat(authentication.isAuthenticated()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenApplyThenCopies() {
|
||||
OAuth2AuthenticationToken factorOne = new OAuth2AuthenticationToken(TestOAuth2Users.create(),
|
||||
AuthorityUtils.createAuthorityList("FACTOR_ONE"), "alice");
|
||||
OAuth2AuthenticationToken factorTwo = new OAuth2AuthenticationToken(TestOAuth2Users.create(),
|
||||
AuthorityUtils.createAuthorityList("FACTOR_TWO"), "bob");
|
||||
OAuth2AuthenticationToken result = factorOne.toBuilder().apply(factorTwo).build();
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(result.getAuthorities());
|
||||
assertThat(result.getPrincipal()).isSameAs(factorTwo.getPrincipal());
|
||||
assertThat(result.getAuthorizedClientRegistrationId()).isSameAs(factorTwo.getAuthorizedClientRegistrationId());
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+43
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.Transient;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
@@ -61,4 +62,46 @@ public class BearerTokenAuthentication extends AbstractOAuth2TokenAuthentication
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new Builder().apply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder preserving the concrete {@link Authentication} type
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public static final class Builder extends AbstractAuthenticationBuilder<BearerTokenAuthentication, Builder> {
|
||||
|
||||
private OAuth2AuthenticatedPrincipal principal;
|
||||
|
||||
private OAuth2AccessToken token;
|
||||
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder apply(BearerTokenAuthentication authentication) {
|
||||
return super.apply(authentication).principal((OAuth2AuthenticatedPrincipal) authentication.getPrincipal())
|
||||
.credentials(authentication.getToken());
|
||||
}
|
||||
|
||||
public Builder principal(OAuth2AuthenticatedPrincipal principal) {
|
||||
this.principal = principal;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder credentials(OAuth2AccessToken credentials) {
|
||||
this.token = credentials;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BearerTokenAuthentication build(Collection<GrantedAuthority> authorities) {
|
||||
return new BearerTokenAuthentication(this.principal, this.token, authorities);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+42
@@ -19,6 +19,7 @@ package org.springframework.security.oauth2.server.resource.authentication;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.Transient;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
@@ -84,4 +85,45 @@ public class JwtAuthenticationToken extends AbstractOAuth2TokenAuthenticationTok
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new Builder().apply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder preserving the concrete {@link Authentication} type
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public static final class Builder extends AbstractAuthenticationBuilder<JwtAuthenticationToken, Builder> {
|
||||
|
||||
private Jwt jwt;
|
||||
|
||||
private String name;
|
||||
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder apply(JwtAuthenticationToken token) {
|
||||
return super.apply(token).jwt(token.getToken()).name(token.getName());
|
||||
}
|
||||
|
||||
public Builder jwt(Jwt jwt) {
|
||||
this.jwt = jwt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JwtAuthenticationToken build(Collection<GrantedAuthority> authorities) {
|
||||
return new JwtAuthenticationToken(this.jwt, authorities, this.name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
@@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -34,6 +35,7 @@ import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrinci
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames;
|
||||
import org.springframework.security.oauth2.core.TestOAuth2AuthenticatedPrincipals;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
@@ -151,4 +153,20 @@ public class BearerTokenAuthenticationTests {
|
||||
token.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenApplyThenCopies() {
|
||||
BearerTokenAuthentication factorOne = new BearerTokenAuthentication(TestOAuth2AuthenticatedPrincipals.active(),
|
||||
this.token, AuthorityUtils.createAuthorityList("FACTOR_ONE"));
|
||||
BearerTokenAuthentication factorTwo = new BearerTokenAuthentication(
|
||||
TestOAuth2AuthenticatedPrincipals.active((m) -> m.put("k", "v")),
|
||||
new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "nekot", Instant.now(),
|
||||
Instant.now().plusSeconds(3600)),
|
||||
AuthorityUtils.createAuthorityList("FACTOR_TWO"));
|
||||
BearerTokenAuthentication authentication = factorOne.toBuilder().apply(factorTwo).build();
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
|
||||
assertThat(authentication.getPrincipal()).isSameAs(factorTwo.getPrincipal());
|
||||
assertThat(authentication.getToken()).isSameAs(factorTwo.getToken());
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.oauth2.server.resource.authentication;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -115,6 +116,19 @@ public class JwtAuthenticationTokenTests {
|
||||
assertThat(new JwtAuthenticationToken(jwt).getName()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenApplyThenCopies() {
|
||||
JwtAuthenticationToken factorOne = new JwtAuthenticationToken(builder().claim("c", "v").build(),
|
||||
AuthorityUtils.createAuthorityList("FACTOR_ONE"), "alice");
|
||||
JwtAuthenticationToken factorTwo = new JwtAuthenticationToken(builder().claim("d", "w").build(),
|
||||
AuthorityUtils.createAuthorityList("FACTOR_TWO"), "bob");
|
||||
JwtAuthenticationToken result = factorOne.toBuilder().apply(factorTwo).build();
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(result.getAuthorities());
|
||||
assertThat(result.getPrincipal()).isSameAs(factorTwo.getPrincipal());
|
||||
assertThat(result.getName()).isSameAs(factorTwo.getName());
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
private Jwt.Builder builder() {
|
||||
return Jwt.withTokenValue("token").header("alg", JwsAlgorithms.RS256);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user