Skip to content

Commit 5fb2875

Browse files
committed
AOT hints for authorization server Jackson 3 types should be registered
Closes gh-18146
1 parent 27ae318 commit 5fb2875

File tree

1 file changed

+146
-65
lines changed

1 file changed

+146
-65
lines changed

oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/aot/hint/OAuth2AuthorizationServerBeanRegistrationAotProcessor.java

Lines changed: 146 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3434
import org.springframework.security.core.authority.SimpleGrantedAuthority;
3535
import org.springframework.security.core.userdetails.User;
36+
import org.springframework.security.jackson.CoreJacksonModule;
3637
import org.springframework.security.jackson2.CoreJackson2Module;
3738
import org.springframework.security.oauth2.core.AbstractOAuth2Token;
3839
import org.springframework.security.oauth2.core.AuthorizationGrantType;
@@ -48,9 +49,11 @@
4849
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeActor;
4950
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeCompositeAuthenticationToken;
5051
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
52+
import org.springframework.security.oauth2.server.authorization.jackson.OAuth2AuthorizationServerJacksonModule;
5153
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
5254
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
5355
import org.springframework.security.web.authentication.WebAuthenticationDetails;
56+
import org.springframework.security.web.jackson.WebServletJacksonModule;
5457
import org.springframework.security.web.jackson2.WebServletJackson2Module;
5558
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
5659
import org.springframework.util.ClassUtils;
@@ -67,7 +70,18 @@
6770
*/
6871
class OAuth2AuthorizationServerBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
6972

70-
private boolean jackson2Contributed;
73+
private static final boolean jackson2Present;
74+
75+
private static final boolean jackson3Present;
76+
77+
static {
78+
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
79+
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader)
80+
&& ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
81+
jackson3Present = ClassUtils.isPresent("tools.jackson.databind.json.JsonMapper", classLoader);
82+
}
83+
84+
private boolean jacksonContributed;
7185

7286
@Override
7387
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
@@ -79,17 +93,17 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe
7993

8094
// @formatter:off
8195
if ((isJdbcBasedOAuth2AuthorizationService || isJdbcBasedRegisteredClientRepository)
82-
&& !this.jackson2Contributed) {
83-
Jackson2ConfigurationBeanRegistrationAotContribution jackson2Contribution =
84-
new Jackson2ConfigurationBeanRegistrationAotContribution();
85-
this.jackson2Contributed = true;
86-
return jackson2Contribution;
96+
&& !this.jacksonContributed) {
97+
JacksonConfigurationBeanRegistrationAotContribution jacksonContribution =
98+
new JacksonConfigurationBeanRegistrationAotContribution();
99+
this.jacksonContributed = true;
100+
return jacksonContribution;
87101
}
88102
// @formatter:on
89103
return null;
90104
}
91105

92-
private static class Jackson2ConfigurationBeanRegistrationAotContribution
106+
private static class JacksonConfigurationBeanRegistrationAotContribution
93107
implements BeanRegistrationAotContribution {
94108

95109
private final BindingReflectionHintsRegistrar reflectionHintsRegistrar = new BindingReflectionHintsRegistrar();
@@ -109,7 +123,6 @@ private void registerHints(RuntimeHints hints) {
109123
.registerType(HashSet.class, MemberCategory.DECLARED_FIELDS,
110124
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS);
111125

112-
// Spring Security and Spring Authorization Server
113126
hints.reflection()
114127
.registerTypes(Arrays.asList(TypeReference.of(AbstractAuthenticationToken.class),
115128
TypeReference.of(DefaultSavedRequest.Builder.class),
@@ -128,75 +141,143 @@ private void registerHints(RuntimeHints hints) {
128141
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
129142
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
130143

131-
// Jackson Modules - Spring Security and Spring Authorization Server
132-
hints.reflection()
133-
.registerTypes(
134-
Arrays.asList(TypeReference.of(CoreJackson2Module.class),
135-
TypeReference.of(WebServletJackson2Module.class),
136-
TypeReference.of(OAuth2AuthorizationServerJackson2Module.class)),
137-
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
138-
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
139-
140-
// Jackson Mixins - Spring Security and Spring Authorization Server
141-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
142-
loadClass("org.springframework.security.jackson2.UnmodifiableSetMixin"));
143-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
144-
loadClass("org.springframework.security.jackson2.UnmodifiableListMixin"));
145-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
146-
loadClass("org.springframework.security.jackson2.UnmodifiableMapMixin"));
147-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
148-
"org.springframework.security.oauth2.server.authorization.jackson2.UnmodifiableMapMixin"));
149-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
150-
loadClass("org.springframework.security.oauth2.server.authorization.jackson2.HashSetMixin"));
151-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
152-
loadClass("org.springframework.security.web.jackson2.DefaultSavedRequestMixin"));
153-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
154-
loadClass("org.springframework.security.web.jackson2.WebAuthenticationDetailsMixin"));
155-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
156-
loadClass("org.springframework.security.jackson2.UsernamePasswordAuthenticationTokenMixin"));
157-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
158-
loadClass("org.springframework.security.jackson2.UserMixin"));
159-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
160-
loadClass("org.springframework.security.jackson2.SimpleGrantedAuthorityMixin"));
161-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
162-
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenExchangeActorMixin"));
163-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
164-
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationRequestMixin"));
165-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
166-
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenExchangeCompositeAuthenticationTokenMixin"));
167-
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
168-
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenFormatMixin"));
169-
170-
// Check if Spring Security OAuth2 Client is on classpath
171-
if (ClassUtils.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration",
172-
ClassUtils.getDefaultClassLoader())) {
173-
174-
// Jackson Module (and required types) - Spring Security OAuth2 Client
144+
// Jackson Modules
145+
if (jackson2Present) {
175146
hints.reflection()
176-
.registerTypes(Arrays.asList(
177-
TypeReference
178-
.of("org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module"),
179-
TypeReference
180-
.of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken")),
147+
.registerTypes(
148+
Arrays.asList(TypeReference.of(CoreJackson2Module.class),
149+
TypeReference.of(WebServletJackson2Module.class),
150+
TypeReference.of(OAuth2AuthorizationServerJackson2Module.class)),
181151
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
182152
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
183153
MemberCategory.INVOKE_DECLARED_METHODS));
154+
}
155+
if (jackson3Present) {
156+
hints.reflection()
157+
.registerTypes(
158+
Arrays.asList(TypeReference.of(CoreJacksonModule.class),
159+
TypeReference.of(WebServletJacksonModule.class),
160+
TypeReference.of(OAuth2AuthorizationServerJacksonModule.class)),
161+
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
162+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
163+
MemberCategory.INVOKE_DECLARED_METHODS));
164+
}
184165

185-
// Jackson Mixins - Spring Security OAuth2 Client
166+
// Jackson Mixins
167+
if (jackson2Present) {
168+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
169+
loadClass("org.springframework.security.jackson2.UnmodifiableSetMixin"));
170+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
171+
loadClass("org.springframework.security.jackson2.UnmodifiableListMixin"));
172+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
173+
loadClass("org.springframework.security.jackson2.UnmodifiableMapMixin"));
186174
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
187-
"org.springframework.security.oauth2.client.jackson2.OAuth2AuthenticationTokenMixin"));
175+
"org.springframework.security.oauth2.server.authorization.jackson2.UnmodifiableMapMixin"));
188176
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
189-
loadClass("org.springframework.security.oauth2.client.jackson2.DefaultOidcUserMixin"));
177+
loadClass("org.springframework.security.oauth2.server.authorization.jackson2.HashSetMixin"));
190178
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
191-
loadClass("org.springframework.security.oauth2.client.jackson2.DefaultOAuth2UserMixin"));
179+
loadClass("org.springframework.security.web.jackson2.DefaultSavedRequestMixin"));
192180
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
193-
loadClass("org.springframework.security.oauth2.client.jackson2.OidcUserAuthorityMixin"));
181+
loadClass("org.springframework.security.web.jackson2.WebAuthenticationDetailsMixin"));
194182
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
195-
loadClass("org.springframework.security.oauth2.client.jackson2.OAuth2UserAuthorityMixin"));
183+
loadClass("org.springframework.security.jackson2.UsernamePasswordAuthenticationTokenMixin"));
196184
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
197-
loadClass("org.springframework.security.oauth2.client.jackson2.OidcIdTokenMixin"));
185+
loadClass("org.springframework.security.jackson2.UserMixin"));
198186
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
199-
loadClass("org.springframework.security.oauth2.client.jackson2.OidcUserInfoMixin"));
187+
loadClass("org.springframework.security.jackson2.SimpleGrantedAuthorityMixin"));
188+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
189+
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenExchangeActorMixin"));
190+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
191+
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationRequestMixin"));
192+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
193+
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenExchangeCompositeAuthenticationTokenMixin"));
194+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
195+
"org.springframework.security.oauth2.server.authorization.jackson2.OAuth2TokenFormatMixin"));
196+
}
197+
if (jackson3Present) {
198+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
199+
loadClass("org.springframework.security.web.jackson.DefaultSavedRequestMixin"));
200+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
201+
loadClass("org.springframework.security.web.jackson.WebAuthenticationDetailsMixin"));
202+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
203+
loadClass("org.springframework.security.jackson.UsernamePasswordAuthenticationTokenMixin"));
204+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
205+
loadClass("org.springframework.security.jackson.UserMixin"));
206+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
207+
loadClass("org.springframework.security.jackson.SimpleGrantedAuthorityMixin"));
208+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
209+
"org.springframework.security.oauth2.server.authorization.jackson.OAuth2TokenExchangeActorMixin"));
210+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
211+
"org.springframework.security.oauth2.server.authorization.jackson.OAuth2AuthorizationRequestMixin"));
212+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
213+
"org.springframework.security.oauth2.server.authorization.jackson.OAuth2TokenExchangeCompositeAuthenticationTokenMixin"));
214+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
215+
"org.springframework.security.oauth2.server.authorization.jackson.OAuth2TokenFormatMixin"));
216+
}
217+
218+
// Check if OAuth2 Client is on classpath
219+
if (ClassUtils.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration",
220+
ClassUtils.getDefaultClassLoader())) {
221+
222+
hints.reflection()
223+
.registerType(TypeReference
224+
.of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken"),
225+
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
226+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
227+
MemberCategory.INVOKE_DECLARED_METHODS));
228+
229+
// Jackson Module
230+
if (jackson2Present) {
231+
hints.reflection()
232+
.registerType(TypeReference
233+
.of("org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module"),
234+
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
235+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
236+
MemberCategory.INVOKE_DECLARED_METHODS));
237+
}
238+
if (jackson3Present) {
239+
hints.reflection()
240+
.registerType(
241+
TypeReference
242+
.of("org.springframework.security.oauth2.client.jackson.OAuth2ClientJacksonModule"),
243+
(builder) -> builder.withMembers(MemberCategory.DECLARED_FIELDS,
244+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
245+
MemberCategory.INVOKE_DECLARED_METHODS));
246+
}
247+
248+
// Jackson Mixins
249+
if (jackson2Present) {
250+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
251+
"org.springframework.security.oauth2.client.jackson2.OAuth2AuthenticationTokenMixin"));
252+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
253+
loadClass("org.springframework.security.oauth2.client.jackson2.DefaultOidcUserMixin"));
254+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
255+
loadClass("org.springframework.security.oauth2.client.jackson2.DefaultOAuth2UserMixin"));
256+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
257+
loadClass("org.springframework.security.oauth2.client.jackson2.OidcUserAuthorityMixin"));
258+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
259+
loadClass("org.springframework.security.oauth2.client.jackson2.OAuth2UserAuthorityMixin"));
260+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
261+
loadClass("org.springframework.security.oauth2.client.jackson2.OidcIdTokenMixin"));
262+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
263+
loadClass("org.springframework.security.oauth2.client.jackson2.OidcUserInfoMixin"));
264+
}
265+
if (jackson3Present) {
266+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(), loadClass(
267+
"org.springframework.security.oauth2.client.jackson.OAuth2AuthenticationTokenMixin"));
268+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
269+
loadClass("org.springframework.security.oauth2.client.jackson.DefaultOidcUserMixin"));
270+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
271+
loadClass("org.springframework.security.oauth2.client.jackson.DefaultOAuth2UserMixin"));
272+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
273+
loadClass("org.springframework.security.oauth2.client.jackson.OidcUserAuthorityMixin"));
274+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
275+
loadClass("org.springframework.security.oauth2.client.jackson.OAuth2UserAuthorityMixin"));
276+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
277+
loadClass("org.springframework.security.oauth2.client.jackson.OidcIdTokenMixin"));
278+
this.reflectionHintsRegistrar.registerReflectionHints(hints.reflection(),
279+
loadClass("org.springframework.security.oauth2.client.jackson.OidcUserInfoMixin"));
280+
}
200281
}
201282
}
202283

0 commit comments

Comments
 (0)