Skip to content

Commit 4c9a255

Browse files
committed
AOT contributions will be registered for JbcOAuth2AuthorizationService subclasses
Prior to this commit, String-based class name comparisons were used for determining if a bean was of type JdbcOAuth2AuthorizationService or JdbcRegisteredClientRepository. Now JdbcOAuth2AuthorizationService.class.isAssignableFrom(...) and JdbcRegisteredClientRepository.class.isAssignableFrom(...) is used so that any subclasses are detected and the necessary AOT hints are contributed. closes gh-1737
1 parent 3b52e15 commit 4c9a255

File tree

2 files changed

+118
-4
lines changed

2 files changed

+118
-4
lines changed

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

+10-4
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
4444
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
4545
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
46+
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
4647
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeActor;
4748
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenExchangeCompositeAuthenticationToken;
49+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
4850
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
4951
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
5052
import org.springframework.security.web.authentication.WebAuthenticationDetails;
@@ -67,11 +69,15 @@ class OAuth2AuthorizationServerBeanRegistrationAotProcessor implements BeanRegis
6769

6870
@Override
6971
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
70-
String beanClassName = registeredBean.getBeanClass().getName();
72+
boolean isJdbcBasedOAuth2AuthorizationService = JdbcOAuth2AuthorizationService.class
73+
.isAssignableFrom(registeredBean.getBeanClass());
74+
75+
boolean isJdbcBasedRegisteredClientRepository = JdbcRegisteredClientRepository.class
76+
.isAssignableFrom(registeredBean.getBeanClass());
77+
7178
// @formatter:off
72-
if ((beanClassName.equals("org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService") ||
73-
beanClassName.equals("org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository")) &&
74-
!this.jackson2Contributed) {
79+
if ((isJdbcBasedOAuth2AuthorizationService || isJdbcBasedRegisteredClientRepository)
80+
&& !this.jackson2Contributed) {
7581
Jackson2ConfigurationBeanRegistrationAotContribution jackson2Contribution =
7682
new Jackson2ConfigurationBeanRegistrationAotContribution();
7783
this.jackson2Contributed = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2020-2021 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+
package org.springframework.security.oauth2.server.authorization.aot.hint;
17+
18+
import org.junit.jupiter.api.BeforeEach;
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.params.ParameterizedTest;
21+
import org.junit.jupiter.params.provider.ValueSource;
22+
23+
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
24+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
25+
import org.springframework.beans.factory.support.RegisteredBean;
26+
import org.springframework.beans.factory.support.RootBeanDefinition;
27+
import org.springframework.jdbc.core.JdbcOperations;
28+
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
29+
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
30+
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
31+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
32+
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
33+
34+
import static org.assertj.core.api.Assertions.assertThat;
35+
36+
class OAuth2AuthorizationServerBeanRegistrationAotProcessorTests {
37+
38+
OAuth2AuthorizationServerBeanRegistrationAotProcessor processor;
39+
40+
DefaultListableBeanFactory defaultListableBeanFactory;
41+
42+
@BeforeEach
43+
void setUp() {
44+
this.processor = new OAuth2AuthorizationServerBeanRegistrationAotProcessor();
45+
this.defaultListableBeanFactory = new DefaultListableBeanFactory();
46+
47+
}
48+
49+
@ParameterizedTest
50+
@ValueSource(classes = { JdbcOAuth2AuthorizationService.class, CustomJdbcOAuth2AuthorizationService.class,
51+
JdbcRegisteredClientRepository.class, CustomJdbcRegisteredClientRepository.class })
52+
void whenABeanRegistrationAotContributionShouldBeReturned(Class<?> beanClass) {
53+
this.defaultListableBeanFactory.registerBeanDefinition("beanName", new RootBeanDefinition(beanClass));
54+
55+
BeanRegistrationAotContribution aotContribution = this.processor
56+
.processAheadOfTime(RegisteredBean.of(this.defaultListableBeanFactory, "beanName"));
57+
58+
assertThat(aotContribution).isNotNull();
59+
}
60+
61+
@ParameterizedTest
62+
@ValueSource(classes = { InMemoryOAuth2AuthorizationService.class, InMemoryRegisteredClientRepository.class,
63+
Object.class })
64+
void whenABeanRegistrationAotContributionShouldNotBeReturned(Class<?> beanClass) {
65+
this.defaultListableBeanFactory.registerBeanDefinition("beanName", new RootBeanDefinition(beanClass));
66+
67+
BeanRegistrationAotContribution aotContribution = this.processor
68+
.processAheadOfTime(RegisteredBean.of(this.defaultListableBeanFactory, "beanName"));
69+
70+
assertThat(aotContribution).isNull();
71+
}
72+
73+
@Test
74+
void aotContributionOnlyNeedsSpecifiedOnce() {
75+
this.defaultListableBeanFactory.registerBeanDefinition("oauth2AuthorizationService",
76+
new RootBeanDefinition(JdbcOAuth2AuthorizationService.class));
77+
78+
this.defaultListableBeanFactory.registerBeanDefinition("registeredClientRepository",
79+
new RootBeanDefinition(CustomJdbcRegisteredClientRepository.class));
80+
81+
BeanRegistrationAotContribution firstAotContribution = this.processor
82+
.processAheadOfTime(RegisteredBean.of(this.defaultListableBeanFactory, "oauth2AuthorizationService"));
83+
84+
BeanRegistrationAotContribution secondAotContribution = this.processor
85+
.processAheadOfTime(RegisteredBean.of(this.defaultListableBeanFactory, "registeredClientRepository"));
86+
87+
assertThat(firstAotContribution).isNotNull();
88+
assertThat(secondAotContribution).isNull();
89+
}
90+
91+
static class CustomJdbcOAuth2AuthorizationService extends JdbcOAuth2AuthorizationService {
92+
93+
CustomJdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations,
94+
RegisteredClientRepository registeredClientRepository) {
95+
super(jdbcOperations, registeredClientRepository);
96+
}
97+
98+
}
99+
100+
static class CustomJdbcRegisteredClientRepository extends JdbcRegisteredClientRepository {
101+
102+
CustomJdbcRegisteredClientRepository(JdbcOperations jdbcOperations) {
103+
super(jdbcOperations);
104+
}
105+
106+
}
107+
108+
}

0 commit comments

Comments
 (0)