Skip to content

Commit 1e14718

Browse files
committed
2 parents 6c630bf + 5da2121 commit 1e14718

File tree

93 files changed

+4495
-216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+4495
-216
lines changed

cas/src/main/java/org/springframework/security/cas/authentication/CasAuthenticationToken.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collection;
2121

2222
import org.apereo.cas.client.validation.Assertion;
23+
import org.jspecify.annotations.Nullable;
2324

2425
import org.springframework.security.authentication.AbstractAuthenticationToken;
2526
import org.springframework.security.core.GrantedAuthority;
@@ -104,6 +105,19 @@ private CasAuthenticationToken(final Integer keyHash, final Object principal, fi
104105
setAuthenticated(true);
105106
}
106107

108+
protected CasAuthenticationToken(Builder<?> builder) {
109+
super(builder);
110+
Assert.isTrue(!"".equals(builder.principal), "principal cannot be null or empty");
111+
Assert.notNull(!"".equals(builder.credentials), "credentials cannot be null or empty");
112+
Assert.notNull(builder.userDetails, "userDetails cannot be null");
113+
Assert.notNull(builder.assertion, "assertion cannot be null");
114+
this.keyHash = builder.keyHash;
115+
this.principal = builder.principal;
116+
this.credentials = builder.credentials;
117+
this.userDetails = builder.userDetails;
118+
this.assertion = builder.assertion;
119+
}
120+
107121
private static Integer extractKeyHash(String key) {
108122
Assert.hasLength(key, "key cannot be null or empty");
109123
return key.hashCode();
@@ -153,6 +167,11 @@ public UserDetails getUserDetails() {
153167
return this.userDetails;
154168
}
155169

170+
@Override
171+
public Builder<?> toBuilder() {
172+
return new Builder<>(this);
173+
}
174+
156175
@Override
157176
public String toString() {
158177
StringBuilder sb = new StringBuilder();
@@ -162,4 +181,81 @@ public String toString() {
162181
return (sb.toString());
163182
}
164183

184+
/**
185+
* A builder of {@link CasAuthenticationToken} instances
186+
*
187+
* @since 7.0
188+
*/
189+
public static class Builder<B extends Builder<B>> extends AbstractAuthenticationBuilder<B> {
190+
191+
private Integer keyHash;
192+
193+
private Object principal;
194+
195+
private Object credentials;
196+
197+
private UserDetails userDetails;
198+
199+
private Assertion assertion;
200+
201+
protected Builder(CasAuthenticationToken token) {
202+
super(token);
203+
this.keyHash = token.keyHash;
204+
this.principal = token.principal;
205+
this.credentials = token.credentials;
206+
this.userDetails = token.userDetails;
207+
this.assertion = token.assertion;
208+
}
209+
210+
/**
211+
* Use this key
212+
* @param key the key to use
213+
* @return the {@link Builder} for further configurations
214+
*/
215+
public B key(String key) {
216+
this.keyHash = key.hashCode();
217+
return (B) this;
218+
}
219+
220+
@Override
221+
public B principal(@Nullable Object principal) {
222+
Assert.notNull(principal, "principal cannot be null");
223+
this.principal = principal;
224+
return (B) this;
225+
}
226+
227+
@Override
228+
public B credentials(@Nullable Object credentials) {
229+
Assert.notNull(credentials, "credentials cannot be null");
230+
this.credentials = credentials;
231+
return (B) this;
232+
}
233+
234+
/**
235+
* Use this {@link UserDetails}
236+
* @param userDetails the {@link UserDetails} to use
237+
* @return the {@link Builder} for further configurations
238+
*/
239+
public B userDetails(UserDetails userDetails) {
240+
this.userDetails = userDetails;
241+
return (B) this;
242+
}
243+
244+
/**
245+
* Use this {@link Assertion}
246+
* @param assertion the {@link Assertion} to use
247+
* @return the {@link Builder} for further configurations
248+
*/
249+
public B assertion(Assertion assertion) {
250+
this.assertion = assertion;
251+
return (B) this;
252+
}
253+
254+
@Override
255+
public CasAuthenticationToken build() {
256+
return new CasAuthenticationToken(this);
257+
}
258+
259+
}
260+
165261
}

cas/src/main/java/org/springframework/security/cas/authentication/CasServiceTicketAuthenticationToken.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public class CasServiceTicketAuthenticationToken extends AbstractAuthenticationT
5252
*
5353
*/
5454
public CasServiceTicketAuthenticationToken(String identifier, Object credentials) {
55-
super(null);
55+
super((Collection<? extends GrantedAuthority>) null);
5656
this.identifier = identifier;
5757
this.credentials = credentials;
5858
setAuthenticated(false);
@@ -75,6 +75,12 @@ public CasServiceTicketAuthenticationToken(String identifier, Object credentials
7575
super.setAuthenticated(true);
7676
}
7777

78+
protected CasServiceTicketAuthenticationToken(Builder<?> builder) {
79+
super(builder);
80+
this.identifier = builder.principal;
81+
this.credentials = builder.credentials;
82+
}
83+
7884
public static CasServiceTicketAuthenticationToken stateful(Object credentials) {
7985
return new CasServiceTicketAuthenticationToken(CAS_STATEFUL_IDENTIFIER, credentials);
8086
}
@@ -110,4 +116,46 @@ public void eraseCredentials() {
110116
this.credentials = null;
111117
}
112118

119+
public Builder<?> toBuilder() {
120+
return new Builder<>(this);
121+
}
122+
123+
/**
124+
* A builder of {@link CasServiceTicketAuthenticationToken} instances
125+
*
126+
* @since 7.0
127+
*/
128+
public static class Builder<B extends Builder<B>> extends AbstractAuthenticationBuilder<B> {
129+
130+
private String principal;
131+
132+
private @Nullable Object credentials;
133+
134+
protected Builder(CasServiceTicketAuthenticationToken token) {
135+
super(token);
136+
this.principal = token.identifier;
137+
this.credentials = token.credentials;
138+
}
139+
140+
@Override
141+
public B principal(@Nullable Object principal) {
142+
Assert.isInstanceOf(String.class, principal, "principal must be of type String");
143+
this.principal = (String) principal;
144+
return (B) this;
145+
}
146+
147+
@Override
148+
public B credentials(@Nullable Object credentials) {
149+
Assert.notNull(credentials, "credentials cannot be null");
150+
this.credentials = credentials;
151+
return (B) this;
152+
}
153+
154+
@Override
155+
public CasServiceTicketAuthenticationToken build() {
156+
return new CasServiceTicketAuthenticationToken(this);
157+
}
158+
159+
}
160+
113161
}

cas/src/test/java/org/springframework/security/cas/authentication/CasAuthenticationTokenTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Collections;
2020
import java.util.List;
21+
import java.util.Set;
2122

2223
import org.apereo.cas.client.validation.Assertion;
2324
import org.apereo.cas.client.validation.AssertionImpl;
@@ -26,6 +27,7 @@
2627
import org.springframework.security.core.GrantedAuthority;
2728
import org.springframework.security.core.authority.AuthorityUtils;
2829
import org.springframework.security.core.authority.SimpleGrantedAuthority;
30+
import org.springframework.security.core.userdetails.PasswordEncodedUser;
2931
import org.springframework.security.core.userdetails.User;
3032
import org.springframework.security.core.userdetails.UserDetails;
3133

@@ -155,4 +157,29 @@ public void testToString() {
155157
assertThat(result.lastIndexOf("Credentials (Service/Proxy Ticket):") != -1).isTrue();
156158
}
157159

160+
@Test
161+
public void toBuilderWhenApplyThenCopies() {
162+
Assertion assertionOne = new AssertionImpl("test");
163+
CasAuthenticationToken factorOne = new CasAuthenticationToken("key", "alice", "pass",
164+
AuthorityUtils.createAuthorityList("FACTOR_ONE"), PasswordEncodedUser.user(), assertionOne);
165+
Assertion assertionTwo = new AssertionImpl("test");
166+
CasAuthenticationToken factorTwo = new CasAuthenticationToken("yek", "bob", "ssap",
167+
AuthorityUtils.createAuthorityList("FACTOR_TWO"), PasswordEncodedUser.admin(), assertionTwo);
168+
CasAuthenticationToken authentication = factorOne.toBuilder()
169+
.authorities((a) -> a.addAll(factorTwo.getAuthorities()))
170+
.key("yek")
171+
.principal(factorTwo.getPrincipal())
172+
.credentials(factorTwo.getCredentials())
173+
.userDetails(factorTwo.getUserDetails())
174+
.assertion(factorTwo.getAssertion())
175+
.build();
176+
Set<String> authorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
177+
assertThat(authentication.getKeyHash()).isEqualTo(factorTwo.getKeyHash());
178+
assertThat(authentication.getPrincipal()).isEqualTo(factorTwo.getPrincipal());
179+
assertThat(authentication.getCredentials()).isEqualTo(factorTwo.getCredentials());
180+
assertThat(authentication.getUserDetails()).isEqualTo(factorTwo.getUserDetails());
181+
assertThat(authentication.getAssertion()).isEqualTo(factorTwo.getAssertion());
182+
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
183+
}
184+
158185
}

config/src/integration-test/java/org/springframework/security/config/ldap/LdapBindAuthenticationManagerFactoryITests.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.security.config.ldap;
1818

1919
import java.util.Collection;
20-
import java.util.Collections;
2120
import java.util.HashSet;
2221
import java.util.Set;
2322

@@ -38,7 +37,6 @@
3837
import org.springframework.security.config.test.SpringTestContextExtension;
3938
import org.springframework.security.core.GrantedAuthority;
4039
import org.springframework.security.core.authority.AuthorityUtils;
41-
import org.springframework.security.core.authority.SimpleGrantedAuthority;
4240
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
4341
import org.springframework.security.core.userdetails.User;
4442
import org.springframework.security.core.userdetails.UserDetails;
@@ -82,8 +80,7 @@ protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, St
8280
this.spring.register(CustomAuthoritiesPopulatorConfig.class).autowire();
8381

8482
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
85-
.andExpect(
86-
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA"))));
83+
.andExpect(authenticated().withRoles("EXTRA"));
8784
}
8885

8986
@Test
@@ -94,8 +91,7 @@ public void authenticationManagerFactoryWhenCustomAuthoritiesMapperThenUsed() th
9491
this.spring.register(CustomAuthoritiesMapperConfig.class).autowire();
9592

9693
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
97-
.andExpect(
98-
authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_CUSTOM"))));
94+
.andExpect(authenticated().withRoles("CUSTOM"));
9995
}
10096

10197
@Test

config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.springframework.security.aot.hint.SecurityHintsRegistrar;
4040
import org.springframework.security.authorization.AuthorizationEventPublisher;
4141
import org.springframework.security.authorization.AuthorizationManager;
42+
import org.springframework.security.authorization.AuthorizationManagerFactory;
4243
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
4344
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
4445
import org.springframework.security.authorization.method.MethodInvocationResult;
@@ -121,6 +122,11 @@ void setRoleHierarchy(RoleHierarchy roleHierarchy) {
121122
this.expressionHandler.setRoleHierarchy(roleHierarchy);
122123
}
123124

125+
@Autowired(required = false)
126+
void setAuthorizationManagerFactory(AuthorizationManagerFactory<MethodInvocation> authorizationManagerFactory) {
127+
this.expressionHandler.setAuthorizationManagerFactory(authorizationManagerFactory);
128+
}
129+
124130
@Autowired(required = false)
125131
void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) {
126132
this.preFilterMethodInterceptor.setTemplateDefaults(templateDefaults);

0 commit comments

Comments
 (0)