pull/5980/head
Phillip Webb 9 years ago
parent 46134b58b8
commit 00fbb5c3d9

@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.security.oauth2.client;
import java.util.Collections; import java.util.Collections;
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoRestTemplateConfiguration; import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoRestTemplateFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -84,7 +84,7 @@ class SsoSecurityConfigurer {
private OAuth2ClientAuthenticationProcessingFilter oauth2SsoFilter( private OAuth2ClientAuthenticationProcessingFilter oauth2SsoFilter(
OAuth2SsoProperties sso) { OAuth2SsoProperties sso) {
OAuth2RestOperations restTemplate = this.applicationContext OAuth2RestOperations restTemplate = this.applicationContext
.getBean(UserInfoRestTemplateConfiguration.class).userInfoRestTemplate(); .getBean(UserInfoRestTemplateFactory.class).getUserInfoRestTemplate();
ResourceServerTokenServices tokenServices = this.applicationContext ResourceServerTokenServices tokenServices = this.applicationContext
.getBean(ResourceServerTokenServices.class); .getBean(ResourceServerTokenServices.class);
OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter( OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(

@ -36,7 +36,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
@ -49,6 +48,7 @@ import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.crypto.codec.Base64; import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest; import org.springframework.security.oauth2.client.token.AccessTokenRequest;
@ -76,12 +76,21 @@ import org.springframework.web.client.RestTemplate;
*/ */
@Configuration @Configuration
@ConditionalOnMissingBean(AuthorizationServerEndpointsConfiguration.class) @ConditionalOnMissingBean(AuthorizationServerEndpointsConfiguration.class)
@Import(UserInfoRestTemplateConfiguration.class)
public class ResourceServerTokenServicesConfiguration { public class ResourceServerTokenServicesConfiguration {
private static final Log logger = LogFactory private static final Log logger = LogFactory
.getLog(ResourceServerTokenServicesConfiguration.class); .getLog(ResourceServerTokenServicesConfiguration.class);
@Bean
@ConditionalOnMissingBean
public UserInfoRestTemplateFactory userInfoRestTemplateFactory(
ObjectProvider<List<UserInfoRestTemplateCustomizer>> customizersProvider,
ObjectProvider<OAuth2ProtectedResourceDetails> detailsProvider,
ObjectProvider<OAuth2ClientContext> oauth2ClientContextProvider) {
return new UserInfoRestTemplateFactory(customizersProvider, detailsProvider,
oauth2ClientContextProvider);
}
@Configuration @Configuration
@Conditional(NotJwtTokenCondition.class) @Conditional(NotJwtTokenCondition.class)
protected static class RemoteTokenServicesConfiguration { protected static class RemoteTokenServicesConfiguration {
@ -122,11 +131,11 @@ public class ResourceServerTokenServicesConfiguration {
public SocialTokenServicesConfiguration(ResourceServerProperties sso, public SocialTokenServicesConfiguration(ResourceServerProperties sso,
ObjectProvider<OAuth2ConnectionFactory<?>> connectionFactoryProvider, ObjectProvider<OAuth2ConnectionFactory<?>> connectionFactoryProvider,
UserInfoRestTemplateConfiguration restTemplateProvider, UserInfoRestTemplateFactory restTemplateFactory,
ObjectProvider<AuthoritiesExtractor> authoritiesExtractorProvider) { ObjectProvider<AuthoritiesExtractor> authoritiesExtractorProvider) {
this.sso = sso; this.sso = sso;
this.connectionFactory = connectionFactoryProvider.getIfAvailable(); this.connectionFactory = connectionFactoryProvider.getIfAvailable();
this.restTemplate = restTemplateProvider.userInfoRestTemplate(); this.restTemplate = restTemplateFactory.getUserInfoRestTemplate();
this.authoritiesExtractor = authoritiesExtractorProvider.getIfAvailable(); this.authoritiesExtractor = authoritiesExtractorProvider.getIfAvailable();
} }
@ -166,10 +175,10 @@ public class ResourceServerTokenServicesConfiguration {
private final AuthoritiesExtractor authoritiesExtractor; private final AuthoritiesExtractor authoritiesExtractor;
public UserInfoTokenServicesConfiguration(ResourceServerProperties sso, public UserInfoTokenServicesConfiguration(ResourceServerProperties sso,
UserInfoRestTemplateConfiguration restTemplateProvider, UserInfoRestTemplateFactory restTemplateFactory,
ObjectProvider<AuthoritiesExtractor> authoritiesExtractorProvider) { ObjectProvider<AuthoritiesExtractor> authoritiesExtractorProvider) {
this.sso = sso; this.sso = sso;
this.restTemplate = restTemplateProvider.userInfoRestTemplate(); this.restTemplate = restTemplateFactory.getUserInfoRestTemplate();
this.authoritiesExtractor = authoritiesExtractorProvider.getIfAvailable(); this.authoritiesExtractor = authoritiesExtractorProvider.getIfAvailable();
} }

@ -31,22 +31,23 @@ import org.springframework.security.oauth2.client.token.grant.code.Authorization
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* Configuration acting as a factory for the rest template used for extracting user info * Factory used to create the rest template used for extracting user info during
* during authentication. * authentication.
* *
* @author Dave Syer * @author Dave Syer
* @since 1.4.0
*/ */
@Configuration @Configuration
public class UserInfoRestTemplateConfiguration { public class UserInfoRestTemplateFactory {
private static final AuthorizationCodeResourceDetails DEFAULT_RESOURCE_DETAILS = new AuthorizationCodeResourceDetails(); private static final AuthorizationCodeResourceDetails DEFAULT_RESOURCE_DETAILS;
static { static {
DEFAULT_RESOURCE_DETAILS.setClientId("<N/A>"); AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
DEFAULT_RESOURCE_DETAILS details.setClientId("<N/A>");
.setUserAuthorizationUri("Not a URI " + "because there is no client"); details.setUserAuthorizationUri("Not a URI because there is no client");
DEFAULT_RESOURCE_DETAILS details.setAccessTokenUri("Not a URI because there is no client");
.setAccessTokenUri("Not a URI " + "because there is no client"); DEFAULT_RESOURCE_DETAILS = details;
} }
private final List<UserInfoRestTemplateCustomizer> customizers; private final List<UserInfoRestTemplateCustomizer> customizers;
@ -57,7 +58,7 @@ public class UserInfoRestTemplateConfiguration {
private OAuth2RestTemplate template; private OAuth2RestTemplate template;
public UserInfoRestTemplateConfiguration( public UserInfoRestTemplateFactory(
ObjectProvider<List<UserInfoRestTemplateCustomizer>> customizersProvider, ObjectProvider<List<UserInfoRestTemplateCustomizer>> customizersProvider,
ObjectProvider<OAuth2ProtectedResourceDetails> detailsProvider, ObjectProvider<OAuth2ProtectedResourceDetails> detailsProvider,
ObjectProvider<OAuth2ClientContext> oauth2ClientContextProvider) { ObjectProvider<OAuth2ClientContext> oauth2ClientContextProvider) {
@ -66,8 +67,7 @@ public class UserInfoRestTemplateConfiguration {
this.oauth2ClientContext = oauth2ClientContextProvider.getIfAvailable(); this.oauth2ClientContext = oauth2ClientContextProvider.getIfAvailable();
} }
// Not a @Bean: use this method as a factory public OAuth2RestTemplate getUserInfoRestTemplate() {
public OAuth2RestTemplate userInfoRestTemplate() {
if (this.template == null) { if (this.template == null) {
this.template = getTemplate( this.template = getTemplate(
this.details == null ? DEFAULT_RESOURCE_DETAILS : this.details); this.details == null ? DEFAULT_RESOURCE_DETAILS : this.details);

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,8 +40,7 @@ public class GsonJsonParser implements JsonParser {
if (json != null) { if (json != null) {
json = json.trim(); json = json.trim();
if (json.startsWith("{")) { if (json.startsWith("{")) {
TypeToken<Map<String, Object>> type = new TypeToken<Map<String, Object>>() { }; return this.gson.fromJson(json, new MapTypeToken().getType());
return this.gson.fromJson(json, type.getType());
} }
} }
throw new IllegalArgumentException("Cannot parse JSON"); throw new IllegalArgumentException("Cannot parse JSON");
@ -52,11 +51,16 @@ public class GsonJsonParser implements JsonParser {
if (json != null) { if (json != null) {
json = json.trim(); json = json.trim();
if (json.startsWith("[")) { if (json.startsWith("[")) {
TypeToken<List<Object>> type = new TypeToken<List<Object>>() { }; TypeToken<List<Object>> type = new TypeToken<List<Object>>() {
};
return this.gson.fromJson(json, type.getType()); return this.gson.fromJson(json, type.getType());
} }
} }
throw new IllegalArgumentException("Cannot parse JSON"); throw new IllegalArgumentException("Cannot parse JSON");
} }
private static final class MapTypeToken extends TypeToken<Map<String, Object>> {
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,8 +33,7 @@ public class JacksonJsonParser implements JsonParser {
@Override @Override
public Map<String, Object> parseMap(String json) { public Map<String, Object> parseMap(String json) {
try { try {
TypeReference<Map<String, Object>> type = new TypeReference<Map<String, Object>>() { }; return new ObjectMapper().readValue(json, new MapTypeReference());
return new ObjectMapper().readValue(json, type);
} }
catch (Exception ex) { catch (Exception ex) {
throw new IllegalArgumentException("Cannot parse JSON", ex); throw new IllegalArgumentException("Cannot parse JSON", ex);
@ -44,7 +43,8 @@ public class JacksonJsonParser implements JsonParser {
@Override @Override
public List<Object> parseList(String json) { public List<Object> parseList(String json) {
try { try {
TypeReference<List<Object>> type = new TypeReference<List<Object>>() { }; TypeReference<List<Object>> type = new TypeReference<List<Object>>() {
};
return new ObjectMapper().readValue(json, type); return new ObjectMapper().readValue(json, type);
} }
catch (Exception ex) { catch (Exception ex) {
@ -52,4 +52,8 @@ public class JacksonJsonParser implements JsonParser {
} }
} }
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
};
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,11 +17,11 @@
package org.springframework.boot.json; package org.springframework.boot.json;
/** /**
* Tests for {@link JsonParser}. * Tests for {@link JacksonJsonParser}.
* *
* @author Dave Syer * @author Dave Syer
*/ */
public class JacksonParserTests extends AbstractJsonParserTests { public class JacksonJsonParserTests extends AbstractJsonParserTests {
@Override @Override
protected JsonParser getParser() { protected JsonParser getParser() {
Loading…
Cancel
Save