mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-12 05:13:33 +00:00
OAuth2AuthorizeRequest supports attributes
Fixes gh-7341
This commit is contained in:
parent
4a754c1f45
commit
a60446836b
@ -26,7 +26,7 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient
|
|||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.reactive.result.method.annotation.OAuth2AuthorizedClientArgumentResolver;
|
import org.springframework.security.oauth2.client.web.reactive.result.method.annotation.OAuth2AuthorizedClientArgumentResolver;
|
||||||
import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||||
@ -73,7 +73,7 @@ final class ReactiveOAuth2ClientImportSelector implements ImportSelector {
|
|||||||
.clientCredentials()
|
.clientCredentials()
|
||||||
.password()
|
.password()
|
||||||
.build();
|
.build();
|
||||||
DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
this.clientRegistrationRepository, getAuthorizedClientRepository());
|
this.clientRegistrationRepository, getAuthorizedClientRepository());
|
||||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
configurer.addCustomResolver(new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager));
|
configurer.addCustomResolver(new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager));
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.security.oauth2.client;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a request the {@link OAuth2AuthorizedClientManager} uses to
|
||||||
|
* {@link OAuth2AuthorizedClientManager#authorize(OAuth2AuthorizeRequest) authorize} (or re-authorize)
|
||||||
|
* the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
|
||||||
|
*
|
||||||
|
* @author Joe Grandja
|
||||||
|
* @since 5.2
|
||||||
|
* @see OAuth2AuthorizedClientManager
|
||||||
|
*/
|
||||||
|
public final class OAuth2AuthorizeRequest {
|
||||||
|
private String clientRegistrationId;
|
||||||
|
private OAuth2AuthorizedClient authorizedClient;
|
||||||
|
private Authentication principal;
|
||||||
|
private Map<String, Object> attributes;
|
||||||
|
|
||||||
|
private OAuth2AuthorizeRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier for the {@link ClientRegistration client registration}.
|
||||||
|
*
|
||||||
|
* @return the identifier for the client registration
|
||||||
|
*/
|
||||||
|
public String getClientRegistrationId() {
|
||||||
|
return this.clientRegistrationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
|
||||||
|
*
|
||||||
|
* @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public OAuth2AuthorizedClient getAuthorizedClient() {
|
||||||
|
return this.authorizedClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code Principal} (to be) associated to the authorized client.
|
||||||
|
*
|
||||||
|
* @return the {@code Principal} (to be) associated to the authorized client
|
||||||
|
*/
|
||||||
|
public Authentication getPrincipal() {
|
||||||
|
return this.principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the attributes associated to the request.
|
||||||
|
*
|
||||||
|
* @return a {@code Map} of the attributes associated to the request
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getAttributes() {
|
||||||
|
return this.attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of an attribute associated to the request or {@code null} if not available.
|
||||||
|
*
|
||||||
|
* @param name the name of the attribute
|
||||||
|
* @param <T> the type of the attribute
|
||||||
|
* @return the value of the attribute associated to the request
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> T getAttribute(String name) {
|
||||||
|
return (T) this.getAttributes().get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@link Builder} initialized with the identifier for the {@link ClientRegistration client registration}.
|
||||||
|
*
|
||||||
|
* @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
|
||||||
|
* @return the {@link Builder}
|
||||||
|
*/
|
||||||
|
public static Builder withClientRegistrationId(String clientRegistrationId) {
|
||||||
|
return new Builder(clientRegistrationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@link Builder} initialized with the {@link OAuth2AuthorizedClient authorized client}.
|
||||||
|
*
|
||||||
|
* @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
|
||||||
|
* @return the {@link Builder}
|
||||||
|
*/
|
||||||
|
public static Builder withAuthorizedClient(OAuth2AuthorizedClient authorizedClient) {
|
||||||
|
return new Builder(authorizedClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder for {@link OAuth2AuthorizeRequest}.
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
private String clientRegistrationId;
|
||||||
|
private OAuth2AuthorizedClient authorizedClient;
|
||||||
|
private Authentication principal;
|
||||||
|
private Map<String, Object> attributes;
|
||||||
|
|
||||||
|
private Builder(String clientRegistrationId) {
|
||||||
|
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
|
||||||
|
this.clientRegistrationId = clientRegistrationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(OAuth2AuthorizedClient authorizedClient) {
|
||||||
|
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
|
||||||
|
this.authorizedClient = authorizedClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@code Principal} (to be) associated to the authorized client.
|
||||||
|
*
|
||||||
|
* @param principal the {@code Principal} (to be) associated to the authorized client
|
||||||
|
* @return the {@link Builder}
|
||||||
|
*/
|
||||||
|
public Builder principal(Authentication principal) {
|
||||||
|
this.principal = principal;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a {@link Consumer} access to the attributes associated to the request.
|
||||||
|
*
|
||||||
|
* @param attributesConsumer a {@link Consumer} of the attributes associated to the request
|
||||||
|
* @return the {@link Builder}
|
||||||
|
*/
|
||||||
|
public Builder attributes(Consumer<Map<String, Object>> attributesConsumer) {
|
||||||
|
if (this.attributes == null) {
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
}
|
||||||
|
attributesConsumer.accept(this.attributes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an attribute associated to the request.
|
||||||
|
*
|
||||||
|
* @param name the name of the attribute
|
||||||
|
* @param value the value of the attribute
|
||||||
|
* @return the {@link Builder}
|
||||||
|
*/
|
||||||
|
public Builder attribute(String name, Object value) {
|
||||||
|
if (this.attributes == null) {
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
}
|
||||||
|
this.attributes.put(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new {@link OAuth2AuthorizeRequest}.
|
||||||
|
*
|
||||||
|
* @return a {@link OAuth2AuthorizeRequest}
|
||||||
|
*/
|
||||||
|
public OAuth2AuthorizeRequest build() {
|
||||||
|
Assert.notNull(this.principal, "principal cannot be null");
|
||||||
|
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest();
|
||||||
|
if (this.authorizedClient != null) {
|
||||||
|
authorizeRequest.clientRegistrationId = this.authorizedClient.getClientRegistration().getRegistrationId();
|
||||||
|
authorizeRequest.authorizedClient = this.authorizedClient;
|
||||||
|
} else {
|
||||||
|
authorizeRequest.clientRegistrationId = this.clientRegistrationId;
|
||||||
|
}
|
||||||
|
authorizeRequest.principal = this.principal;
|
||||||
|
authorizeRequest.attributes = Collections.unmodifiableMap(
|
||||||
|
CollectionUtils.isEmpty(this.attributes) ?
|
||||||
|
Collections.emptyMap() : new LinkedHashMap<>(this.attributes));
|
||||||
|
return authorizeRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,12 +13,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web;
|
package org.springframework.security.oauth2.client;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementations of this interface are responsible for the overall management
|
* Implementations of this interface are responsible for the overall management
|
||||||
@ -30,13 +29,14 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
|
|||||||
* <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
|
* <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
|
||||||
* by leveraging an {@link OAuth2AuthorizedClientProvider}(s).</li>
|
* by leveraging an {@link OAuth2AuthorizedClientProvider}(s).</li>
|
||||||
* <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
|
* <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
|
||||||
* typically using an {@link OAuth2AuthorizedClientRepository}.</li>
|
* typically using an {@link OAuth2AuthorizedClientService} OR {@link OAuth2AuthorizedClientRepository}.</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
* @see OAuth2AuthorizedClient
|
* @see OAuth2AuthorizedClient
|
||||||
* @see OAuth2AuthorizedClientProvider
|
* @see OAuth2AuthorizedClientProvider
|
||||||
|
* @see OAuth2AuthorizedClientService
|
||||||
* @see OAuth2AuthorizedClientRepository
|
* @see OAuth2AuthorizedClientRepository
|
||||||
*/
|
*/
|
||||||
public interface OAuth2AuthorizedClientManager {
|
public interface OAuth2AuthorizedClientManager {
|
@ -13,11 +13,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web.server;
|
package org.springframework.security.oauth2.client;
|
||||||
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,26 +29,27 @@ import reactor.core.publisher.Mono;
|
|||||||
* <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
|
* <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
|
||||||
* by leveraging a {@link ReactiveOAuth2AuthorizedClientProvider}(s).</li>
|
* by leveraging a {@link ReactiveOAuth2AuthorizedClientProvider}(s).</li>
|
||||||
* <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
|
* <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
|
||||||
* typically using an {@link ServerOAuth2AuthorizedClientRepository}.</li>
|
* typically using a {@link ReactiveOAuth2AuthorizedClientService} OR {@link ServerOAuth2AuthorizedClientRepository}.</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
* @see OAuth2AuthorizedClient
|
* @see OAuth2AuthorizedClient
|
||||||
* @see ReactiveOAuth2AuthorizedClientProvider
|
* @see ReactiveOAuth2AuthorizedClientProvider
|
||||||
|
* @see ReactiveOAuth2AuthorizedClientService
|
||||||
* @see ServerOAuth2AuthorizedClientRepository
|
* @see ServerOAuth2AuthorizedClientRepository
|
||||||
*/
|
*/
|
||||||
public interface ServerOAuth2AuthorizedClientManager {
|
public interface ReactiveOAuth2AuthorizedClientManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to authorize or re-authorize (if required) the {@link ClientRegistration client}
|
* Attempt to authorize or re-authorize (if required) the {@link ClientRegistration client}
|
||||||
* identified by the provided {@link ServerOAuth2AuthorizeRequest#getClientRegistrationId() clientRegistrationId}.
|
* identified by the provided {@link OAuth2AuthorizeRequest#getClientRegistrationId() clientRegistrationId}.
|
||||||
* Implementations must return an empty {@code Mono} if authorization is not supported for the specified client,
|
* Implementations must return an empty {@code Mono} if authorization is not supported for the specified client,
|
||||||
* e.g. the associated {@link ReactiveOAuth2AuthorizedClientProvider}(s) does not support
|
* e.g. the associated {@link ReactiveOAuth2AuthorizedClientProvider}(s) does not support
|
||||||
* the {@link ClientRegistration#getAuthorizationGrantType() authorization grant} type configured for the client.
|
* the {@link ClientRegistration#getAuthorizationGrantType() authorization grant} type configured for the client.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* In the case of re-authorization, implementations must return the provided {@link ServerOAuth2AuthorizeRequest#getAuthorizedClient() authorized client}
|
* In the case of re-authorization, implementations must return the provided {@link OAuth2AuthorizeRequest#getAuthorizedClient() authorized client}
|
||||||
* if re-authorization is not supported for the client OR is not required,
|
* if re-authorization is not supported for the client OR is not required,
|
||||||
* e.g. a {@link OAuth2AuthorizedClient#getRefreshToken() refresh token} is not available OR
|
* e.g. a {@link OAuth2AuthorizedClient#getRefreshToken() refresh token} is not available OR
|
||||||
* the {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
|
* the {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
|
||||||
@ -57,6 +57,6 @@ public interface ServerOAuth2AuthorizedClientManager {
|
|||||||
* @param authorizeRequest the authorize request
|
* @param authorizeRequest the authorize request
|
||||||
* @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if authorization is not supported for the specified client
|
* @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if authorization is not supported for the specified client
|
||||||
*/
|
*/
|
||||||
Mono<OAuth2AuthorizedClient> authorize(ServerOAuth2AuthorizeRequest authorizeRequest);
|
Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest);
|
||||||
|
|
||||||
}
|
}
|
@ -18,16 +18,21 @@ package org.springframework.security.oauth2.client.web;
|
|||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -68,8 +73,11 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
|
|||||||
String clientRegistrationId = authorizeRequest.getClientRegistrationId();
|
String clientRegistrationId = authorizeRequest.getClientRegistrationId();
|
||||||
OAuth2AuthorizedClient authorizedClient = authorizeRequest.getAuthorizedClient();
|
OAuth2AuthorizedClient authorizedClient = authorizeRequest.getAuthorizedClient();
|
||||||
Authentication principal = authorizeRequest.getPrincipal();
|
Authentication principal = authorizeRequest.getPrincipal();
|
||||||
HttpServletRequest servletRequest = authorizeRequest.getServletRequest();
|
|
||||||
HttpServletResponse servletResponse = authorizeRequest.getServletResponse();
|
HttpServletRequest servletRequest = getHttpServletRequestOrDefault(authorizeRequest.getAttributes());
|
||||||
|
Assert.notNull(servletRequest, "servletRequest cannot be null");
|
||||||
|
HttpServletResponse servletResponse = getHttpServletResponseOrDefault(authorizeRequest.getAttributes());
|
||||||
|
Assert.notNull(servletResponse, "servletResponse cannot be null");
|
||||||
|
|
||||||
OAuth2AuthorizationContext.Builder contextBuilder;
|
OAuth2AuthorizationContext.Builder contextBuilder;
|
||||||
if (authorizedClient != null) {
|
if (authorizedClient != null) {
|
||||||
@ -104,6 +112,28 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
|
|||||||
return authorizedClient;
|
return authorizedClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HttpServletRequest getHttpServletRequestOrDefault(Map<String, Object> attributes) {
|
||||||
|
HttpServletRequest servletRequest = (HttpServletRequest) attributes.get(HttpServletRequest.class.getName());
|
||||||
|
if (servletRequest == null) {
|
||||||
|
ServletRequestAttributes context = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (context != null) {
|
||||||
|
servletRequest = context.getRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return servletRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpServletResponse getHttpServletResponseOrDefault(Map<String, Object> attributes) {
|
||||||
|
HttpServletResponse servletResponse = (HttpServletResponse) attributes.get(HttpServletResponse.class.getName());
|
||||||
|
if (servletResponse == null) {
|
||||||
|
ServletRequestAttributes context = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (context != null) {
|
||||||
|
servletResponse = context.getResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return servletResponse;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
|
* Sets the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
|
||||||
*
|
*
|
||||||
@ -133,9 +163,11 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> apply(OAuth2AuthorizeRequest authorizeRequest) {
|
public Map<String, Object> apply(OAuth2AuthorizeRequest authorizeRequest) {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = Collections.emptyMap();
|
||||||
String scope = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.SCOPE);
|
HttpServletRequest servletRequest = getHttpServletRequestOrDefault(authorizeRequest.getAttributes());
|
||||||
|
String scope = servletRequest.getParameter(OAuth2ParameterNames.SCOPE);
|
||||||
if (StringUtils.hasText(scope)) {
|
if (StringUtils.hasText(scope)) {
|
||||||
|
contextAttributes = new HashMap<>();
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
|
contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
|
||||||
StringUtils.delimitedListToStringArray(scope, " "));
|
StringUtils.delimitedListToStringArray(scope, " "));
|
||||||
}
|
}
|
||||||
|
@ -13,45 +13,49 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web.server;
|
package org.springframework.security.oauth2.client.web;
|
||||||
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default implementation of a {@link ServerOAuth2AuthorizedClientManager}.
|
* The default implementation of a {@link ReactiveOAuth2AuthorizedClientManager}.
|
||||||
*
|
*
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
* @see ServerOAuth2AuthorizedClientManager
|
* @see ReactiveOAuth2AuthorizedClientManager
|
||||||
* @see ReactiveOAuth2AuthorizedClientProvider
|
* @see ReactiveOAuth2AuthorizedClientProvider
|
||||||
*/
|
*/
|
||||||
public final class DefaultServerOAuth2AuthorizedClientManager implements ServerOAuth2AuthorizedClientManager {
|
public final class DefaultReactiveOAuth2AuthorizedClientManager implements ReactiveOAuth2AuthorizedClientManager {
|
||||||
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
|
||||||
private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
|
private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
|
||||||
private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = context -> Mono.empty();
|
private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = context -> Mono.empty();
|
||||||
private Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper = new DefaultContextAttributesMapper();
|
private Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper = new DefaultContextAttributesMapper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a {@code DefaultServerOAuth2AuthorizedClientManager} using the provided parameters.
|
* Constructs a {@code DefaultReactiveOAuth2AuthorizedClientManager} using the provided parameters.
|
||||||
*
|
*
|
||||||
* @param clientRegistrationRepository the repository of client registrations
|
* @param clientRegistrationRepository the repository of client registrations
|
||||||
* @param authorizedClientRepository the repository of authorized clients
|
* @param authorizedClientRepository the repository of authorized clients
|
||||||
*/
|
*/
|
||||||
public DefaultServerOAuth2AuthorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
|
public DefaultReactiveOAuth2AuthorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
|
||||||
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||||
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
|
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
|
||||||
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
|
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
|
||||||
@ -60,12 +64,14 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<OAuth2AuthorizedClient> authorize(ServerOAuth2AuthorizeRequest authorizeRequest) {
|
public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest) {
|
||||||
Assert.notNull(authorizeRequest, "authorizeRequest cannot be null");
|
Assert.notNull(authorizeRequest, "authorizeRequest cannot be null");
|
||||||
|
|
||||||
String clientRegistrationId = authorizeRequest.getClientRegistrationId();
|
String clientRegistrationId = authorizeRequest.getClientRegistrationId();
|
||||||
Authentication principal = authorizeRequest.getPrincipal();
|
Authentication principal = authorizeRequest.getPrincipal();
|
||||||
ServerWebExchange serverWebExchange = authorizeRequest.getServerWebExchange();
|
|
||||||
|
ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
|
||||||
|
Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
|
||||||
|
|
||||||
return Mono.justOrEmpty(authorizeRequest.getAuthorizedClient())
|
return Mono.justOrEmpty(authorizeRequest.getAuthorizedClient())
|
||||||
.switchIfEmpty(Mono.defer(() ->
|
.switchIfEmpty(Mono.defer(() ->
|
||||||
@ -94,7 +100,7 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<OAuth2AuthorizationContext> authorizationContext(ServerOAuth2AuthorizeRequest authorizeRequest,
|
private Mono<OAuth2AuthorizationContext> authorizationContext(OAuth2AuthorizeRequest authorizeRequest,
|
||||||
OAuth2AuthorizedClient authorizedClient) {
|
OAuth2AuthorizedClient authorizedClient) {
|
||||||
return Mono.just(authorizeRequest)
|
return Mono.just(authorizeRequest)
|
||||||
.flatMap(this.contextAttributesMapper::apply)
|
.flatMap(this.contextAttributesMapper::apply)
|
||||||
@ -104,7 +110,7 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
|
|||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<OAuth2AuthorizationContext> authorizationContext(ServerOAuth2AuthorizeRequest authorizeRequest,
|
private Mono<OAuth2AuthorizationContext> authorizationContext(OAuth2AuthorizeRequest authorizeRequest,
|
||||||
ClientRegistration clientRegistration) {
|
ClientRegistration clientRegistration) {
|
||||||
return Mono.just(authorizeRequest)
|
return Mono.just(authorizeRequest)
|
||||||
.flatMap(this.contextAttributesMapper::apply)
|
.flatMap(this.contextAttributesMapper::apply)
|
||||||
@ -125,13 +131,13 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@code Function} used for mapping attribute(s) from the {@link ServerOAuth2AuthorizeRequest} to a {@code Map} of attributes
|
* Sets the {@code Function} used for mapping attribute(s) from the {@link OAuth2AuthorizeRequest} to a {@code Map} of attributes
|
||||||
* to be associated to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}.
|
* to be associated to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}.
|
||||||
*
|
*
|
||||||
* @param contextAttributesMapper the {@code Function} used for supplying the {@code Map} of attributes
|
* @param contextAttributesMapper the {@code Function} used for supplying the {@code Map} of attributes
|
||||||
* to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}
|
* to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}
|
||||||
*/
|
*/
|
||||||
public void setContextAttributesMapper(Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper) {
|
public void setContextAttributesMapper(Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper) {
|
||||||
Assert.notNull(contextAttributesMapper, "contextAttributesMapper cannot be null");
|
Assert.notNull(contextAttributesMapper, "contextAttributesMapper cannot be null");
|
||||||
this.contextAttributesMapper = contextAttributesMapper;
|
this.contextAttributesMapper = contextAttributesMapper;
|
||||||
}
|
}
|
||||||
@ -139,13 +145,15 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
|
|||||||
/**
|
/**
|
||||||
* The default implementation of the {@link #setContextAttributesMapper(Function) contextAttributesMapper}.
|
* The default implementation of the {@link #setContextAttributesMapper(Function) contextAttributesMapper}.
|
||||||
*/
|
*/
|
||||||
public static class DefaultContextAttributesMapper implements Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> {
|
public static class DefaultContextAttributesMapper implements Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Map<String, Object>> apply(ServerOAuth2AuthorizeRequest authorizeRequest) {
|
public Mono<Map<String, Object>> apply(OAuth2AuthorizeRequest authorizeRequest) {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = Collections.emptyMap();
|
||||||
String scope = authorizeRequest.getServerWebExchange().getRequest().getQueryParams().getFirst(OAuth2ParameterNames.SCOPE);
|
ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
|
||||||
|
String scope = serverWebExchange.getRequest().getQueryParams().getFirst(OAuth2ParameterNames.SCOPE);
|
||||||
if (StringUtils.hasText(scope)) {
|
if (StringUtils.hasText(scope)) {
|
||||||
|
contextAttributes = new HashMap<>();
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
|
contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
|
||||||
StringUtils.delimitedListToStringArray(scope, " "));
|
StringUtils.delimitedListToStringArray(scope, " "));
|
||||||
}
|
}
|
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a request the {@link OAuth2AuthorizedClientManager} uses to
|
|
||||||
* {@link OAuth2AuthorizedClientManager#authorize(OAuth2AuthorizeRequest) authorize} (or re-authorize)
|
|
||||||
* the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
|
|
||||||
*
|
|
||||||
* @author Joe Grandja
|
|
||||||
* @since 5.2
|
|
||||||
* @see OAuth2AuthorizedClientManager
|
|
||||||
*/
|
|
||||||
public class OAuth2AuthorizeRequest {
|
|
||||||
private final String clientRegistrationId;
|
|
||||||
private final OAuth2AuthorizedClient authorizedClient;
|
|
||||||
private final Authentication principal;
|
|
||||||
private final HttpServletRequest servletRequest;
|
|
||||||
private final HttpServletResponse servletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an {@code OAuth2AuthorizeRequest} using the provided parameters.
|
|
||||||
*
|
|
||||||
* @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
|
|
||||||
* @param principal the {@code Principal} (to be) associated to the authorized client
|
|
||||||
* @param servletRequest the {@code HttpServletRequest}
|
|
||||||
* @param servletResponse the {@code HttpServletResponse}
|
|
||||||
*/
|
|
||||||
public OAuth2AuthorizeRequest(String clientRegistrationId, Authentication principal,
|
|
||||||
HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
|
|
||||||
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
|
|
||||||
Assert.notNull(principal, "principal cannot be null");
|
|
||||||
Assert.notNull(servletRequest, "servletRequest cannot be null");
|
|
||||||
Assert.notNull(servletResponse, "servletResponse cannot be null");
|
|
||||||
this.clientRegistrationId = clientRegistrationId;
|
|
||||||
this.authorizedClient = null;
|
|
||||||
this.principal = principal;
|
|
||||||
this.servletRequest = servletRequest;
|
|
||||||
this.servletResponse = servletResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an {@code OAuth2AuthorizeRequest} using the provided parameters.
|
|
||||||
*
|
|
||||||
* @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
|
|
||||||
* @param principal the {@code Principal} associated to the authorized client
|
|
||||||
* @param servletRequest the {@code HttpServletRequest}
|
|
||||||
* @param servletResponse the {@code HttpServletResponse}
|
|
||||||
*/
|
|
||||||
public OAuth2AuthorizeRequest(OAuth2AuthorizedClient authorizedClient, Authentication principal,
|
|
||||||
HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
|
|
||||||
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
|
|
||||||
Assert.notNull(principal, "principal cannot be null");
|
|
||||||
Assert.notNull(servletRequest, "servletRequest cannot be null");
|
|
||||||
Assert.notNull(servletResponse, "servletResponse cannot be null");
|
|
||||||
this.clientRegistrationId = authorizedClient.getClientRegistration().getRegistrationId();
|
|
||||||
this.authorizedClient = authorizedClient;
|
|
||||||
this.principal = principal;
|
|
||||||
this.servletRequest = servletRequest;
|
|
||||||
this.servletResponse = servletResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the identifier for the {@link ClientRegistration client registration}.
|
|
||||||
*
|
|
||||||
* @return the identifier for the client registration
|
|
||||||
*/
|
|
||||||
public String getClientRegistrationId() {
|
|
||||||
return this.clientRegistrationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
|
|
||||||
*
|
|
||||||
* @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public OAuth2AuthorizedClient getAuthorizedClient() {
|
|
||||||
return this.authorizedClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@code Principal} (to be) associated to the authorized client.
|
|
||||||
*
|
|
||||||
* @return the {@code Principal} (to be) associated to the authorized client
|
|
||||||
*/
|
|
||||||
public Authentication getPrincipal() {
|
|
||||||
return this.principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@code HttpServletRequest}.
|
|
||||||
*
|
|
||||||
* @return the {@code HttpServletRequest}
|
|
||||||
*/
|
|
||||||
public HttpServletRequest getServletRequest() {
|
|
||||||
return this.servletRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@code HttpServletResponse}.
|
|
||||||
*
|
|
||||||
* @return the {@code HttpServletResponse}
|
|
||||||
*/
|
|
||||||
public HttpServletResponse getServletResponse() {
|
|
||||||
return this.servletResponse;
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,8 +33,8 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResp
|
|||||||
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
|
import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizeRequest;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@ -143,8 +143,11 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
|
|||||||
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
|
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
|
||||||
HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
|
HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
|
||||||
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
|
||||||
clientRegistrationId, principal, servletRequest, servletResponse);
|
.principal(principal)
|
||||||
|
.attribute(HttpServletRequest.class.getName(), servletRequest)
|
||||||
|
.attribute(HttpServletResponse.class.getName(), servletResponse)
|
||||||
|
.build();
|
||||||
|
|
||||||
return this.authorizedClientManager.authorize(authorizeRequest);
|
return this.authorizedClientManager.authorize(authorizeRequest);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
|||||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
||||||
import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider;
|
||||||
@ -31,9 +33,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia
|
|||||||
import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
|
import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizeRequest;
|
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
|
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||||
@ -75,7 +75,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken("anonymous", "anonymousUser",
|
private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken("anonymous", "anonymousUser",
|
||||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
|
|
||||||
private ServerOAuth2AuthorizedClientManager authorizedClientManager;
|
private ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
|
||||||
|
|
||||||
private boolean defaultAuthorizedClientManager;
|
private boolean defaultAuthorizedClientManager;
|
||||||
|
|
||||||
@ -94,9 +94,9 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
* Constructs a {@code ServerOAuth2AuthorizedClientExchangeFilterFunction} using the provided parameters.
|
* Constructs a {@code ServerOAuth2AuthorizedClientExchangeFilterFunction} using the provided parameters.
|
||||||
*
|
*
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
* @param authorizedClientManager the {@link ServerOAuth2AuthorizedClientManager} which manages the authorized client(s)
|
* @param authorizedClientManager the {@link ReactiveOAuth2AuthorizedClientManager} which manages the authorized client(s)
|
||||||
*/
|
*/
|
||||||
public ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
|
public ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
|
||||||
Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
|
Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
|
||||||
this.authorizedClientManager = authorizedClientManager;
|
this.authorizedClientManager = authorizedClientManager;
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
this.defaultAuthorizedClientManager = true;
|
this.defaultAuthorizedClientManager = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
|
private static ReactiveOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
|
||||||
ReactiveClientRegistrationRepository clientRegistrationRepository,
|
ReactiveClientRegistrationRepository clientRegistrationRepository,
|
||||||
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
.clientCredentials()
|
.clientCredentials()
|
||||||
.password()
|
.password()
|
||||||
.build();
|
.build();
|
||||||
DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
clientRegistrationRepository, authorizedClientRepository);
|
clientRegistrationRepository, authorizedClientRepository);
|
||||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
|
|
||||||
@ -241,10 +241,10 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
/**
|
/**
|
||||||
* Sets the {@link ReactiveOAuth2AccessTokenResponseClient} used for getting an {@link OAuth2AuthorizedClient} for the client_credentials grant.
|
* Sets the {@link ReactiveOAuth2AccessTokenResponseClient} used for getting an {@link OAuth2AuthorizedClient} for the client_credentials grant.
|
||||||
*
|
*
|
||||||
* @deprecated Use {@link #ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)} instead.
|
* @deprecated Use {@link #ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)} instead.
|
||||||
* Create an instance of {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider} configured with a
|
* Create an instance of {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider} configured with a
|
||||||
* {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setAccessTokenResponseClient(ReactiveOAuth2AccessTokenResponseClient) WebClientReactiveClientCredentialsTokenResponseClient}
|
* {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setAccessTokenResponseClient(ReactiveOAuth2AccessTokenResponseClient) WebClientReactiveClientCredentialsTokenResponseClient}
|
||||||
* (or a custom one) and than supply it to {@link DefaultServerOAuth2AuthorizedClientManager#setAuthorizedClientProvider(ReactiveOAuth2AuthorizedClientProvider) DefaultOAuth2AuthorizedClientManager}.
|
* (or a custom one) and than supply it to {@link DefaultReactiveOAuth2AuthorizedClientManager#setAuthorizedClientProvider(ReactiveOAuth2AuthorizedClientProvider) DefaultReactiveOAuth2AuthorizedClientManager}.
|
||||||
*
|
*
|
||||||
* @param clientCredentialsTokenResponseClient the client to use
|
* @param clientCredentialsTokenResponseClient the client to use
|
||||||
*/
|
*/
|
||||||
@ -252,7 +252,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
public void setClientCredentialsTokenResponseClient(
|
public void setClientCredentialsTokenResponseClient(
|
||||||
ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
|
ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
|
||||||
Assert.notNull(clientCredentialsTokenResponseClient, "clientCredentialsTokenResponseClient cannot be null");
|
Assert.notNull(clientCredentialsTokenResponseClient, "clientCredentialsTokenResponseClient cannot be null");
|
||||||
Assert.state(this.defaultAuthorizedClientManager, "The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
|
Assert.state(this.defaultAuthorizedClientManager, "The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
|
||||||
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
||||||
this.clientCredentialsTokenResponseClient = clientCredentialsTokenResponseClient;
|
this.clientCredentialsTokenResponseClient = clientCredentialsTokenResponseClient;
|
||||||
updateDefaultAuthorizedClientManager();
|
updateDefaultAuthorizedClientManager();
|
||||||
@ -266,7 +266,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
.clientCredentials(this::updateClientCredentialsProvider)
|
.clientCredentials(this::updateClientCredentialsProvider)
|
||||||
.password(configurer -> configurer.clockSkew(this.accessTokenExpiresSkew))
|
.password(configurer -> configurer.clockSkew(this.accessTokenExpiresSkew))
|
||||||
.build();
|
.build();
|
||||||
((DefaultServerOAuth2AuthorizedClientManager) this.authorizedClientManager).setAuthorizedClientProvider(authorizedClientProvider);
|
((DefaultReactiveOAuth2AuthorizedClientManager) this.authorizedClientManager).setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClientCredentialsProvider(ReactiveOAuth2AuthorizedClientProviderBuilder.ClientCredentialsGrantBuilder builder) {
|
private void updateClientCredentialsProvider(ReactiveOAuth2AuthorizedClientProviderBuilder.ClientCredentialsGrantBuilder builder) {
|
||||||
@ -289,7 +289,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public void setAccessTokenExpiresSkew(Duration accessTokenExpiresSkew) {
|
public void setAccessTokenExpiresSkew(Duration accessTokenExpiresSkew) {
|
||||||
Assert.notNull(accessTokenExpiresSkew, "accessTokenExpiresSkew cannot be null");
|
Assert.notNull(accessTokenExpiresSkew, "accessTokenExpiresSkew cannot be null");
|
||||||
Assert.state(this.defaultAuthorizedClientManager, "The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
|
Assert.state(this.defaultAuthorizedClientManager, "The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
|
||||||
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
||||||
this.accessTokenExpiresSkew = accessTokenExpiresSkew;
|
this.accessTokenExpiresSkew = accessTokenExpiresSkew;
|
||||||
updateDefaultAuthorizedClientManager();
|
updateDefaultAuthorizedClientManager();
|
||||||
@ -312,7 +312,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
reauthorizeRequest(request, authorizedClient).flatMap(this.authorizedClientManager::authorize));
|
reauthorizeRequest(request, authorizedClient).flatMap(this.authorizedClientManager::authorize));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<ServerOAuth2AuthorizeRequest> authorizeRequest(ClientRequest request) {
|
private Mono<OAuth2AuthorizeRequest> authorizeRequest(ClientRequest request) {
|
||||||
Mono<Authentication> authentication = currentAuthentication();
|
Mono<Authentication> authentication = currentAuthentication();
|
||||||
|
|
||||||
Mono<String> clientRegistrationId = Mono.justOrEmpty(clientRegistrationId(request))
|
Mono<String> clientRegistrationId = Mono.justOrEmpty(clientRegistrationId(request))
|
||||||
@ -325,10 +325,16 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
.defaultIfEmpty(Optional.empty());
|
.defaultIfEmpty(Optional.empty());
|
||||||
|
|
||||||
return Mono.zip(clientRegistrationId, authentication, serverWebExchange)
|
return Mono.zip(clientRegistrationId, authentication, serverWebExchange)
|
||||||
.map(t3 -> new ServerOAuth2AuthorizeRequest(t3.getT1(), t3.getT2(), t3.getT3().orElse(null)));
|
.map(t3 -> {
|
||||||
|
OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(t3.getT1()).principal(t3.getT2());
|
||||||
|
if (t3.getT3().isPresent()) {
|
||||||
|
builder.attribute(ServerWebExchange.class.getName(), t3.getT3().get());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<ServerOAuth2AuthorizeRequest> reauthorizeRequest(ClientRequest request, OAuth2AuthorizedClient authorizedClient) {
|
private Mono<OAuth2AuthorizeRequest> reauthorizeRequest(ClientRequest request, OAuth2AuthorizedClient authorizedClient) {
|
||||||
Mono<Authentication> authentication = currentAuthentication();
|
Mono<Authentication> authentication = currentAuthentication();
|
||||||
|
|
||||||
Mono<Optional<ServerWebExchange>> serverWebExchange = Mono.justOrEmpty(serverWebExchange(request))
|
Mono<Optional<ServerWebExchange>> serverWebExchange = Mono.justOrEmpty(serverWebExchange(request))
|
||||||
@ -337,7 +343,13 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
|
|||||||
.defaultIfEmpty(Optional.empty());
|
.defaultIfEmpty(Optional.empty());
|
||||||
|
|
||||||
return Mono.zip(authentication, serverWebExchange)
|
return Mono.zip(authentication, serverWebExchange)
|
||||||
.map(t2 -> new ServerOAuth2AuthorizeRequest(authorizedClient, t2.getT1(), t2.getT2().orElse(null)));
|
.map(t2 -> {
|
||||||
|
OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withAuthorizedClient(authorizedClient).principal(t2.getT1());
|
||||||
|
if (t2.getT2().isPresent()) {
|
||||||
|
builder.attribute(ServerWebExchange.class.getName(), t2.getT2().get());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<Authentication> currentAuthentication() {
|
private Mono<Authentication> currentAuthentication() {
|
||||||
|
@ -26,7 +26,9 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
||||||
import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
|
||||||
@ -36,8 +38,6 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia
|
|||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizeRequest;
|
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
|
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
@ -451,8 +451,17 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction
|
|||||||
}
|
}
|
||||||
HttpServletRequest servletRequest = getRequest(attrs);
|
HttpServletRequest servletRequest = getRequest(attrs);
|
||||||
HttpServletResponse servletResponse = getResponse(attrs);
|
HttpServletResponse servletResponse = getResponse(attrs);
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
|
||||||
clientRegistrationId, authentication, servletRequest, servletResponse);
|
OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId).principal(authentication);
|
||||||
|
builder.attributes(attributes -> {
|
||||||
|
if (servletRequest != null) {
|
||||||
|
attributes.put(HttpServletRequest.class.getName(), servletRequest);
|
||||||
|
}
|
||||||
|
if (servletResponse != null) {
|
||||||
|
attributes.put(HttpServletResponse.class.getName(), servletResponse);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
OAuth2AuthorizeRequest authorizeRequest = builder.build();
|
||||||
|
|
||||||
// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
|
// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
|
||||||
// since it performs a blocking I/O operation using RestTemplate internally
|
// since it performs a blocking I/O operation using RestTemplate internally
|
||||||
@ -470,8 +479,17 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction
|
|||||||
}
|
}
|
||||||
HttpServletRequest servletRequest = getRequest(attrs);
|
HttpServletRequest servletRequest = getRequest(attrs);
|
||||||
HttpServletResponse servletResponse = getResponse(attrs);
|
HttpServletResponse servletResponse = getResponse(attrs);
|
||||||
OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
|
|
||||||
authorizedClient, authentication, servletRequest, servletResponse);
|
OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withAuthorizedClient(authorizedClient).principal(authentication);
|
||||||
|
builder.attributes(attributes -> {
|
||||||
|
if (servletRequest != null) {
|
||||||
|
attributes.put(HttpServletRequest.class.getName(), servletRequest);
|
||||||
|
}
|
||||||
|
if (servletResponse != null) {
|
||||||
|
attributes.put(HttpServletResponse.class.getName(), servletResponse);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
OAuth2AuthorizeRequest reauthorizeRequest = builder.build();
|
||||||
|
|
||||||
// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
|
// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
|
||||||
// since it performs a blocking I/O operation using RestTemplate internally
|
// since it performs a blocking I/O operation using RestTemplate internally
|
||||||
|
@ -23,15 +23,15 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
||||||
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizeRequest;
|
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
|
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@ -64,15 +64,15 @@ import reactor.core.publisher.Mono;
|
|||||||
public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMethodArgumentResolver {
|
public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMethodArgumentResolver {
|
||||||
private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken(
|
private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken(
|
||||||
"anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
"anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||||
private ServerOAuth2AuthorizedClientManager authorizedClientManager;
|
private ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an {@code OAuth2AuthorizedClientArgumentResolver} using the provided parameters.
|
* Constructs an {@code OAuth2AuthorizedClientArgumentResolver} using the provided parameters.
|
||||||
*
|
*
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
* @param authorizedClientManager the {@link ServerOAuth2AuthorizedClientManager} which manages the authorized client(s)
|
* @param authorizedClientManager the {@link ReactiveOAuth2AuthorizedClientManager} which manages the authorized client(s)
|
||||||
*/
|
*/
|
||||||
public OAuth2AuthorizedClientArgumentResolver(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
|
public OAuth2AuthorizedClientArgumentResolver(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
|
||||||
Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
|
Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
|
||||||
this.authorizedClientManager = authorizedClientManager;
|
this.authorizedClientManager = authorizedClientManager;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
|
|||||||
this.authorizedClientManager = createDefaultAuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
|
this.authorizedClientManager = createDefaultAuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
|
private static ReactiveOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
|
||||||
ReactiveClientRegistrationRepository clientRegistrationRepository, ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
ReactiveClientRegistrationRepository clientRegistrationRepository, ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||||
|
|
||||||
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
|
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
|
||||||
@ -100,7 +100,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
|
|||||||
.clientCredentials()
|
.clientCredentials()
|
||||||
.password()
|
.password()
|
||||||
.build();
|
.build();
|
||||||
DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
clientRegistrationRepository, authorizedClientRepository);
|
clientRegistrationRepository, authorizedClientRepository);
|
||||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<ServerOAuth2AuthorizeRequest> authorizeRequest(String registrationId, ServerWebExchange exchange) {
|
private Mono<OAuth2AuthorizeRequest> authorizeRequest(String registrationId, ServerWebExchange exchange) {
|
||||||
Mono<Authentication> defaultedAuthentication = currentAuthentication();
|
Mono<Authentication> defaultedAuthentication = currentAuthentication();
|
||||||
|
|
||||||
Mono<String> defaultedRegistrationId = Mono.justOrEmpty(registrationId)
|
Mono<String> defaultedRegistrationId = Mono.justOrEmpty(registrationId)
|
||||||
@ -137,7 +137,13 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
|
|||||||
.switchIfEmpty(currentServerWebExchange());
|
.switchIfEmpty(currentServerWebExchange());
|
||||||
|
|
||||||
return Mono.zip(defaultedRegistrationId, defaultedAuthentication, defaultedExchange)
|
return Mono.zip(defaultedRegistrationId, defaultedAuthentication, defaultedExchange)
|
||||||
.map(t3 -> new ServerOAuth2AuthorizeRequest(t3.getT1(), t3.getT2(), t3.getT3()));
|
.map(t3 -> {
|
||||||
|
OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(t3.getT1()).principal(t3.getT2());
|
||||||
|
if (t3.getT3() != null) {
|
||||||
|
builder.attribute(ServerWebExchange.class.getName(), t3.getT3());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<Authentication> currentAuthentication() {
|
private Mono<Authentication> currentAuthentication() {
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.security.oauth2.client.web.server;
|
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a request the {@link ServerOAuth2AuthorizedClientManager} uses to
|
|
||||||
* {@link ServerOAuth2AuthorizedClientManager#authorize(ServerOAuth2AuthorizeRequest) authorize} (or re-authorize)
|
|
||||||
* the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
|
|
||||||
*
|
|
||||||
* @author Joe Grandja
|
|
||||||
* @since 5.2
|
|
||||||
* @see ServerOAuth2AuthorizedClientManager
|
|
||||||
*/
|
|
||||||
public class ServerOAuth2AuthorizeRequest {
|
|
||||||
private final String clientRegistrationId;
|
|
||||||
private final OAuth2AuthorizedClient authorizedClient;
|
|
||||||
private final Authentication principal;
|
|
||||||
private final ServerWebExchange serverWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a {@code ServerOAuth2AuthorizeRequest} using the provided parameters.
|
|
||||||
*
|
|
||||||
* @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
|
|
||||||
* @param principal the {@code Principal} (to be) associated to the authorized client
|
|
||||||
* @param serverWebExchange the {@code ServerWebExchange}
|
|
||||||
*/
|
|
||||||
public ServerOAuth2AuthorizeRequest(String clientRegistrationId, Authentication principal,
|
|
||||||
ServerWebExchange serverWebExchange) {
|
|
||||||
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
|
|
||||||
Assert.notNull(principal, "principal cannot be null");
|
|
||||||
Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
|
|
||||||
this.clientRegistrationId = clientRegistrationId;
|
|
||||||
this.authorizedClient = null;
|
|
||||||
this.principal = principal;
|
|
||||||
this.serverWebExchange = serverWebExchange;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a {@code ServerOAuth2AuthorizeRequest} using the provided parameters.
|
|
||||||
*
|
|
||||||
* @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
|
|
||||||
* @param principal the {@code Principal} (to be) associated to the authorized client
|
|
||||||
* @param serverWebExchange the {@code ServerWebExchange}
|
|
||||||
*/
|
|
||||||
public ServerOAuth2AuthorizeRequest(OAuth2AuthorizedClient authorizedClient, Authentication principal,
|
|
||||||
ServerWebExchange serverWebExchange) {
|
|
||||||
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
|
|
||||||
Assert.notNull(principal, "principal cannot be null");
|
|
||||||
Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
|
|
||||||
this.clientRegistrationId = authorizedClient.getClientRegistration().getRegistrationId();
|
|
||||||
this.authorizedClient = authorizedClient;
|
|
||||||
this.principal = principal;
|
|
||||||
this.serverWebExchange = serverWebExchange;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the identifier for the {@link ClientRegistration client registration}.
|
|
||||||
*
|
|
||||||
* @return the identifier for the client registration
|
|
||||||
*/
|
|
||||||
public String getClientRegistrationId() {
|
|
||||||
return this.clientRegistrationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
|
|
||||||
*
|
|
||||||
* @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public OAuth2AuthorizedClient getAuthorizedClient() {
|
|
||||||
return this.authorizedClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@code Principal} (to be) associated to the authorized client.
|
|
||||||
*
|
|
||||||
* @return the {@code Principal} (to be) associated to the authorized client
|
|
||||||
*/
|
|
||||||
public Authentication getPrincipal() {
|
|
||||||
return this.principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link ServerWebExchange}.
|
|
||||||
*
|
|
||||||
* @return the {@link ServerWebExchange}
|
|
||||||
*/
|
|
||||||
public ServerWebExchange getServerWebExchange() {
|
|
||||||
return this.serverWebExchange;
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,81 +13,80 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web.server;
|
package org.springframework.security.oauth2.client;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link ServerOAuth2AuthorizeRequest}.
|
* Tests for {@link OAuth2AuthorizeRequest}.
|
||||||
*
|
*
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
*/
|
*/
|
||||||
public class ServerOAuth2AuthorizeRequestTests {
|
public class OAuth2AuthorizeRequestTests {
|
||||||
private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
|
private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
|
||||||
private Authentication principal = new TestingAuthenticationToken("principal", "password");
|
private Authentication principal = new TestingAuthenticationToken("principal", "password");
|
||||||
private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
|
private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
|
||||||
this.clientRegistration, this.principal.getName(),
|
this.clientRegistration, this.principal.getName(),
|
||||||
TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
|
TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
|
||||||
private MockServerWebExchange serverWebExchange = MockServerWebExchange.builder(MockServerHttpRequest.get("/")).build();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
|
public void withClientRegistrationIdWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest((String) null, this.principal, this.serverWebExchange))
|
assertThatThrownBy(() -> OAuth2AuthorizeRequest.withClientRegistrationId(null))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("clientRegistrationId cannot be empty");
|
.hasMessage("clientRegistrationId cannot be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
|
public void withAuthorizedClientWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest((OAuth2AuthorizedClient) null, this.principal, this.serverWebExchange))
|
assertThatThrownBy(() -> OAuth2AuthorizeRequest.withAuthorizedClient(null))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("authorizedClient cannot be null");
|
.hasMessage("authorizedClient cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenPrincipalIsNullThenThrowIllegalArgumentException() {
|
public void withClientRegistrationIdWhenPrincipalIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), null, this.serverWebExchange))
|
assertThatThrownBy(() -> OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId()).build())
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("principal cannot be null");
|
.hasMessage("principal cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenServerWebExchangeIsNullThenThrowIllegalArgumentException() {
|
public void withClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
|
||||||
assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, null))
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.principal(this.principal)
|
||||||
.hasMessage("serverWebExchange cannot be null");
|
.attributes(attrs -> {
|
||||||
}
|
attrs.put("name1", "value1");
|
||||||
|
attrs.put("name2", "value2");
|
||||||
@Test
|
})
|
||||||
public void constructorClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
|
.build();
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
|
|
||||||
|
|
||||||
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
|
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
|
||||||
|
assertThat(authorizeRequest.getAuthorizedClient()).isNull();
|
||||||
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
||||||
assertThat(authorizeRequest.getServerWebExchange()).isEqualTo(this.serverWebExchange);
|
assertThat(authorizeRequest.getAttributes()).contains(entry("name1", "value1"), entry("name2", "value2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
|
public void withAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put("name1", "value1");
|
||||||
|
attrs.put("name2", "value2");
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
|
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
|
||||||
assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
|
assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
|
||||||
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
||||||
assertThat(authorizeRequest.getServerWebExchange()).isEqualTo(this.serverWebExchange);
|
assertThat(authorizeRequest.getAttributes()).contains(entry("name1", "value1"), entry("name2", "value2"));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
|||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
@ -33,6 +34,8 @@ import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
|||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -114,10 +117,36 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
.hasMessage("authorizeRequest cannot be null");
|
.hasMessage("authorizeRequest cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authorizeWhenHttpServletRequestIsNullThenThrowIllegalArgumentException() {
|
||||||
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
|
.principal(this.principal)
|
||||||
|
.build();
|
||||||
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessage("servletRequest cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authorizeWhenHttpServletResponseIsNullThenThrowIllegalArgumentException() {
|
||||||
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
|
.principal(this.principal)
|
||||||
|
.attribute(HttpServletRequest.class.getName(), this.request)
|
||||||
|
.build();
|
||||||
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessage("servletResponse cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
|
public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("invalid-registration-id")
|
||||||
"invalid-registration-id", this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
|
.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
|
||||||
@ -129,8 +158,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
when(this.clientRegistrationRepository.findByRegistrationId(
|
when(this.clientRegistrationRepository.findByRegistrationId(
|
||||||
eq(this.clientRegistration.getRegistrationId()))).thenReturn(this.clientRegistration);
|
eq(this.clientRegistration.getRegistrationId()))).thenReturn(this.clientRegistration);
|
||||||
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -154,8 +188,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(this.authorizedClient);
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(this.authorizedClient);
|
||||||
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -185,8 +224,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
|
||||||
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -212,8 +256,9 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
// Set custom contextAttributesMapper
|
// Set custom contextAttributesMapper
|
||||||
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = new HashMap<>();
|
||||||
String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
|
HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
|
||||||
String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
|
String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
|
||||||
|
String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
|
||||||
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
||||||
@ -224,8 +269,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
this.request.addParameter(OAuth2ParameterNames.USERNAME, "username");
|
this.request.addParameter(OAuth2ParameterNames.USERNAME, "username");
|
||||||
this.request.addParameter(OAuth2ParameterNames.PASSWORD, "password");
|
this.request.addParameter(OAuth2ParameterNames.PASSWORD, "password");
|
||||||
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
this.authorizedClientManager.authorize(authorizeRequest);
|
this.authorizedClientManager.authorize(authorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -240,8 +290,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
|
public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
|
||||||
OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -266,8 +321,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
|
||||||
|
|
||||||
OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -297,8 +357,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
this.request.addParameter(OAuth2ParameterNames.SCOPE, "read write");
|
this.request.addParameter(OAuth2ParameterNames.SCOPE, "read write");
|
||||||
|
|
||||||
OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.request, this.response);
|
.principal(this.principal)
|
||||||
|
.attributes(attrs -> {
|
||||||
|
attrs.put(HttpServletRequest.class.getName(), this.request);
|
||||||
|
attrs.put(HttpServletResponse.class.getName(), this.response);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
this.authorizedClientManager.authorize(reauthorizeRequest);
|
this.authorizedClientManager.authorize(reauthorizeRequest);
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.oauth2.client.web.server;
|
package org.springframework.security.oauth2.client.web;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -24,11 +24,13 @@ import org.springframework.mock.web.server.MockServerWebExchange;
|
|||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
||||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||||
@ -48,16 +50,16 @@ import static org.mockito.ArgumentMatchers.eq;
|
|||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link DefaultServerOAuth2AuthorizedClientManager}.
|
* Tests for {@link DefaultReactiveOAuth2AuthorizedClientManager}.
|
||||||
*
|
*
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
*/
|
*/
|
||||||
public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
public class DefaultReactiveOAuth2AuthorizedClientManagerTests {
|
||||||
private ReactiveClientRegistrationRepository clientRegistrationRepository;
|
private ReactiveClientRegistrationRepository clientRegistrationRepository;
|
||||||
private ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
|
private ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
|
||||||
private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider;
|
private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider;
|
||||||
private Function contextAttributesMapper;
|
private Function contextAttributesMapper;
|
||||||
private DefaultServerOAuth2AuthorizedClientManager authorizedClientManager;
|
private DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager;
|
||||||
private ClientRegistration clientRegistration;
|
private ClientRegistration clientRegistration;
|
||||||
private Authentication principal;
|
private Authentication principal;
|
||||||
private OAuth2AuthorizedClient authorizedClient;
|
private OAuth2AuthorizedClient authorizedClient;
|
||||||
@ -77,7 +79,7 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.empty());
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.empty());
|
||||||
this.contextAttributesMapper = mock(Function.class);
|
this.contextAttributesMapper = mock(Function.class);
|
||||||
when(this.contextAttributesMapper.apply(any())).thenReturn(Mono.just(Collections.emptyMap()));
|
when(this.contextAttributesMapper.apply(any())).thenReturn(Mono.just(Collections.emptyMap()));
|
||||||
this.authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
this.authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
this.clientRegistrationRepository, this.authorizedClientRepository);
|
this.clientRegistrationRepository, this.authorizedClientRepository);
|
||||||
this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider);
|
this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider);
|
||||||
this.authorizedClientManager.setContextAttributesMapper(this.contextAttributesMapper);
|
this.authorizedClientManager.setContextAttributesMapper(this.contextAttributesMapper);
|
||||||
@ -91,14 +93,14 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenClientRegistrationRepositoryIsNullThenThrowIllegalArgumentException() {
|
public void constructorWhenClientRegistrationRepositoryIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> new DefaultServerOAuth2AuthorizedClientManager(null, this.authorizedClientRepository))
|
assertThatThrownBy(() -> new DefaultReactiveOAuth2AuthorizedClientManager(null, this.authorizedClientRepository))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("clientRegistrationRepository cannot be null");
|
.hasMessage("clientRegistrationRepository cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructorWhenOAuth2AuthorizedClientRepositoryIsNullThenThrowIllegalArgumentException() {
|
public void constructorWhenOAuth2AuthorizedClientRepositoryIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> new DefaultServerOAuth2AuthorizedClientManager(this.clientRegistrationRepository, null))
|
assertThatThrownBy(() -> new DefaultReactiveOAuth2AuthorizedClientManager(this.clientRegistrationRepository, null))
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("authorizedClientRepository cannot be null");
|
.hasMessage("authorizedClientRepository cannot be null");
|
||||||
}
|
}
|
||||||
@ -117,6 +119,16 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
.hasMessage("contextAttributesMapper cannot be null");
|
.hasMessage("contextAttributesMapper cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authorizeWhenServerWebExchangeIsNullThenThrowIllegalArgumentException() {
|
||||||
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
|
.principal(this.principal)
|
||||||
|
.build();
|
||||||
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessage("serverWebExchange cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authorizeWhenRequestIsNullThenThrowIllegalArgumentException() {
|
public void authorizeWhenRequestIsNullThenThrowIllegalArgumentException() {
|
||||||
assertThatThrownBy(() -> this.authorizedClientManager.authorize(null).block())
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(null).block())
|
||||||
@ -126,8 +138,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
|
public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("invalid-registration-id")
|
||||||
"invalid-registration-id", this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
|
assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
|
.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
|
||||||
@ -139,8 +153,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
when(this.clientRegistrationRepository.findByRegistrationId(
|
when(this.clientRegistrationRepository.findByRegistrationId(
|
||||||
eq(this.clientRegistration.getRegistrationId()))).thenReturn(Mono.just(this.clientRegistration));
|
eq(this.clientRegistration.getRegistrationId()))).thenReturn(Mono.just(this.clientRegistration));
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -165,8 +181,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
when(this.authorizedClientProvider.authorize(
|
when(this.authorizedClientProvider.authorize(
|
||||||
any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
|
any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -196,8 +214,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -221,8 +241,9 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
|
||||||
|
|
||||||
// Set custom contextAttributesMapper capable of mapping the form parameters
|
// Set custom contextAttributesMapper capable of mapping the form parameters
|
||||||
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest ->
|
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
||||||
Mono.just(authorizeRequest.getServerWebExchange())
|
ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
|
||||||
|
return Mono.just(serverWebExchange)
|
||||||
.flatMap(ServerWebExchange::getFormData)
|
.flatMap(ServerWebExchange::getFormData)
|
||||||
.map(formData -> {
|
.map(formData -> {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = new HashMap<>();
|
||||||
@ -233,8 +254,8 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
||||||
}
|
}
|
||||||
return contextAttributes;
|
return contextAttributes;
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
this.serverWebExchange = MockServerWebExchange.builder(
|
this.serverWebExchange = MockServerWebExchange.builder(
|
||||||
MockServerHttpRequest
|
MockServerHttpRequest
|
||||||
@ -243,8 +264,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
.body("username=username&password=password"))
|
.body("username=username&password=password"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
this.authorizedClientManager.authorize(authorizeRequest).block();
|
this.authorizedClientManager.authorize(authorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -259,8 +282,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
|
public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
|
||||||
ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -285,8 +310,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
|
when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
||||||
@ -312,7 +339,7 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
|
|
||||||
// Override the mock with the default
|
// Override the mock with the default
|
||||||
this.authorizedClientManager.setContextAttributesMapper(
|
this.authorizedClientManager.setContextAttributesMapper(
|
||||||
new DefaultServerOAuth2AuthorizedClientManager.DefaultContextAttributesMapper());
|
new DefaultReactiveOAuth2AuthorizedClientManager.DefaultContextAttributesMapper());
|
||||||
|
|
||||||
this.serverWebExchange = MockServerWebExchange.builder(
|
this.serverWebExchange = MockServerWebExchange.builder(
|
||||||
MockServerHttpRequest
|
MockServerHttpRequest
|
||||||
@ -320,8 +347,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
|
|||||||
.queryParam(OAuth2ParameterNames.SCOPE, "read write"))
|
.queryParam(OAuth2ParameterNames.SCOPE, "read write"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
|
OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
|
||||||
this.authorizedClient, this.principal, this.serverWebExchange);
|
.principal(this.principal)
|
||||||
|
.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
|
||||||
|
.build();
|
||||||
this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
this.authorizedClientManager.authorize(reauthorizeRequest).block();
|
||||||
|
|
||||||
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
|
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.security.oauth2.client.web;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@link OAuth2AuthorizeRequest}.
|
|
||||||
*
|
|
||||||
* @author Joe Grandja
|
|
||||||
*/
|
|
||||||
public class OAuth2AuthorizeRequestTests {
|
|
||||||
private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
|
|
||||||
private Authentication principal = new TestingAuthenticationToken("principal", "password");
|
|
||||||
private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
|
|
||||||
this.clientRegistration, this.principal.getName(),
|
|
||||||
TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
|
|
||||||
private MockHttpServletRequest servletRequest = new MockHttpServletRequest();
|
|
||||||
private MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
|
|
||||||
assertThatThrownBy(() -> new OAuth2AuthorizeRequest((String) null, this.principal, this.servletRequest, this.servletResponse))
|
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
|
||||||
.hasMessage("clientRegistrationId cannot be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
|
|
||||||
assertThatThrownBy(() -> new OAuth2AuthorizeRequest((OAuth2AuthorizedClient) null, this.principal, this.servletRequest, this.servletResponse))
|
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
|
||||||
.hasMessage("authorizedClient cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorWhenPrincipalIsNullThenThrowIllegalArgumentException() {
|
|
||||||
assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), null, this.servletRequest, this.servletResponse))
|
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
|
||||||
.hasMessage("principal cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorWhenServletRequestIsNullThenThrowIllegalArgumentException() {
|
|
||||||
assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, null, this.servletResponse))
|
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
|
||||||
.hasMessage("servletRequest cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorWhenServletResponseIsNullThenThrowIllegalArgumentException() {
|
|
||||||
assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, this.servletRequest, null))
|
|
||||||
.isInstanceOf(IllegalArgumentException.class)
|
|
||||||
.hasMessage("servletResponse cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
|
||||||
this.clientRegistration.getRegistrationId(), this.principal, this.servletRequest, this.servletResponse);
|
|
||||||
|
|
||||||
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
|
|
||||||
assertThat(authorizeRequest.getAuthorizedClient()).isNull();
|
|
||||||
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
|
||||||
assertThat(authorizeRequest.getServletRequest()).isEqualTo(this.servletRequest);
|
|
||||||
assertThat(authorizeRequest.getServletResponse()).isEqualTo(this.servletResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void constructorAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
|
|
||||||
OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
|
|
||||||
this.authorizedClient, this.principal, this.servletRequest, this.servletResponse);
|
|
||||||
|
|
||||||
assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
|
|
||||||
assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
|
|
||||||
assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
|
|
||||||
assertThat(authorizeRequest.getServletRequest()).isEqualTo(this.servletRequest);
|
|
||||||
assertThat(authorizeRequest.getServletResponse()).isEqualTo(this.servletResponse);
|
|
||||||
}
|
|
||||||
}
|
|
@ -293,8 +293,9 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
|
|||||||
// Set custom contextAttributesMapper
|
// Set custom contextAttributesMapper
|
||||||
authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = new HashMap<>();
|
||||||
String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
|
HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
|
||||||
String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
|
String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
|
||||||
|
String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
|
||||||
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
||||||
|
@ -55,7 +55,7 @@ import org.springframework.security.oauth2.client.endpoint.WebClientReactiveClie
|
|||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||||
@ -127,7 +127,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
Instant.now(),
|
Instant.now(),
|
||||||
Instant.now().plus(Duration.ofDays(1)));
|
Instant.now().plus(Duration.ofDays(1)));
|
||||||
|
|
||||||
private DefaultServerOAuth2AuthorizedClientManager authorizedClientManager;
|
private DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@ -138,7 +138,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
.clientCredentials(configurer -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
|
.clientCredentials(configurer -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
|
||||||
.password(configurer -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
|
.password(configurer -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
|
||||||
.build();
|
.build();
|
||||||
this.authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
this.authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
this.clientRegistrationRepository, this.authorizedClientRepository);
|
this.clientRegistrationRepository, this.authorizedClientRepository);
|
||||||
this.authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
this.authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
this.function = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
|
this.function = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
|
||||||
@ -161,7 +161,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
public void setClientCredentialsTokenResponseClientWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
|
public void setClientCredentialsTokenResponseClientWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
|
||||||
assertThatThrownBy(() -> this.function.setClientCredentialsTokenResponseClient(new WebClientReactiveClientCredentialsTokenResponseClient()))
|
assertThatThrownBy(() -> this.function.setClientCredentialsTokenResponseClient(new WebClientReactiveClientCredentialsTokenResponseClient()))
|
||||||
.isInstanceOf(IllegalStateException.class)
|
.isInstanceOf(IllegalStateException.class)
|
||||||
.hasMessage("The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
|
.hasMessage("The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
|
||||||
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
public void setAccessTokenExpiresSkewWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
|
public void setAccessTokenExpiresSkewWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
|
||||||
assertThatThrownBy(() -> this.function.setAccessTokenExpiresSkew(Duration.ofSeconds(30)))
|
assertThatThrownBy(() -> this.function.setAccessTokenExpiresSkew(Duration.ofSeconds(30)))
|
||||||
.isInstanceOf(IllegalStateException.class)
|
.isInstanceOf(IllegalStateException.class)
|
||||||
.hasMessage("The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
|
.hasMessage("The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
|
||||||
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,8 +429,9 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
when(this.authorizedClientRepository.loadAuthorizedClient(eq(registration.getRegistrationId()), eq(authentication), any())).thenReturn(Mono.empty());
|
when(this.authorizedClientRepository.loadAuthorizedClient(eq(registration.getRegistrationId()), eq(authentication), any())).thenReturn(Mono.empty());
|
||||||
|
|
||||||
// Set custom contextAttributesMapper capable of mapping the form parameters
|
// Set custom contextAttributesMapper capable of mapping the form parameters
|
||||||
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest ->
|
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
||||||
Mono.just(authorizeRequest.getServerWebExchange())
|
ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
|
||||||
|
return Mono.just(serverWebExchange)
|
||||||
.flatMap(ServerWebExchange::getFormData)
|
.flatMap(ServerWebExchange::getFormData)
|
||||||
.map(formData -> {
|
.map(formData -> {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = new HashMap<>();
|
||||||
@ -441,8 +442,8 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
||||||
}
|
}
|
||||||
return contextAttributes;
|
return contextAttributes;
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
this.serverWebExchange = MockServerWebExchange.builder(
|
this.serverWebExchange = MockServerWebExchange.builder(
|
||||||
MockServerHttpRequest
|
MockServerHttpRequest
|
||||||
|
@ -81,6 +81,7 @@ import reactor.core.publisher.BaseSubscriber;
|
|||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.util.context.Context;
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -466,8 +467,9 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
|
|||||||
// Set custom contextAttributesMapper
|
// Set custom contextAttributesMapper
|
||||||
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
|
||||||
Map<String, Object> contextAttributes = new HashMap<>();
|
Map<String, Object> contextAttributes = new HashMap<>();
|
||||||
String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
|
HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
|
||||||
String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
|
String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
|
||||||
|
String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
|
||||||
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
|
||||||
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
|
||||||
|
@ -36,7 +36,7 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic
|
|||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
@ -79,7 +79,7 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
|
|||||||
.refreshToken()
|
.refreshToken()
|
||||||
.clientCredentials()
|
.clientCredentials()
|
||||||
.build();
|
.build();
|
||||||
DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
|
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
this.clientRegistrationRepository, this.authorizedClientRepository);
|
this.clientRegistrationRepository, this.authorizedClientRepository);
|
||||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
this.argumentResolver = new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager);
|
this.argumentResolver = new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager);
|
||||||
|
@ -22,8 +22,8 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient
|
|||||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
||||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
|
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
|
||||||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||||||
public class WebClientConfig {
|
public class WebClientConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
WebClient webClient(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
|
WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
|
||||||
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
|
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
|
||||||
new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
|
new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
|
||||||
oauth.setDefaultOAuth2AuthorizedClient(true);
|
oauth.setDefaultOAuth2AuthorizedClient(true);
|
||||||
@ -45,7 +45,7 @@ public class WebClientConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
ServerOAuth2AuthorizedClientManager authorizedClientManager(
|
ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
|
||||||
ReactiveClientRegistrationRepository clientRegistrationRepository,
|
ReactiveClientRegistrationRepository clientRegistrationRepository,
|
||||||
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
|
||||||
|
|
||||||
@ -56,8 +56,8 @@ public class WebClientConfig {
|
|||||||
.clientCredentials()
|
.clientCredentials()
|
||||||
.password()
|
.password()
|
||||||
.build();
|
.build();
|
||||||
DefaultServerOAuth2AuthorizedClientManager authorizedClientManager =
|
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
|
||||||
new DefaultServerOAuth2AuthorizedClientManager(
|
new DefaultReactiveOAuth2AuthorizedClientManager(
|
||||||
clientRegistrationRepository, authorizedClientRepository);
|
clientRegistrationRepository, authorizedClientRepository);
|
||||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider
|
|||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
|
||||||
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
|
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user