Commit 1c0bcc13 authored by Dave Syer's avatar Dave Syer

Set UserDetailsService in default AuthenticationManagerBuilder

Only affects the default AuthenticationManagerBuilder (so when users
are not overriding the default global user details). Makes the
UserDetailsService effectively available as it would be if we used
AuthenticationManagerBuilder.inMemoryAuthentication() as a
shared object in the HttpSecurity.

Fixes gh-3152
parent c7103bf2
......@@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.security;
import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
......@@ -46,6 +47,7 @@ import org.springframework.security.config.annotation.authentication.configurati
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
/**
* Configuration for a Spring Security in-memory {@link AuthenticationManager}. Can be
......@@ -171,9 +173,21 @@ public class AuthenticationManagerConfiguration {
Set<String> roles = new LinkedHashSet<String>(user.getRole());
withUser(user.getName()).password(user.getPassword()).roles(
roles.toArray(new String[roles.size()]));
setField(auth, "defaultUserDetailsService", getUserDetailsService());
super.configure(auth);
}
private void setField(Object target, String name, Object value) {
try {
Field field = ReflectionUtils.findField(target.getClass(), name);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, target, value);
}
catch (Exception e) {
logger.info("Could not set " + name);
}
}
}
/**
......
......@@ -49,6 +49,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
......@@ -190,6 +191,19 @@ public class SecurityAutoConfigurationTests {
this.context.getBean(AuthenticationManager.class));
}
@Test
public void testDefaultAuthenticationManagerMakesUserDetailsAvailable()
throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(UserDetailsSecurityCustomizer.class,
SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(UserDetailsSecurityCustomizer.class)
.getUserDetails().loadUserByUsername("user"));
}
@Test
public void testOverrideAuthenticationManagerAndInjectIntoSecurityFilter()
throws Exception {
......@@ -380,4 +394,21 @@ public class SecurityAutoConfigurationTests {
}
@Configuration
protected static class UserDetailsSecurityCustomizer extends
WebSecurityConfigurerAdapter {
private UserDetailsService userDetails;
@Override
protected void configure(HttpSecurity http) throws Exception {
this.userDetails = http.getSharedObject(UserDetailsService.class);
}
public UserDetailsService getUserDetails() {
return this.userDetails;
}
}
}
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