Skip to content

Commit 812ac23

Browse files
Fix Session Security Runtime Hints always being registered
Splits the Security and Common Session hints in two different classes and only register security hints if SecurityContextImpl is present Issue spring-projectsgh-2104
1 parent cc4a15d commit 812ac23

File tree

5 files changed

+162
-76
lines changed

5 files changed

+162
-76
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2014-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.session.aot.hint;
18+
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.TreeSet;
22+
23+
import org.springframework.aot.hint.RuntimeHints;
24+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
25+
import org.springframework.aot.hint.TypeReference;
26+
27+
/**
28+
* A {@link RuntimeHintsRegistrar} for common session hints.
29+
*
30+
* @author Marcus Da Coregio
31+
*/
32+
class CommonSessionRuntimeHints implements RuntimeHintsRegistrar {
33+
34+
@Override
35+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
36+
Arrays.asList(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
37+
TypeReference.of(TreeSet.class), TypeReference.of(Number.class), TypeReference.of(Long.class),
38+
TypeReference.of(Integer.class), TypeReference.of(StackTraceElement.class),
39+
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
40+
TypeReference.of(RuntimeException.class),
41+
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
42+
TypeReference.of("java.util.Collections$UnmodifiableList"),
43+
TypeReference.of("java.util.Collections$EmptyList"),
44+
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
45+
TypeReference.of("java.util.Collections$UnmodifiableSet")).forEach(hints.serialization()::registerType);
46+
}
47+
48+
}

spring-session-core/src/main/java/org/springframework/session/aot/hint/CommonSessionSecurityRuntimeHints.java

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,11 @@
1616

1717
package org.springframework.session.aot.hint;
1818

19-
import java.util.ArrayList;
2019
import java.util.Arrays;
21-
import java.util.TreeSet;
2220

2321
import org.springframework.aot.hint.RuntimeHints;
2422
import org.springframework.aot.hint.RuntimeHintsRegistrar;
2523
import org.springframework.aot.hint.TypeReference;
26-
import org.springframework.security.authentication.AbstractAuthenticationToken;
27-
import org.springframework.security.authentication.AccountExpiredException;
28-
import org.springframework.security.authentication.AuthenticationServiceException;
29-
import org.springframework.security.authentication.BadCredentialsException;
30-
import org.springframework.security.authentication.CredentialsExpiredException;
31-
import org.springframework.security.authentication.DisabledException;
32-
import org.springframework.security.authentication.InsufficientAuthenticationException;
33-
import org.springframework.security.authentication.LockedException;
34-
import org.springframework.security.authentication.ProviderNotFoundException;
35-
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
36-
import org.springframework.security.core.AuthenticationException;
37-
import org.springframework.security.core.authority.SimpleGrantedAuthority;
38-
import org.springframework.security.core.context.SecurityContextImpl;
39-
import org.springframework.security.core.userdetails.User;
40-
import org.springframework.security.core.userdetails.UsernameNotFoundException;
4124

4225
/**
4326
* A {@link RuntimeHintsRegistrar} for common session security hints.
@@ -48,33 +31,34 @@ class CommonSessionSecurityRuntimeHints implements RuntimeHintsRegistrar {
4831

4932
@Override
5033
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
51-
Arrays.asList(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
52-
TypeReference.of(TreeSet.class), TypeReference.of(SecurityContextImpl.class),
53-
TypeReference.of(SimpleGrantedAuthority.class), TypeReference.of(User.class),
54-
TypeReference.of(Number.class), TypeReference.of(Long.class), TypeReference.of(Integer.class),
55-
TypeReference.of(AbstractAuthenticationToken.class),
56-
TypeReference.of(UsernamePasswordAuthenticationToken.class), TypeReference.of(StackTraceElement.class),
57-
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
58-
TypeReference.of(RuntimeException.class), TypeReference.of(AuthenticationException.class),
59-
TypeReference.of(BadCredentialsException.class), TypeReference.of(UsernameNotFoundException.class),
60-
TypeReference.of(AccountExpiredException.class), TypeReference.of(ProviderNotFoundException.class),
61-
TypeReference.of(DisabledException.class), TypeReference.of(LockedException.class),
62-
TypeReference.of(AuthenticationServiceException.class),
63-
TypeReference.of(CredentialsExpiredException.class),
64-
TypeReference.of(InsufficientAuthenticationException.class),
34+
registerSecurityHintsIfNeeded(hints);
35+
registerOAuth2ClientHintsIfNeeded(hints);
36+
registerOAuth2ResourceServerHintsIfNeeded(hints);
37+
}
38+
39+
private void registerSecurityHintsIfNeeded(RuntimeHints hints) {
40+
Arrays.asList(TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"),
41+
TypeReference.of("org.springframework.security.core.authority.SimpleGrantedAuthority"),
42+
TypeReference.of("org.springframework.security.core.userdetails.User"),
43+
TypeReference.of("org.springframework.security.authentication.AbstractAuthenticationToken"),
44+
TypeReference.of("org.springframework.security.authentication.UsernamePasswordAuthenticationToken"),
45+
TypeReference.of("org.springframework.security.core.AuthenticationException"),
46+
TypeReference.of("org.springframework.security.authentication.BadCredentialsException"),
47+
TypeReference.of("org.springframework.security.core.userdetails.UsernameNotFoundException"),
48+
TypeReference.of("org.springframework.security.authentication.AccountExpiredException"),
49+
TypeReference.of("org.springframework.security.authentication.ProviderNotFoundException"),
50+
TypeReference.of("org.springframework.security.authentication.DisabledException"),
51+
TypeReference.of("org.springframework.security.authentication.LockedException"),
52+
TypeReference.of("org.springframework.security.authentication.AuthenticationServiceException"),
53+
TypeReference.of("org.springframework.security.authentication.CredentialsExpiredException"),
54+
TypeReference.of("org.springframework.security.authentication.InsufficientAuthenticationException"),
6555
TypeReference
6656
.of("org.springframework.security.web.authentication.session.SessionAuthenticationException"),
6757
TypeReference.of(
6858
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException"),
69-
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
70-
TypeReference.of("java.util.Collections$UnmodifiableList"),
71-
TypeReference.of("java.util.Collections$EmptyList"),
72-
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
73-
TypeReference.of("java.util.Collections$UnmodifiableSet"),
7459
TypeReference.of("org.springframework.security.core.userdetails.User$AuthorityComparator"))
75-
.forEach(hints.serialization()::registerType);
76-
registerOAuth2ClientHintsIfNeeded(hints);
77-
registerOAuth2ResourceServerHintsIfNeeded(hints);
60+
.forEach((type) -> hints.serialization().registerType(type, (hint) -> hint.onReachableType(
61+
TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"))));
7862
}
7963

8064
private void registerOAuth2ResourceServerHintsIfNeeded(RuntimeHints hints) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
org.springframework.aot.hint.RuntimeHintsRegistrar=\
2+
org.springframework.session.aot.hint.CommonSessionRuntimeHints,\
23
org.springframework.session.aot.hint.CommonSessionSecurityRuntimeHints,\
34
org.springframework.session.aot.hint.servlet.HttpSessionSecurityRuntimeHints,\
45
org.springframework.session.aot.hint.server.WebSessionSecurityRuntimeHints
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2014-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.session.aot.hint;
18+
19+
import java.util.ArrayList;
20+
import java.util.TreeSet;
21+
import java.util.stream.Stream;
22+
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.MethodSource;
26+
27+
import org.springframework.aot.hint.RuntimeHints;
28+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
29+
import org.springframework.aot.hint.TypeReference;
30+
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
31+
import org.springframework.core.io.support.SpringFactoriesLoader;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
35+
/**
36+
* Tests for {@link CommonSessionRuntimeHints}
37+
*
38+
* @author Marcus Da Coregio
39+
*/
40+
class CommonSessionRuntimeHintsTests {
41+
42+
private final RuntimeHints hints = new RuntimeHints();
43+
44+
private final CommonSessionRuntimeHints commonSessionRuntimeHints = new CommonSessionRuntimeHints();
45+
46+
@ParameterizedTest
47+
@MethodSource("getSerializationHintTypes")
48+
void commonSessionTypesHasHints(TypeReference typeReference) {
49+
this.commonSessionRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
50+
assertThat(RuntimeHintsPredicates.serialization().onType(typeReference)).accepts(this.hints);
51+
}
52+
53+
@Test
54+
void aotFactoriesContainsRegistrar() {
55+
boolean match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
56+
.load(RuntimeHintsRegistrar.class).stream()
57+
.anyMatch((registrar) -> registrar instanceof CommonSessionRuntimeHints);
58+
assertThat(match).isTrue();
59+
}
60+
61+
private static Stream<TypeReference> getSerializationHintTypes() {
62+
return Stream.of(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
63+
TypeReference.of(TreeSet.class), TypeReference.of(Number.class), TypeReference.of(Long.class),
64+
TypeReference.of(Integer.class), TypeReference.of(StackTraceElement.class),
65+
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
66+
TypeReference.of(RuntimeException.class),
67+
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
68+
TypeReference.of("java.util.Collections$UnmodifiableList"),
69+
TypeReference.of("java.util.Collections$EmptyList"),
70+
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
71+
TypeReference.of("java.util.Collections$UnmodifiableSet"));
72+
}
73+
74+
}

spring-session-core/src/test/java/org/springframework/session/aot/hint/CommonSessionSecurityRuntimeHintsTests.java

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.session.aot.hint;
1818

19-
import java.util.ArrayList;
20-
import java.util.TreeSet;
2119
import java.util.stream.Stream;
2220

2321
import org.junit.jupiter.api.Test;
@@ -29,21 +27,6 @@
2927
import org.springframework.aot.hint.TypeReference;
3028
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
3129
import org.springframework.core.io.support.SpringFactoriesLoader;
32-
import org.springframework.security.authentication.AbstractAuthenticationToken;
33-
import org.springframework.security.authentication.AccountExpiredException;
34-
import org.springframework.security.authentication.AuthenticationServiceException;
35-
import org.springframework.security.authentication.BadCredentialsException;
36-
import org.springframework.security.authentication.CredentialsExpiredException;
37-
import org.springframework.security.authentication.DisabledException;
38-
import org.springframework.security.authentication.InsufficientAuthenticationException;
39-
import org.springframework.security.authentication.LockedException;
40-
import org.springframework.security.authentication.ProviderNotFoundException;
41-
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
42-
import org.springframework.security.core.AuthenticationException;
43-
import org.springframework.security.core.authority.SimpleGrantedAuthority;
44-
import org.springframework.security.core.context.SecurityContextImpl;
45-
import org.springframework.security.core.userdetails.User;
46-
import org.springframework.security.core.userdetails.UsernameNotFoundException;
4730

4831
import static org.assertj.core.api.Assertions.assertThat;
4932

@@ -60,7 +43,7 @@ class CommonSessionSecurityRuntimeHintsTests {
6043

6144
@ParameterizedTest
6245
@MethodSource("getSerializationHintTypes")
63-
void coreTypesHasHints(TypeReference typeReference) {
46+
void commonSecurityTypesHasHints(TypeReference typeReference) {
6447
this.commonSessionSecurityRuntimeHints.registerHints(this.hints, getClass().getClassLoader());
6548
assertThat(RuntimeHintsPredicates.serialization().onType(typeReference)).accepts(this.hints);
6649
}
@@ -74,29 +57,25 @@ void aotFactoriesContainsRegistrar() {
7457
}
7558

7659
private static Stream<TypeReference> getSerializationHintTypes() {
77-
return Stream.of(TypeReference.of(String.class), TypeReference.of(ArrayList.class),
78-
TypeReference.of(TreeSet.class), TypeReference.of(SecurityContextImpl.class),
79-
TypeReference.of(SimpleGrantedAuthority.class), TypeReference.of(User.class),
80-
TypeReference.of(Number.class), TypeReference.of(Long.class), TypeReference.of(Integer.class),
81-
TypeReference.of(AbstractAuthenticationToken.class),
82-
TypeReference.of(UsernamePasswordAuthenticationToken.class), TypeReference.of(StackTraceElement.class),
83-
TypeReference.of(Throwable.class), TypeReference.of(Exception.class),
84-
TypeReference.of(RuntimeException.class), TypeReference.of(AuthenticationException.class),
85-
TypeReference.of(BadCredentialsException.class), TypeReference.of(UsernameNotFoundException.class),
86-
TypeReference.of(AccountExpiredException.class), TypeReference.of(ProviderNotFoundException.class),
87-
TypeReference.of(DisabledException.class), TypeReference.of(LockedException.class),
88-
TypeReference.of(AuthenticationServiceException.class),
89-
TypeReference.of(CredentialsExpiredException.class),
90-
TypeReference.of(InsufficientAuthenticationException.class),
60+
return Stream.of(TypeReference.of("org.springframework.security.core.context.SecurityContextImpl"),
61+
TypeReference.of("org.springframework.security.core.authority.SimpleGrantedAuthority"),
62+
TypeReference.of("org.springframework.security.core.userdetails.User"),
63+
TypeReference.of("org.springframework.security.authentication.AbstractAuthenticationToken"),
64+
TypeReference.of("org.springframework.security.authentication.UsernamePasswordAuthenticationToken"),
65+
TypeReference.of("org.springframework.security.core.AuthenticationException"),
66+
TypeReference.of("org.springframework.security.authentication.BadCredentialsException"),
67+
TypeReference.of("org.springframework.security.core.userdetails.UsernameNotFoundException"),
68+
TypeReference.of("org.springframework.security.authentication.AccountExpiredException"),
69+
TypeReference.of("org.springframework.security.authentication.ProviderNotFoundException"),
70+
TypeReference.of("org.springframework.security.authentication.DisabledException"),
71+
TypeReference.of("org.springframework.security.authentication.LockedException"),
72+
TypeReference.of("org.springframework.security.authentication.AuthenticationServiceException"),
73+
TypeReference.of("org.springframework.security.authentication.CredentialsExpiredException"),
74+
TypeReference.of("org.springframework.security.authentication.InsufficientAuthenticationException"),
9175
TypeReference
9276
.of("org.springframework.security.web.authentication.session.SessionAuthenticationException"),
9377
TypeReference.of(
9478
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationException"),
95-
TypeReference.of("java.util.Collections$UnmodifiableCollection"),
96-
TypeReference.of("java.util.Collections$UnmodifiableList"),
97-
TypeReference.of("java.util.Collections$EmptyList"),
98-
TypeReference.of("java.util.Collections$UnmodifiableRandomAccessList"),
99-
TypeReference.of("java.util.Collections$UnmodifiableSet"),
10079
TypeReference.of("org.springframework.security.core.userdetails.User$AuthorityComparator"),
10180
TypeReference.of("org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken"),
10281
TypeReference.of(

0 commit comments

Comments
 (0)