Remove HttpClientConfig

Issue gh-4478
This commit is contained in:
Joe Grandja 2017-09-12 21:03:40 -04:00
parent 95de158909
commit 4ff0b52f74
5 changed files with 28 additions and 149 deletions

View File

@ -15,11 +15,9 @@
*/
package org.springframework.security.config.annotation.web.configurers.oauth2.client;
import org.springframework.context.ApplicationContext;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.jose.jws.JwsAlgorithm;
import org.springframework.security.jwt.JwtDecoder;
import org.springframework.security.jwt.nimbus.NimbusJwtDecoderJwkSupport;
import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProcessingFilter;
@ -36,7 +34,6 @@ import org.springframework.security.oauth2.client.token.SecurityTokenRepository;
import org.springframework.security.oauth2.client.user.OAuth2UserService;
import org.springframework.security.oauth2.client.user.nimbus.NimbusOAuth2UserService;
import org.springframework.security.oauth2.core.AccessToken;
import org.springframework.security.oauth2.core.http.HttpClientConfig;
import org.springframework.security.oauth2.core.provider.DefaultProviderMetadata;
import org.springframework.security.oauth2.core.provider.ProviderMetadata;
import org.springframework.security.oauth2.core.user.OAuth2User;
@ -134,8 +131,8 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
@Override
public void init(H http) throws Exception {
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
this.getAuthorizationCodeTokenExchanger(http), this.getAccessTokenRepository(),
this.getProviderJwtDecoderRegistry(http), this.getUserInfoService(http));
this.getAuthorizationCodeTokenExchanger(), this.getAccessTokenRepository(),
this.getProviderJwtDecoderRegistry(), this.getUserInfoService());
if (this.userAuthoritiesMapper != null) {
authenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper);
}
@ -160,14 +157,9 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
this.authorizationResponseMatcher : this.getAuthenticationFilter().getAuthorizationResponseMatcher());
}
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> getAuthorizationCodeTokenExchanger(H http) {
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> getAuthorizationCodeTokenExchanger() {
if (this.authorizationCodeTokenExchanger == null) {
NimbusAuthorizationCodeTokenExchanger nimbusAuthorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();
HttpClientConfig httpClientConfig = this.getHttpClientConfig(http);
if (httpClientConfig != null) {
nimbusAuthorizationCodeTokenExchanger.setHttpClientConfig(httpClientConfig);
}
this.authorizationCodeTokenExchanger = nimbusAuthorizationCodeTokenExchanger;
this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();
}
return this.authorizationCodeTokenExchanger;
}
@ -179,11 +171,10 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
return this.accessTokenRepository;
}
private ProviderJwtDecoderRegistry getProviderJwtDecoderRegistry(H http) {
HttpClientConfig httpClientConfig = this.getHttpClientConfig(http);
private ProviderJwtDecoderRegistry getProviderJwtDecoderRegistry() {
Map<ProviderMetadata, JwtDecoder> jwtDecoders = new HashMap<>();
ClientRegistrationRepository clientRegistrationRepository = OAuth2LoginConfigurer.getClientRegistrationRepository(this.getBuilder());
clientRegistrationRepository.getRegistrations().stream().forEach(registration -> {
clientRegistrationRepository.getRegistrations().forEach(registration -> {
ClientRegistration.ProviderDetails providerDetails = registration.getProviderDetails();
if (StringUtils.hasText(providerDetails.getJwkSetUri())) {
DefaultProviderMetadata providerMetadata = new DefaultProviderMetadata();
@ -198,15 +189,15 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
providerMetadata.setTokenEndpoint(this.toURL(providerDetails.getTokenUri()));
providerMetadata.setUserInfoEndpoint(this.toURL(providerDetails.getUserInfoUri()));
providerMetadata.setJwkSetUri(this.toURL(providerDetails.getJwkSetUri()));
NimbusJwtDecoderJwkSupport nimbusJwtDecoderJwkSupport = new NimbusJwtDecoderJwkSupport(
providerDetails.getJwkSetUri(), JwsAlgorithm.RS256, httpClientConfig);
NimbusJwtDecoderJwkSupport nimbusJwtDecoderJwkSupport =
new NimbusJwtDecoderJwkSupport(providerDetails.getJwkSetUri());
jwtDecoders.put(providerMetadata, nimbusJwtDecoderJwkSupport);
}
});
return new DefaultProviderJwtDecoderRegistry(jwtDecoders);
}
private OAuth2UserService getUserInfoService(H http) {
private OAuth2UserService getUserInfoService() {
if (this.userInfoService == null) {
NimbusOAuth2UserService nimbusOAuth2UserService = new NimbusOAuth2UserService();
if (!this.customUserTypes.isEmpty()) {
@ -215,21 +206,11 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
if (!this.userNameAttributeNames.isEmpty()) {
nimbusOAuth2UserService.setUserNameAttributeNames(this.userNameAttributeNames);
}
HttpClientConfig httpClientConfig = this.getHttpClientConfig(http);
if (httpClientConfig != null) {
nimbusOAuth2UserService.setHttpClientConfig(httpClientConfig);
}
this.userInfoService = nimbusOAuth2UserService;
}
return this.userInfoService;
}
private HttpClientConfig getHttpClientConfig(H http) {
Map<String, HttpClientConfig> httpClientConfigs =
http.getSharedObject(ApplicationContext.class).getBeansOfType(HttpClientConfig.class);
return (!httpClientConfigs.isEmpty() ? httpClientConfigs.values().iterator().next() : null);
}
private URL toURL(String urlStr) {
if (!StringUtils.hasText(urlStr)) {
return null;

View File

@ -32,7 +32,6 @@ import org.springframework.security.jose.jws.JwsAlgorithm;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtDecoder;
import org.springframework.security.jwt.JwtException;
import org.springframework.security.oauth2.core.http.HttpClientConfig;
import org.springframework.util.Assert;
import java.net.MalformedURLException;
@ -68,10 +67,6 @@ public class NimbusJwtDecoderJwkSupport implements JwtDecoder {
}
public NimbusJwtDecoderJwkSupport(String jwkSetUrl, String jwsAlgorithm) {
this(jwkSetUrl, jwsAlgorithm, null);
}
public NimbusJwtDecoderJwkSupport(String jwkSetUrl, String jwsAlgorithm, HttpClientConfig httpClientConfig) {
Assert.hasText(jwkSetUrl, "jwkSetUrl cannot be empty");
Assert.hasText(jwsAlgorithm, "jwsAlgorithm cannot be empty");
try {
@ -81,11 +76,7 @@ public class NimbusJwtDecoderJwkSupport implements JwtDecoder {
}
this.jwsAlgorithm = JWSAlgorithm.parse(jwsAlgorithm);
int connectTimeout = (httpClientConfig != null ?
httpClientConfig.getConnectTimeout() : HttpClientConfig.DEFAULT_CONNECT_TIMEOUT);
int readTimeout = (httpClientConfig != null ?
httpClientConfig.getReadTimeout() : HttpClientConfig.DEFAULT_READ_TIMEOUT);
ResourceRetriever jwkSetRetriever = new DefaultResourceRetriever(connectTimeout, readTimeout);
ResourceRetriever jwkSetRetriever = new DefaultResourceRetriever(30000, 30000);
JWKSource jwkSource = new RemoteJWKSet(this.jwkSetUrl, jwkSetRetriever);
JWSKeySelector<SecurityContext> jwsKeySelector =
new JWSVerificationKeySelector<SecurityContext>(this.jwsAlgorithm, jwkSource);

View File

@ -16,7 +16,15 @@
package org.springframework.security.oauth2.client.authentication.nimbus;
import com.nimbusds.oauth2.sdk.*;
import com.nimbusds.oauth2.sdk.AccessTokenResponse;
import com.nimbusds.oauth2.sdk.AuthorizationCode;
import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
import com.nimbusds.oauth2.sdk.AuthorizationGrant;
import com.nimbusds.oauth2.sdk.ErrorObject;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.TokenErrorResponse;
import com.nimbusds.oauth2.sdk.TokenRequest;
import com.nimbusds.oauth2.sdk.TokenResponse;
import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
import com.nimbusds.oauth2.sdk.auth.ClientSecretPost;
@ -28,13 +36,11 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.http.HttpClientConfig;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AccessToken;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.TokenResponseAttributes;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
@ -63,7 +69,6 @@ import java.util.stream.Collectors;
*/
public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> {
private static final String INVALID_TOKEN_RESPONSE_ERROR_CODE = "invalid_token_response";
private HttpClientConfig httpClientConfig = new HttpClientConfig();
@Override
public TokenResponseAttributes exchange(AuthorizationCodeAuthenticationToken authorizationCodeAuthenticationToken)
@ -93,8 +98,8 @@ public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrant
TokenRequest tokenRequest = new TokenRequest(tokenUri, clientAuthentication, authorizationCodeGrant);
HTTPRequest httpRequest = tokenRequest.toHTTPRequest();
httpRequest.setAccept(MediaType.APPLICATION_JSON_VALUE);
httpRequest.setConnectTimeout(this.httpClientConfig.getConnectTimeout());
httpRequest.setReadTimeout(this.httpClientConfig.getReadTimeout());
httpRequest.setConnectTimeout(30000);
httpRequest.setReadTimeout(30000);
tokenResponse = TokenResponse.parse(httpRequest.send());
} catch (ParseException pe) {
// This error occurs if the Access Token Response is not well-formed,
@ -137,11 +142,6 @@ public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrant
.build();
}
public final void setHttpClientConfig(HttpClientConfig httpClientConfig) {
Assert.notNull(httpClientConfig, "httpClientConfig cannot be null");
this.httpClientConfig = httpClientConfig;
}
private URI toURI(String uriStr) {
try {
return new URI(uriStr);

View File

@ -24,14 +24,12 @@ import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse;
import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.http.HttpClientConfig;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.user.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2Error;
@ -46,7 +44,11 @@ import org.springframework.util.Assert;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* An implementation of an {@link OAuth2UserService} that uses the <b>Nimbus OAuth 2.0 SDK</b> internally.
@ -73,7 +75,6 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
private Map<URI, String> userNameAttributeNames = Collections.unmodifiableMap(Collections.emptyMap());
private Map<URI, Class<? extends OAuth2User>> customUserTypes = Collections.unmodifiableMap(Collections.emptyMap());
private HttpClientConfig httpClientConfig = new HttpClientConfig();
public NimbusOAuth2UserService() {
}
@ -152,8 +153,8 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
UserInfoRequest userInfoRequest = new UserInfoRequest(userInfoUri, accessToken);
HTTPRequest httpRequest = userInfoRequest.toHTTPRequest();
httpRequest.setConnectTimeout(this.httpClientConfig.getConnectTimeout());
httpRequest.setReadTimeout(this.httpClientConfig.getReadTimeout());
httpRequest.setConnectTimeout(30000);
httpRequest.setReadTimeout(30000);
HTTPResponse httpResponse;
try {
@ -218,11 +219,6 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
this.customUserTypes = Collections.unmodifiableMap(new HashMap<>(customUserTypes));
}
public final void setHttpClientConfig(HttpClientConfig httpClientConfig) {
Assert.notNull(httpClientConfig, "httpClientConfig cannot be null");
this.httpClientConfig = httpClientConfig;
}
private URI getUserInfoUri(OAuth2AuthenticationToken token) {
ClientRegistration clientRegistration = token.getClientRegistration();
try {

View File

@ -1,89 +0,0 @@
/*
* Copyright 2012-2017 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
*
* http://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.core.http;
import org.springframework.util.Assert;
/**
* This class provides the capability for configuring the underlying HTTP client.
*
* <p>
* To customize the configuration of the underlying HTTP client, create/configure
* an instance of {@link HttpClientConfig} and register it with the <code>ApplicationContext</code>.
*
* <p>
* For example:
*
* <pre>
* &#064;Bean
* public HttpClientConfig httpClientConfig() {
* HttpClientConfig httpClientConfig = new HttpClientConfig();
* httpClientConfig.setConnectTimeout(60000);
* httpClientConfig.setReadTimeout(60000);
* return httpClientConfig;
* }
* </pre>
*
* @author Joe Grandja
* @since 5.0
*/
public class HttpClientConfig {
public static final int DEFAULT_CONNECT_TIMEOUT = 30000;
public static final int DEFAULT_READ_TIMEOUT = 30000;
private int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
private int readTimeout = DEFAULT_READ_TIMEOUT;
/**
* Returns the timeout in milliseconds until a connection is established.
*
* @return the connect timeout value in milliseconds
*/
public int getConnectTimeout() {
return this.connectTimeout;
}
/**
* Sets the timeout in milliseconds until a connection is established.
* A timeout value of 0 implies the option is disabled (timeout of infinity).
*
* @param connectTimeout the connect timeout value in milliseconds
*/
public void setConnectTimeout(int connectTimeout) {
Assert.isTrue(connectTimeout >= 0, "connectTimeout cannot be negative");
this.connectTimeout = connectTimeout;
}
/**
* Returns the timeout in milliseconds for inactivity when reading from the <code>InputStream</code>.
*
* @return the read timeout value in milliseconds
*/
public int getReadTimeout() {
return this.readTimeout;
}
/**
* Sets the timeout in milliseconds for inactivity when reading from the <code>InputStream</code>.
* A timeout value of 0 implies the option is disabled (timeout of infinity).
*
* @param readTimeout the read timeout value in milliseconds
*/
public void setReadTimeout(int readTimeout) {
Assert.isTrue(readTimeout >= 0, "readTimeout cannot be negative");
this.readTimeout = readTimeout;
}
}