Skip to content

Commit 7303821

Browse files
committed
Refactor and use OAuth2AuthorizedClientProvider implementations
1 parent 22d43b9 commit 7303821

File tree

5 files changed

+246
-263
lines changed

5 files changed

+246
-263
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configuration/OAuth2ClientConfiguration.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
*/
1616
package org.springframework.security.config.annotation.web.configuration;
1717

18-
import java.util.List;
19-
import java.util.Optional;
2018
import org.springframework.beans.factory.annotation.Autowired;
2119
import org.springframework.context.annotation.Configuration;
2220
import org.springframework.context.annotation.Import;
2321
import org.springframework.context.annotation.ImportSelector;
2422
import org.springframework.core.type.AnnotationMetadata;
23+
import org.springframework.security.oauth2.client.AuthorizationCodeOAuth2AuthorizedClientProvider;
24+
import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
25+
import org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClientProvider;
26+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
2527
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
2628
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
2729
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@@ -31,6 +33,9 @@
3133
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
3234
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
3335

36+
import java.util.List;
37+
import java.util.Optional;
38+
3439
/**
3540
* {@link Configuration} for OAuth 2.0 Client support.
3641
*
@@ -71,7 +76,13 @@ public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentRes
7176
new OAuth2AuthorizedClientArgumentResolver(
7277
this.clientRegistrationRepository, this.authorizedClientRepository);
7378
if (this.accessTokenResponseClient != null) {
74-
authorizedClientArgumentResolver.setClientCredentialsTokenResponseClient(this.accessTokenResponseClient);
79+
ClientCredentialsOAuth2AuthorizedClientProvider clientCredentialsAuthorizedClientProvider =
80+
new ClientCredentialsOAuth2AuthorizedClientProvider(
81+
this.clientRegistrationRepository, this.authorizedClientRepository);
82+
clientCredentialsAuthorizedClientProvider.setAccessTokenResponseClient(this.accessTokenResponseClient);
83+
OAuth2AuthorizedClientProvider authorizedClientProvider = new DelegatingOAuth2AuthorizedClientProvider(
84+
new AuthorizationCodeOAuth2AuthorizedClientProvider(), clientCredentialsAuthorizedClientProvider);
85+
authorizedClientArgumentResolver.setAuthorizedClientProvider(authorizedClientProvider);
7586
}
7687
argumentResolvers.add(authorizedClientArgumentResolver);
7788
}

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolver.java

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,8 +21,12 @@
2121
import org.springframework.lang.Nullable;
2222
import org.springframework.security.core.Authentication;
2323
import org.springframework.security.core.context.SecurityContextHolder;
24-
import org.springframework.security.oauth2.client.ClientAuthorizationRequiredException;
24+
import org.springframework.security.oauth2.client.AuthorizationCodeOAuth2AuthorizedClientProvider;
25+
import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
26+
import org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClientProvider;
27+
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
2528
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
29+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
2630
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
2731
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
2832
import org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient;
@@ -31,8 +35,6 @@
3135
import org.springframework.security.oauth2.client.registration.ClientRegistration;
3236
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
3337
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
34-
import org.springframework.security.oauth2.core.AuthorizationGrantType;
35-
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
3638
import org.springframework.util.Assert;
3739
import org.springframework.util.StringUtils;
3840
import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -66,8 +68,7 @@
6668
public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMethodArgumentResolver {
6769
private final ClientRegistrationRepository clientRegistrationRepository;
6870
private final OAuth2AuthorizedClientRepository authorizedClientRepository;
69-
private OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient =
70-
new DefaultClientCredentialsTokenResponseClient();
71+
private OAuth2AuthorizedClientProvider authorizedClientProvider;
7172

7273
/**
7374
* Constructs an {@code OAuth2AuthorizedClientArgumentResolver} using the provided parameters.
@@ -81,6 +82,7 @@ public OAuth2AuthorizedClientArgumentResolver(ClientRegistrationRepository clien
8182
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
8283
this.clientRegistrationRepository = clientRegistrationRepository;
8384
this.authorizedClientRepository = authorizedClientRepository;
85+
this.authorizedClientProvider = createAuthorizedClientProvider(new DefaultClientCredentialsTokenResponseClient());
8486
}
8587

8688
@Override
@@ -119,16 +121,20 @@ public Object resolveArgument(MethodParameter parameter,
119121
return null;
120122
}
121123

122-
if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) {
123-
throw new ClientAuthorizationRequiredException(clientRegistrationId);
124-
}
124+
HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
125125

126-
if (AuthorizationGrantType.CLIENT_CREDENTIALS.equals(clientRegistration.getAuthorizationGrantType())) {
127-
HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
128-
authorizedClient = this.authorizeClientCredentialsClient(clientRegistration, servletRequest, servletResponse);
126+
OAuth2AuthorizationContext.Builder authorizationContextBuilder = OAuth2AuthorizationContext.authorize(clientRegistration);
127+
if (principal == null) {
128+
authorizationContextBuilder.principal("anonymousUser");
129+
} else {
130+
authorizationContextBuilder.principal(principal);
129131
}
132+
OAuth2AuthorizationContext authorizationContext = authorizationContextBuilder
133+
.attribute(HttpServletRequest.class.getName(), servletRequest)
134+
.attribute(HttpServletResponse.class.getName(), servletResponse)
135+
.build();
130136

131-
return authorizedClient;
137+
return this.authorizedClientProvider.authorize(authorizationContext);
132138
}
133139

134140
private String resolveClientRegistrationId(MethodParameter parameter) {
@@ -149,37 +155,37 @@ private String resolveClientRegistrationId(MethodParameter parameter) {
149155
return clientRegistrationId;
150156
}
151157

152-
private OAuth2AuthorizedClient authorizeClientCredentialsClient(ClientRegistration clientRegistration,
153-
HttpServletRequest request, HttpServletResponse response) {
154-
OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest =
155-
new OAuth2ClientCredentialsGrantRequest(clientRegistration);
156-
OAuth2AccessTokenResponse tokenResponse =
157-
this.clientCredentialsTokenResponseClient.getTokenResponse(clientCredentialsGrantRequest);
158-
159-
Authentication principal = SecurityContextHolder.getContext().getAuthentication();
160-
161-
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
162-
clientRegistration,
163-
(principal != null ? principal.getName() : "anonymousUser"),
164-
tokenResponse.getAccessToken());
165-
166-
this.authorizedClientRepository.saveAuthorizedClient(
167-
authorizedClient,
168-
principal,
169-
request,
170-
response);
171-
172-
return authorizedClient;
158+
/**
159+
* Sets the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
160+
*
161+
* @since 5.2
162+
* @param authorizedClientProvider the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
163+
*/
164+
public void setAuthorizedClientProvider(OAuth2AuthorizedClientProvider authorizedClientProvider) {
165+
Assert.notNull(authorizedClientProvider, "authorizedClientProvider cannot be null");
166+
this.authorizedClientProvider = authorizedClientProvider;
173167
}
174168

175169
/**
176170
* Sets the client used when requesting an access token credential at the Token Endpoint for the {@code client_credentials} grant.
177171
*
172+
* @deprecated Use {@link #setAuthorizedClientProvider(OAuth2AuthorizedClientProvider)} instead by providing it an instance of {@link ClientCredentialsOAuth2AuthorizedClientProvider} configured with a {@link ClientCredentialsOAuth2AuthorizedClientProvider#setAccessTokenResponseClient(OAuth2AccessTokenResponseClient) DefaultClientCredentialsTokenResponseClient} or a custom one.
173+
*
178174
* @param clientCredentialsTokenResponseClient the client used when requesting an access token credential at the Token Endpoint for the {@code client_credentials} grant
179175
*/
176+
@Deprecated
180177
public final void setClientCredentialsTokenResponseClient(
181178
OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
182179
Assert.notNull(clientCredentialsTokenResponseClient, "clientCredentialsTokenResponseClient cannot be null");
183-
this.clientCredentialsTokenResponseClient = clientCredentialsTokenResponseClient;
180+
this.authorizedClientProvider = createAuthorizedClientProvider(clientCredentialsTokenResponseClient);
181+
}
182+
183+
private OAuth2AuthorizedClientProvider createAuthorizedClientProvider(
184+
OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
185+
ClientCredentialsOAuth2AuthorizedClientProvider clientCredentialsAuthorizedClientProvider =
186+
new ClientCredentialsOAuth2AuthorizedClientProvider(this.clientRegistrationRepository, this.authorizedClientRepository);
187+
clientCredentialsAuthorizedClientProvider.setAccessTokenResponseClient(clientCredentialsTokenResponseClient);
188+
return new DelegatingOAuth2AuthorizedClientProvider(
189+
new AuthorizationCodeOAuth2AuthorizedClientProvider(), clientCredentialsAuthorizedClientProvider);
184190
}
185191
}

0 commit comments

Comments
 (0)