From da816526bd86afe354ed63ca201c0e0b62a53a53 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 21 Jul 2015 10:17:51 +0100 Subject: [PATCH] Add additional pre-validation check in ResourceServerProperties With this change a user can have `@EnableOAuth2Client` without `@EnableOAuth2Sso`. Fixes gh-3568 --- .../resource/ResourceServerProperties.java | 15 +++++-- .../oauth2/OAuth2AutoConfigurationTests.java | 45 +++++++++++++------ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerProperties.java index db97966379..97045d711b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerProperties.java @@ -165,12 +165,16 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { @Override public void validate(Object target, Errors errors) { - if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, - AuthorizationServerEndpointsConfiguration.class).length > 0) { + if (countBeans(AuthorizationServerEndpointsConfiguration.class) > 0) { // If we are an authorization server we don't need remote resource token // services return; } + if (countBeans(ResourceServerTokenServicesConfiguration.class) == 0) { + // If we are not a resource server or an SSO client we don't need remote + // resource token services + return; + } ResourceServerProperties resource = (ResourceServerProperties) target; if (StringUtils.hasText(this.clientId)) { if (!StringUtils.hasText(this.clientSecret)) { @@ -197,6 +201,11 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { } } + private int countBeans(Class type) { + return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, + type, true, false).length; + } + public class Jwt { /** @@ -235,7 +244,7 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { } if (ResourceServerProperties.this.tokenInfoUri != null && ResourceServerProperties.this.tokenInfoUri - .endsWith("/check_token")) { + .endsWith("/check_token")) { return ResourceServerProperties.this.userInfoUri.replace("/check_token", "/token_key"); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/OAuth2AutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/OAuth2AutoConfigurationTests.java index 9832940503..f4d0100937 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/OAuth2AutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/OAuth2AutoConfigurationTests.java @@ -16,6 +16,9 @@ package org.springframework.boot.autoconfigure.security.oauth2; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + import java.net.URI; import java.util.Arrays; import java.util.List; @@ -60,9 +63,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; @@ -89,9 +94,6 @@ import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.databind.JsonNode; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; - /** * Verify Spring Security OAuth2 auto-configuration secures end points properly, accepts * environmental overrides, and also backs off in the presence of other @@ -159,6 +161,18 @@ public class OAuth2AutoConfigurationTests { assertThat(countBeans(AUTHORIZATION_SERVER_CONFIG), equalTo(1)); } + @Test + public void testClientIsNotResourceServer() { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + this.context.register(ClientConfiguration.class, + MinimalSecureWebApplication.class); + this.context.refresh(); + assertThat(countBeans(RESOURCE_SERVER_CONFIG), equalTo(0)); + assertThat(countBeans(AUTHORIZATION_SERVER_CONFIG), equalTo(0)); + // Scoped target and proxy: + assertThat(countBeans(OAuth2ClientContext.class), equalTo(2)); + } + @Test public void testDisablingAuthorizationServer() { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); @@ -344,9 +358,9 @@ public class OAuth2AutoConfigurationTests { @Configuration @Import({ UseFreePortEmbeddedContainerConfiguration.class, - SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, OAuth2AutoConfiguration.class, - WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) + SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, + DispatcherServletAutoConfiguration.class, OAuth2AutoConfiguration.class, + WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) protected static class MinimalSecureWebApplication { } @@ -372,12 +386,17 @@ public class OAuth2AutoConfigurationTests { } + @Configuration + @EnableOAuth2Client + protected static class ClientConfiguration extends TestSecurityConfiguration { + } + @Configuration @EnableAuthorizationServer @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) protected static class AuthorizationAndResourceServerConfiguration extends - TestSecurityConfiguration { + TestSecurityConfiguration { } @@ -400,7 +419,7 @@ public class OAuth2AutoConfigurationTests { @Configuration @EnableAuthorizationServer protected static class AuthorizationServerConfiguration extends - TestSecurityConfiguration { + TestSecurityConfiguration { } @@ -455,7 +474,7 @@ public class OAuth2AutoConfigurationTests { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and() - .csrf().disable(); + .csrf().disable(); } } @@ -463,7 +482,7 @@ public class OAuth2AutoConfigurationTests { @Configuration @EnableAuthorizationServer protected static class CustomAuthorizationServer extends - AuthorizationServerConfigurerAdapter { + AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @@ -483,9 +502,9 @@ public class OAuth2AutoConfigurationTests { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("client").secret("secret") - .resourceIds("resource-id").authorizedGrantTypes("password") - .authorities("USER").scopes("read") - .redirectUris("http://localhost:8080"); + .resourceIds("resource-id").authorizedGrantTypes("password") + .authorities("USER").scopes("read") + .redirectUris("http://localhost:8080"); } @Override