@@ -8,17 +8,20 @@ import feign.auth.BasicAuthRequestInterceptor
88import org.springframework.beans.factory.annotation.Value
99import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
1010{ {/-first} }
11+ { {^useSpringBoot4} }
1112{ {#isOAuth} }
1213import org.springframework.boot.context.properties.ConfigurationProperties
1314{ {/isOAuth} }
15+ { {/useSpringBoot4} }
1416{ {/authMethods} }
17+ { {^useSpringBoot4} }
1518import org.springframework.boot.context.properties.EnableConfigurationProperties
16- { {#authMethods } }
17- { {#-first } }
19+ { {/useSpringBoot4 } }
20+ { {#hasAuthMethods } }
1821import org.springframework.context.annotation.Bean
19- { {/-first} }
20- { {/authMethods} }
22+ { {/hasAuthMethods} }
2123import org.springframework.context.annotation.Configuration
24+ { {^useSpringBoot4} }
2225{ {#authMethods} }
2326{ {#isOAuth} }
2427import org.springframework.cloud.openfeign.security.OAuth2FeignRequestInterceptor
@@ -38,9 +41,29 @@ import org.springframework.security.oauth2.client.token.grant.password.ResourceO
3841{ {/isPassword} }
3942{ {/isOAuth} }
4043{ {/authMethods} }
44+ { {/useSpringBoot4} }
45+ { {#useSpringBoot4} }
46+ { {#hasOAuthMethods} }
47+ import org.springframework.security.authentication.AnonymousAuthenticationToken
48+ import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager
49+ import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest
50+ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager
51+ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService
52+ import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
53+ import org.springframework.security.oauth2.core.OAuth2AuthenticationException
54+ import org.springframework.security.oauth2.core.OAuth2AccessToken
55+ import org.springframework.security.core.authority.AuthorityUtils
56+ import org.springframework.http.HttpHeaders
57+
58+ import feign.RequestInterceptor
59+ import feign.RequestTemplate
60+ { {/hasOAuthMethods} }
61+ { {/useSpringBoot4} }
4162
4263@Configuration
64+ { {^useSpringBoot4} }
4365@EnableConfigurationProperties
66+ { {/useSpringBoot4} }
4467class ClientConfiguration {
4568
4669 {{#authMethods} }
@@ -70,6 +93,7 @@ class ClientConfiguration {
7093
7194 { {/isApiKey} }
7295 { {#isOAuth} }
96+ { {^useSpringBoot4} }
7397 @Bean
7498 @ConditionalOnProperty("{ {#lambda.lowercase} }{ {{title} }}{ {/lambda.lowercase} }.security.{ {{name} }}.client-id")
7599 fun { {#lambda.camelcase} }{ {{name} }}{ {/lambda.camelcase} }RequestInterceptor(oAuth2ClientContext: OAuth2ClientContext): OAuth2FeignRequestInterceptor {
@@ -127,6 +151,61 @@ class ClientConfiguration {
127151 }
128152
129153 { {/isImplicit} }
154+ { {/useSpringBoot4} }
155+ { {#useSpringBoot4} }
156+ @Bean
157+ @ConditionalOnProperty(prefix = "spring.security.oauth2.client.registration.{ {{name} }}{ {#lambda.pascalcase} }{ {{flow} }}{ {/lambda.pascalcase} }", name = ["enabled"], havingValue = "true")
158+ fun { {{flow} }}OAuth2RequestInterceptor({ {{flow} }}AuthorizedClientManager: OAuth2AuthorizedClientManager): OAuth2RequestInterceptor {
159+ return OAuth2RequestInterceptor(
160+ OAuth2AuthorizeRequest.withClientRegistrationId(" {{{name}}}{{#lambda.pascalcase}}{{{flow}}}{{/lambda.pascalcase}}" )
161+ .principal(AnonymousAuthenticationToken(CLIENT_PRINCIPAL_{{#lambda.uppercase} }{ {{flow} }}{ {/lambda.uppercase} }, CLIENT_PRINCIPAL_{ {#lambda.uppercase} }{ {{flow} }}{ {/lambda.uppercase} }, AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")))
162+ .build(),
163+ { {{flow} }}AuthorizedClientManager
164+ )
165+ }
166+
167+ @Bean
168+ @ConditionalOnProperty(prefix = "spring.security.oauth2.client.registration.{ {{name} }}{ {#lambda.pascalcase} }{ {{flow} }}{ {/lambda.pascalcase} }", name = ["enabled"], havingValue = "true")
169+ fun { {{flow} }}AuthorizedClientManager(
170+ clientRegistrationRepository: ClientRegistrationRepository,
171+ authorizedClientService: OAuth2AuthorizedClientService
172+ ): OAuth2AuthorizedClientManager {
173+ return AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService)
174+ }
175+
176+ { {/useSpringBoot4} }
130177 { {/isOAuth} }
131178 { {/authMethods} }
132- }
179+ { {#useSpringBoot4} }
180+ { {#hasOAuthMethods} }
181+ class OAuth2RequestInterceptor(
182+ private val oAuth2AuthorizeRequest: OAuth2AuthorizeRequest,
183+ private val oAuth2AuthorizedClientManager: OAuth2AuthorizedClientManager
184+ ) : RequestInterceptor {
185+
186+ override fun apply(template: RequestTemplate) {
187+ template.header(HttpHeaders.AUTHORIZATION, getBearerToken())
188+ }
189+
190+ fun getAccessToken(): OAuth2AccessToken {
191+ val authorizedClient = oAuth2AuthorizedClientManager.authorize(oAuth2AuthorizeRequest)
192+ ?: throw OAuth2AuthenticationException(" Client failed to authenticate" )
193+ return authorizedClient.accessToken
194+ }
195+
196+ fun getBearerToken(): String {
197+ val accessToken = getAccessToken()
198+ return String.format(java.util.Locale.ROOT, " %s %s" , accessToken.tokenType?.value, accessToken.tokenValue)
199+ }
200+ }
201+
202+ companion object {
203+ {{#authMethods} }
204+ { {#isOAuth} }
205+ private const val CLIENT_PRINCIPAL_{ {#lambda.uppercase} }{ {{flow} }}{ {/lambda.uppercase} } = "oauth2FeignClient"
206+ { {/isOAuth} }
207+ { {/authMethods} }
208+ }
209+ { {/hasOAuthMethods} }
210+ { {/useSpringBoot4} }
211+ }
0 commit comments