mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Fix tests
Some assumptions were being made in tests, e.g. about there being an AuthenticationManager @Bean, which were false with the new Security 3.2.1 updates from Rob. Also parent-child contexts with the actuator were problematic because they didn't exclude the web configuration for the management security in the parent context. Fixes gh-244
This commit is contained in:
parent
6b0eba3759
commit
b0b7bc0e7f
@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityPrequisite;
|
||||
@ -43,12 +44,12 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity.IgnoredRequestConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||
@ -145,10 +146,17 @@ public class ManagementSecurityAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("${management.security.enabled:true} && !${security.basic.enabled:true}")
|
||||
@ConditionalOnMissingBean(WebSecurityConfiguration.class)
|
||||
@EnableWebSecurity
|
||||
protected static class WebSecurityEnabler extends AuthenticationManagerConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean({ ManagementWebSecurityConfigurerAdapter.class })
|
||||
@ConditionalOnExpression("${management.security.enabled:true}")
|
||||
@EnableWebSecurity
|
||||
@ConditionalOnWebApplication
|
||||
// Give user-supplied filters a chance to be last in line
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 10)
|
||||
protected static class ManagementWebSecurityConfigurerAdapter extends
|
||||
@ -198,13 +206,6 @@ public class ManagementSecurityAutoConfiguration {
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(AuthenticationManager.class)
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 4)
|
||||
protected static class ManagementAuthenticationManagerConfiguration extends
|
||||
AuthenticationManagerConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String[] getEndpointPaths(
|
||||
|
@ -98,8 +98,8 @@ public class ManagementSecurityAutoConfigurationTests {
|
||||
|
||||
private UserDetails getUser() {
|
||||
ProviderManager manager = this.context.getBean(ProviderManager.class);
|
||||
ProviderManager parent = (ProviderManager) ReflectionTestUtils.getField(
|
||||
manager, "parent");
|
||||
ProviderManager parent = (ProviderManager) ReflectionTestUtils.getField(manager,
|
||||
"parent");
|
||||
DaoAuthenticationProvider provider = (DaoAuthenticationProvider) parent
|
||||
.getProviders().get(0);
|
||||
UserDetailsService service = (UserDetailsService) ReflectionTestUtils.getField(
|
||||
@ -159,7 +159,7 @@ public class ManagementSecurityAutoConfigurationTests {
|
||||
public void testSecurityPropertiesNotAvailable() throws Exception {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
this.context.register(TestConfiguration.class,
|
||||
this.context.register(TestConfiguration.class, SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class,
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
|
@ -19,8 +19,6 @@ package org.springframework.boot.actuate.autoconfigure;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
@ -61,9 +59,8 @@ public class SpringApplicationHierarchyTests {
|
||||
public static class Child {
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = { ServerPropertiesAutoConfiguration.class,
|
||||
JolokiaAutoConfiguration.class, EndpointMBeanExportAutoConfiguration.class,
|
||||
SecurityAutoConfiguration.class })
|
||||
@EnableAutoConfiguration(exclude = { JolokiaAutoConfiguration.class,
|
||||
EndpointMBeanExportAutoConfiguration.class })
|
||||
public static class Parent {
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -45,11 +44,12 @@ import org.springframework.security.config.annotation.authentication.configurers
|
||||
@Configuration
|
||||
@ConditionalOnBean(ObjectPostProcessor.class)
|
||||
@ConditionalOnMissingBean(AuthenticationManager.class)
|
||||
@ConditionalOnWebApplication
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 3)
|
||||
public class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter {
|
||||
public class AuthenticationManagerConfiguration extends
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
|
||||
private static Log logger = LogFactory.getLog(AuthenticationManagerConfiguration.class);
|
||||
private static Log logger = LogFactory
|
||||
.getLog(AuthenticationManagerConfiguration.class);
|
||||
|
||||
@Autowired
|
||||
private List<SecurityPrequisite> dependencies;
|
||||
@ -60,41 +60,41 @@ public class AuthenticationManagerConfiguration extends GlobalAuthenticationConf
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Override
|
||||
public void init(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.apply(new BootDefaultingAuthenticationConfigurerAdapter());
|
||||
}
|
||||
|
||||
/**
|
||||
* We must add {@link BootDefaultingAuthenticationConfigurerAdapter} in the
|
||||
* init phase of the last {@link GlobalAuthenticationConfigurerAdapter}. The
|
||||
* reason is that the typical flow is something like:
|
||||
*
|
||||
* We must add {@link BootDefaultingAuthenticationConfigurerAdapter} in the init phase
|
||||
* of the last {@link GlobalAuthenticationConfigurerAdapter}. The reason is that the
|
||||
* typical flow is something like:
|
||||
*
|
||||
* <ul>
|
||||
* <li>A
|
||||
* {@link GlobalAuthenticationConfigurerAdapter#init(AuthenticationManagerBuilder)}
|
||||
* exists that adds a {@link SecurityConfigurer} to the
|
||||
* {@link AuthenticationManagerBuilder}</li>
|
||||
* <li>
|
||||
* {@link AuthenticationManagerConfiguration#init(AuthenticationManagerBuilder)}
|
||||
* adds BootDefaultingAuthenticationConfigurerAdapter so it is after the
|
||||
* {@link AuthenticationManagerConfiguration#init(AuthenticationManagerBuilder)} adds
|
||||
* BootDefaultingAuthenticationConfigurerAdapter so it is after the
|
||||
* {@link SecurityConfigurer} in the first step</li>
|
||||
* <li>We then can default an {@link AuthenticationProvider} if necessary.
|
||||
* Note we can only invoke the
|
||||
* <li>We then can default an {@link AuthenticationProvider} if necessary. Note we can
|
||||
* only invoke the
|
||||
* {@link AuthenticationManagerBuilder#authenticationProvider(AuthenticationProvider)}
|
||||
* method since all other methods add a {@link SecurityConfigurer} which is
|
||||
* not allowed in the configure stage. It is not allowed because we
|
||||
* guarantee all init methods are invoked before configure, which cannot be
|
||||
* guaranteed at this point.</li>
|
||||
* method since all other methods add a {@link SecurityConfigurer} which is not
|
||||
* allowed in the configure stage. It is not allowed because we guarantee all init
|
||||
* methods are invoked before configure, which cannot be guaranteed at this point.</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
private class BootDefaultingAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
|
||||
private class BootDefaultingAuthenticationConfigurerAdapter extends
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void configure(AuthenticationManagerBuilder auth)
|
||||
throws Exception {
|
||||
if(auth.isConfigured()) {
|
||||
public void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
if (auth.isConfigured()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,18 +104,14 @@ public class AuthenticationManagerConfiguration extends GlobalAuthenticationConf
|
||||
+ user.getPassword() + "\n\n");
|
||||
}
|
||||
|
||||
AuthenticationManagerBuilder defaultAuth = new AuthenticationManagerBuilder(objectPostProcessor);
|
||||
AuthenticationManagerBuilder defaultAuth = new AuthenticationManagerBuilder(
|
||||
AuthenticationManagerConfiguration.this.objectPostProcessor);
|
||||
|
||||
Set<String> roles = new LinkedHashSet<String>(user.getRole());
|
||||
|
||||
AuthenticationManager parent = defaultAuth.
|
||||
inMemoryAuthentication()
|
||||
.withUser(user.getName())
|
||||
.password(user.getPassword())
|
||||
.roles(roles.toArray(new String[roles.size()]))
|
||||
.and()
|
||||
.and()
|
||||
.build();
|
||||
AuthenticationManager parent = defaultAuth.inMemoryAuthentication()
|
||||
.withUser(user.getName()).password(user.getPassword())
|
||||
.roles(roles.toArray(new String[roles.size()])).and().and().build();
|
||||
|
||||
auth.parentAuthenticationManager(parent);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package sample.secure;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -28,6 +30,7 @@ import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -35,8 +38,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import sample.secure.SampleSecureApplicationTests.TestConfiguration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Basic integration tests for demo application.
|
||||
*
|
||||
@ -58,7 +59,7 @@ public class SampleSecureApplicationTests {
|
||||
@Before
|
||||
public void init() {
|
||||
AuthenticationManager authenticationManager = context
|
||||
.getBean(AuthenticationManager.class);
|
||||
.getBean(AuthenticationManagerBuilder.class).getOrBuild();
|
||||
authentication = authenticationManager
|
||||
.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
|
||||
}
|
||||
@ -94,7 +95,6 @@ public class SampleSecureApplicationTests {
|
||||
@PropertySource("classpath:test.properties")
|
||||
@Configuration
|
||||
protected static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user