From 1c0bcc13cfa3aa00a8fea96e2ecb2e1867859a96 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 8 Jun 2015 13:14:12 +0100 Subject: [PATCH] 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 --- .../AuthenticationManagerConfiguration.java | 14 +++++++++ .../SecurityAutoConfigurationTests.java | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java index 45c2b846e8e..059ffa9e0eb 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java @@ -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 roles = new LinkedHashSet(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); + } + } + } /** diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java index f743f6da58c..77375b2d96d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java @@ -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; + } + + } + }