Commit da816526 authored by Dave Syer's avatar Dave Syer

Add additional pre-validation check in ResourceServerProperties

With this change a user can have `@EnableOAuth2Client` without
`@EnableOAuth2Sso`.

Fixes gh-3568
parent 6f6f8987
...@@ -165,12 +165,16 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { ...@@ -165,12 +165,16 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware {
@Override @Override
public void validate(Object target, Errors errors) { public void validate(Object target, Errors errors) {
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, if (countBeans(AuthorizationServerEndpointsConfiguration.class) > 0) {
AuthorizationServerEndpointsConfiguration.class).length > 0) {
// If we are an authorization server we don't need remote resource token // If we are an authorization server we don't need remote resource token
// services // services
return; 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; ResourceServerProperties resource = (ResourceServerProperties) target;
if (StringUtils.hasText(this.clientId)) { if (StringUtils.hasText(this.clientId)) {
if (!StringUtils.hasText(this.clientSecret)) { if (!StringUtils.hasText(this.clientSecret)) {
...@@ -197,6 +201,11 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { ...@@ -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 { public class Jwt {
/** /**
...@@ -235,7 +244,7 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware { ...@@ -235,7 +244,7 @@ public class ResourceServerProperties implements Validator, BeanFactoryAware {
} }
if (ResourceServerProperties.this.tokenInfoUri != null if (ResourceServerProperties.this.tokenInfoUri != null
&& ResourceServerProperties.this.tokenInfoUri && ResourceServerProperties.this.tokenInfoUri
.endsWith("/check_token")) { .endsWith("/check_token")) {
return ResourceServerProperties.this.userInfoUri.replace("/check_token", return ResourceServerProperties.this.userInfoUri.replace("/check_token",
"/token_key"); "/token_key");
} }
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
package org.springframework.boot.autoconfigure.security.oauth2; 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.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
...@@ -60,9 +63,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; ...@@ -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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
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.config.annotation.configurers.ClientDetailsServiceConfigurer; 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.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 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.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
...@@ -89,9 +94,6 @@ import org.springframework.web.client.RestTemplate; ...@@ -89,9 +94,6 @@ import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode; 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 * Verify Spring Security OAuth2 auto-configuration secures end points properly, accepts
* environmental overrides, and also backs off in the presence of other * environmental overrides, and also backs off in the presence of other
...@@ -159,6 +161,18 @@ public class OAuth2AutoConfigurationTests { ...@@ -159,6 +161,18 @@ public class OAuth2AutoConfigurationTests {
assertThat(countBeans(AUTHORIZATION_SERVER_CONFIG), equalTo(1)); 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 @Test
public void testDisablingAuthorizationServer() { public void testDisablingAuthorizationServer() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(); this.context = new AnnotationConfigEmbeddedWebApplicationContext();
...@@ -344,9 +358,9 @@ public class OAuth2AutoConfigurationTests { ...@@ -344,9 +358,9 @@ public class OAuth2AutoConfigurationTests {
@Configuration @Configuration
@Import({ UseFreePortEmbeddedContainerConfiguration.class, @Import({ UseFreePortEmbeddedContainerConfiguration.class,
SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, OAuth2AutoConfiguration.class, DispatcherServletAutoConfiguration.class, OAuth2AutoConfiguration.class,
WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class })
protected static class MinimalSecureWebApplication { protected static class MinimalSecureWebApplication {
} }
...@@ -372,12 +386,17 @@ public class OAuth2AutoConfigurationTests { ...@@ -372,12 +386,17 @@ public class OAuth2AutoConfigurationTests {
} }
@Configuration
@EnableOAuth2Client
protected static class ClientConfiguration extends TestSecurityConfiguration {
}
@Configuration @Configuration
@EnableAuthorizationServer @EnableAuthorizationServer
@EnableResourceServer @EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class AuthorizationAndResourceServerConfiguration extends protected static class AuthorizationAndResourceServerConfiguration extends
TestSecurityConfiguration { TestSecurityConfiguration {
} }
...@@ -400,7 +419,7 @@ public class OAuth2AutoConfigurationTests { ...@@ -400,7 +419,7 @@ public class OAuth2AutoConfigurationTests {
@Configuration @Configuration
@EnableAuthorizationServer @EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends protected static class AuthorizationServerConfiguration extends
TestSecurityConfiguration { TestSecurityConfiguration {
} }
...@@ -455,7 +474,7 @@ public class OAuth2AutoConfigurationTests { ...@@ -455,7 +474,7 @@ public class OAuth2AutoConfigurationTests {
@Override @Override
public void configure(HttpSecurity http) throws Exception { public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and() http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and()
.csrf().disable(); .csrf().disable();
} }
} }
...@@ -463,7 +482,7 @@ public class OAuth2AutoConfigurationTests { ...@@ -463,7 +482,7 @@ public class OAuth2AutoConfigurationTests {
@Configuration @Configuration
@EnableAuthorizationServer @EnableAuthorizationServer
protected static class CustomAuthorizationServer extends protected static class CustomAuthorizationServer extends
AuthorizationServerConfigurerAdapter { AuthorizationServerConfigurerAdapter {
@Autowired @Autowired
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
...@@ -483,9 +502,9 @@ public class OAuth2AutoConfigurationTests { ...@@ -483,9 +502,9 @@ public class OAuth2AutoConfigurationTests {
@Override @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception { public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("client").secret("secret") clients.inMemory().withClient("client").secret("secret")
.resourceIds("resource-id").authorizedGrantTypes("password") .resourceIds("resource-id").authorizedGrantTypes("password")
.authorities("USER").scopes("read") .authorities("USER").scopes("read")
.redirectUris("http://localhost:8080"); .redirectUris("http://localhost:8080");
} }
@Override @Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment