Skip to content

Commit 2efebcf

Browse files
committed
Replace streams spring-projectsgh-7154
First version of replacing streams Fix wwwAuthenticate and codestyle Fix errors in implementation to pass tests
1 parent 09c98da commit 2efebcf

File tree

29 files changed

+295
-180
lines changed

29 files changed

+295
-180
lines changed

config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,11 @@
4343
import org.springframework.security.crypto.password.PasswordEncoder;
4444
import org.springframework.util.Assert;
4545

46-
import java.util.Arrays;
4746
import java.util.Collections;
4847
import java.util.List;
4948
import java.util.Map;
49+
import java.util.ArrayList;
5050
import java.util.concurrent.atomic.AtomicBoolean;
51-
import java.util.stream.Collectors;
5251

5352
/**
5453
* Exports the authentication {@link Configuration}
@@ -153,10 +152,7 @@ private <T> T lazyBean(Class<T> interfaceName) {
153152
}
154153
String beanName;
155154
if (beanNamesForType.length > 1) {
156-
List<String> primaryBeanNames = Arrays.stream(beanNamesForType)
157-
.filter(i -> applicationContext instanceof ConfigurableApplicationContext)
158-
.filter(n -> ((ConfigurableApplicationContext) applicationContext).getBeanFactory().getBeanDefinition(n).isPrimary())
159-
.collect(Collectors.toList());
155+
List<String> primaryBeanNames = getPrimaryBeanNames(beanNamesForType);
160156

161157
Assert.isTrue(primaryBeanNames.size() != 0, () -> "Found " + beanNamesForType.length
162158
+ " beans for type " + interfaceName + ", but none marked as primary");
@@ -175,6 +171,20 @@ private <T> T lazyBean(Class<T> interfaceName) {
175171
return (T) proxyFactory.getObject();
176172
}
177173

174+
private List<String> getPrimaryBeanNames(String[] beanNamesForType) {
175+
final List<String> list = new ArrayList<>();
176+
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
177+
return Collections.emptyList();
178+
}
179+
for (String beanName: beanNamesForType) {
180+
if (((ConfigurableApplicationContext) applicationContext).getBeanFactory()
181+
.getBeanDefinition(beanName).isPrimary()) {
182+
list.add(beanName);
183+
}
184+
}
185+
return list;
186+
}
187+
178188
private AuthenticationManager getAuthenticationManagerBean() {
179189
return lazyBean(AuthenticationManager.class);
180190
}

core/src/main/java/org/springframework/security/authorization/AuthorityReactiveAuthorizationManager.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import java.util.Arrays;
2424
import java.util.List;
25-
import java.util.stream.Stream;
2625

2726
/**
2827
* A {@link ReactiveAuthorizationManager} that determines if the current user is
@@ -109,9 +108,14 @@ public static <T> AuthorityReactiveAuthorizationManager<T> hasAnyRole(String...
109108
Assert.notNull(role, "role cannot be null");
110109
}
111110

112-
return hasAnyAuthority(Stream.of(roles)
113-
.map(r -> "ROLE_" + r)
114-
.toArray(String[]::new)
115-
);
111+
return hasAnyAuthority(toNamedRolesArray(roles));
112+
}
113+
114+
private static String[] toNamedRolesArray(String... roles) {
115+
String[] result = new String[roles.length];
116+
for (int i=0; i < roles.length; i++) {
117+
result[i] = "ROLE_" + roles[i];
118+
}
119+
return result;
116120
}
117121
}

core/src/main/java/org/springframework/security/converter/RsaKeyConverters.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,14 @@
1616

1717
package org.springframework.security.converter;
1818

19-
import java.io.BufferedReader;
20-
import java.io.InputStream;
21-
import java.io.InputStreamReader;
19+
import java.io.*;
2220
import java.security.KeyFactory;
2321
import java.security.NoSuchAlgorithmException;
2422
import java.security.interfaces.RSAPrivateKey;
2523
import java.security.interfaces.RSAPublicKey;
2624
import java.security.spec.PKCS8EncodedKeySpec;
2725
import java.security.spec.X509EncodedKeySpec;
28-
import java.util.Base64;
29-
import java.util.List;
26+
import java.util.*;
3027
import java.util.stream.Collectors;
3128

3229
import org.springframework.core.convert.converter.Converter;
@@ -66,10 +63,13 @@ public static Converter<InputStream, RSAPrivateKey> pkcs8() {
6663
Assert.isTrue(!lines.isEmpty() && lines.get(0).startsWith(PKCS8_PEM_HEADER),
6764
"Key is not in PEM-encoded PKCS#8 format, " +
6865
"please check that the header begins with -----" + PKCS8_PEM_HEADER + "-----");
69-
String base64Encoded = lines.stream()
70-
.filter(RsaKeyConverters::isNotPkcs8Wrapper)
71-
.collect(Collectors.joining());
72-
byte[] pkcs8 = Base64.getDecoder().decode(base64Encoded);
66+
StringBuilder base64Encoded = new StringBuilder();
67+
for (String line: lines) {
68+
if (RsaKeyConverters.isNotPkcs8Wrapper(line)) {
69+
base64Encoded.append(line);
70+
}
71+
}
72+
byte[] pkcs8 = Base64.getDecoder().decode(base64Encoded.toString());
7373

7474
try {
7575
return (RSAPrivateKey) keyFactory.generatePrivate(
@@ -97,10 +97,13 @@ public static Converter<InputStream, RSAPublicKey> x509() {
9797
Assert.isTrue(!lines.isEmpty() && lines.get(0).startsWith(X509_PEM_HEADER),
9898
"Key is not in PEM-encoded X.509 format, " +
9999
"please check that the header begins with -----" + X509_PEM_HEADER + "-----");
100-
String base64Encoded = lines.stream()
101-
.filter(RsaKeyConverters::isNotX509Wrapper)
102-
.collect(Collectors.joining());
103-
byte[] x509 = Base64.getDecoder().decode(base64Encoded);
100+
StringBuilder base64Encoded = new StringBuilder();
101+
for (String line: lines) {
102+
if (RsaKeyConverters.isNotX509Wrapper(line)) {
103+
base64Encoded.append(line);
104+
}
105+
}
106+
byte[] x509 = Base64.getDecoder().decode(base64Encoded.toString());
104107

105108
try {
106109
return (RSAPublicKey) keyFactory.generatePublic(

core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
import java.util.Arrays;
2020
import java.util.Collection;
2121
import java.util.Map;
22-
import java.util.function.Function;
23-
import java.util.stream.Collectors;
22+
import java.util.concurrent.ConcurrentHashMap;
2423

2524
import org.springframework.util.Assert;
2625
import reactor.core.publisher.Mono;
@@ -56,7 +55,11 @@ public MapReactiveUserDetailsService(UserDetails... users) {
5655
*/
5756
public MapReactiveUserDetailsService(Collection<UserDetails> users) {
5857
Assert.notEmpty(users, "users cannot be null or empty");
59-
this.users = users.stream().collect(Collectors.toConcurrentMap( u -> getKey(u.getUsername()), Function.identity()));
58+
final ConcurrentHashMap<String, UserDetails> map = new ConcurrentHashMap<>();
59+
for (UserDetails user: users) {
60+
map.put(user.getUsername(), user);
61+
}
62+
this.users = map;
6063
}
6164

6265
@Override

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/DelegatingOAuth2AuthorizedClientProvider.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Arrays;
2323
import java.util.Collections;
2424
import java.util.List;
25-
import java.util.Objects;
2625

2726
/**
2827
* An implementation of an {@link OAuth2AuthorizedClientProvider} that simply delegates
@@ -64,10 +63,17 @@ public DelegatingOAuth2AuthorizedClientProvider(List<OAuth2AuthorizedClientProvi
6463
@Nullable
6564
public OAuth2AuthorizedClient authorize(OAuth2AuthorizationContext context) {
6665
Assert.notNull(context, "context cannot be null");
67-
return this.authorizedClientProviders.stream()
68-
.map(authorizedClientProvider -> authorizedClientProvider.authorize(context))
69-
.filter(Objects::nonNull)
70-
.findFirst()
71-
.orElse(null);
66+
final List<OAuth2AuthorizedClient> clients = new ArrayList<>();
67+
for (OAuth2AuthorizedClientProvider authorizedClientProvider: authorizedClientProviders) {
68+
final OAuth2AuthorizedClient auth2AuthorizedClient = authorizedClientProvider.authorize(context);
69+
if (auth2AuthorizedClient != null) {
70+
clients.add(auth2AuthorizedClient);
71+
}
72+
}
73+
if (!clients.isEmpty()) {
74+
return clients.get(0);
75+
} else {
76+
return null;
77+
}
7278
}
7379
}

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientProviderBuilder.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@
2121
import org.springframework.util.Assert;
2222

2323
import java.time.Duration;
24-
import java.util.LinkedHashMap;
25-
import java.util.List;
26-
import java.util.Map;
24+
import java.util.*;
2725
import java.util.function.Consumer;
28-
import java.util.stream.Collectors;
2926

3027
/**
3128
* A builder that builds a {@link DelegatingOAuth2AuthorizedClientProvider} composed of
@@ -254,10 +251,10 @@ public OAuth2AuthorizedClientProvider build() {
254251
* @return the {@link DelegatingOAuth2AuthorizedClientProvider}
255252
*/
256253
public OAuth2AuthorizedClientProvider build() {
257-
List<OAuth2AuthorizedClientProvider> authorizedClientProviders =
258-
this.builders.values().stream()
259-
.map(Builder::build)
260-
.collect(Collectors.toList());
254+
List<OAuth2AuthorizedClientProvider> authorizedClientProviders = new ArrayList<>();
255+
for (Builder builder : this.builders.values()) {
256+
authorizedClientProviders.add(builder.build());
257+
}
261258
return new DelegatingOAuth2AuthorizedClientProvider(authorizedClientProviders);
262259
}
263260

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenValidator.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.HashMap;
3333
import java.util.List;
3434
import java.util.Map;
35-
import java.util.stream.Collectors;
3635

3736
/**
3837
* An {@link OAuth2TokenValidator} responsible for
@@ -137,9 +136,14 @@ public final void setClockSkew(Duration clockSkew) {
137136
}
138137

139138
private static OAuth2Error invalidIdToken(Map<String, Object> invalidClaims) {
140-
String claimsDetail = invalidClaims.entrySet().stream()
141-
.map(it -> it.getKey() + " (" + it.getValue() + ")")
142-
.collect(Collectors.joining(", "));
139+
final StringBuilder claimsDetail = new StringBuilder();
140+
int i = 0;
141+
for (Map.Entry<String, Object> entry : invalidClaims.entrySet()) {
142+
claimsDetail.append(entry.getKey()).append(" (").append(entry.getValue()).append(")");
143+
if (i != invalidClaims.size() - 1) {
144+
claimsDetail.append(", ");
145+
}
146+
}
143147
return new OAuth2Error("invalid_id_token",
144148
"The ID Token contains invalid claims: " + claimsDetail,
145149
"https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation");

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@
2222
import java.util.Iterator;
2323
import java.util.List;
2424
import java.util.Map;
25-
import java.util.concurrent.ConcurrentMap;
26-
import java.util.function.Function;
27-
import java.util.stream.Collector;
28-
29-
import static java.util.stream.Collectors.collectingAndThen;
30-
import static java.util.stream.Collectors.toConcurrentMap;
25+
import java.util.concurrent.ConcurrentHashMap;
3126

3227
/**
3328
* A {@link ClientRegistrationRepository} that stores {@link ClientRegistration}(s) in-memory.
@@ -62,9 +57,19 @@ public InMemoryClientRegistrationRepository(List<ClientRegistration> registratio
6257

6358
private static Map<String, ClientRegistration> createRegistrationsMap(List<ClientRegistration> registrations) {
6459
Assert.notEmpty(registrations, "registrations cannot be empty");
65-
Collector<ClientRegistration, ?, ConcurrentMap<String, ClientRegistration>> collector =
66-
toConcurrentMap(ClientRegistration::getRegistrationId, Function.identity());
67-
return registrations.stream().collect(collectingAndThen(collector, Collections::unmodifiableMap));
60+
return toUnmodifiableConcurrentMap(registrations);
61+
}
62+
63+
private static Map<String, ClientRegistration> toUnmodifiableConcurrentMap(List<ClientRegistration> registrations) {
64+
final ConcurrentHashMap<String, ClientRegistration> result = new ConcurrentHashMap<>();
65+
for (ClientRegistration registration : registrations) {
66+
if (result.containsKey(registration.getRegistrationId())) {
67+
throw new IllegalStateException(String.format("Duplicate key %s",
68+
registration.getRegistrationId()));
69+
}
70+
result.put(registration.getRegistrationId(), registration);
71+
}
72+
return Collections.unmodifiableMap(result);
6873
}
6974

7075
/**

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
import java.util.Iterator;
1919
import java.util.List;
2020
import java.util.Map;
21-
import java.util.function.Function;
22-
import java.util.stream.Collectors;
21+
import java.util.concurrent.ConcurrentHashMap;
2322

2423
import org.springframework.util.Assert;
2524
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -60,11 +59,9 @@ public InMemoryReactiveClientRegistrationRepository(ClientRegistration... regist
6059
*/
6160
public InMemoryReactiveClientRegistrationRepository(List<ClientRegistration> registrations) {
6261
Assert.notEmpty(registrations, "registrations cannot be null or empty");
63-
this.clientIdToClientRegistration = registrations.stream()
64-
.collect(Collectors.toConcurrentMap(ClientRegistration::getRegistrationId, Function.identity()));
62+
this.clientIdToClientRegistration = toConcurrentMap(registrations);
6563
}
6664

67-
6865
@Override
6966
public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
7067
return Mono.justOrEmpty(this.clientIdToClientRegistration.get(registrationId));
@@ -79,4 +76,12 @@ public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
7976
public Iterator<ClientRegistration> iterator() {
8077
return this.clientIdToClientRegistration.values().iterator();
8178
}
79+
80+
private ConcurrentHashMap<String, ClientRegistration> toConcurrentMap(List<ClientRegistration> registrations) {
81+
final ConcurrentHashMap<String, ClientRegistration> result = new ConcurrentHashMap<>();
82+
for (ClientRegistration registration : registrations) {
83+
result.put(registration.getRegistrationId(), registration);
84+
}
85+
return result;
86+
}
8287
}

oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/converter/ObjectToListStringConverter.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
import java.util.Collections;
2424
import java.util.LinkedHashSet;
2525
import java.util.List;
26-
import java.util.Objects;
2726
import java.util.Set;
28-
import java.util.stream.Collectors;
27+
import java.util.ArrayList;
2928

3029
/**
3130
* @author Joe Grandja
@@ -64,10 +63,13 @@ public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor t
6463
}
6564
}
6665
if (source instanceof Collection) {
67-
return ((Collection<?>) source).stream()
68-
.filter(Objects::nonNull)
69-
.map(Objects::toString)
70-
.collect(Collectors.toList());
66+
final Collection<String> results = new ArrayList<>();
67+
for (Object object : ((Collection<?>) source)) {
68+
if (object != null) {
69+
results.add(object.toString());
70+
}
71+
}
72+
return results;
7173
}
7274
return Collections.singletonList(source.toString());
7375
}

0 commit comments

Comments
 (0)