From 760d6eceee9260e6dc065a4556a064d805da81bf Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Mon, 2 Mar 2015 14:45:50 -0600 Subject: [PATCH] Fix Unnecessarily Adding Default Security User Fixes gh-2567 --- .../AuthenticationManagerConfiguration.java | 62 +++++++++++++++---- .../SecurityAutoConfigurationTests.java | 57 ++++++++++++++++- 2 files changed, 106 insertions(+), 13 deletions(-) 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 ff71eb5dcb0..16d794f13e3 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 @@ -43,6 +43,7 @@ import org.springframework.security.config.annotation.SecurityConfigurer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; +import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer; import org.springframework.stereotype.Component; /** @@ -137,21 +138,58 @@ public class AuthenticationManagerConfiguration { @Override public void init(AuthenticationManagerBuilder auth) throws Exception { - if (auth.isConfigured()) { - return; + auth.apply(new DefaultingInMemoryUserDetailsManagerConfigurer(this.security)); + } + + /** + * This is necessary to delay adding the default user. + * + * + * + * @author Rob Winch + */ + private static class DefaultingInMemoryUserDetailsManagerConfigurer extends + InMemoryUserDetailsManagerConfigurer { + private final SecurityProperties security; + + public DefaultingInMemoryUserDetailsManagerConfigurer( + SecurityProperties security) { + this.security = security; } - User user = this.security.getUser(); - if (user.isDefaultPassword()) { - logger.info("\n\nUsing default security password: " + user.getPassword() - + "\n\n"); + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + if (auth.isConfigured()) { + return; + } + + User user = this.security.getUser(); + if (user.isDefaultPassword()) { + logger.info("\n\nUsing default security password: " + + user.getPassword() + "\n"); + } + + Set roles = new LinkedHashSet(user.getRole()); + withUser(user.getName()).password(user.getPassword()).roles( + roles.toArray(new String[roles.size()])); + + super.configure(auth); } - Set roles = new LinkedHashSet(user.getRole()); - auth.inMemoryAuthentication().withUser(user.getName()) - .password(user.getPassword()) - .roles(roles.toArray(new String[roles.size()])); } } - -} +} \ No newline at end of file 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 ed2b18a7117..89c4ad4c538 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.event.AbstractAuthenticationEvent; import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; @@ -226,6 +227,60 @@ public class SecurityAutoConfigurationTests { assertNotNull(this.context.getBean(JpaTransactionManager.class)); } + @Test + public void testDefaultUsernamePassword() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + + this.context.register(SecurityAutoConfiguration.class, + ServerPropertiesAutoConfiguration.class); + this.context.refresh(); + + SecurityProperties security = this.context.getBean(SecurityProperties.class); + AuthenticationManager manager = this.context.getBean(AuthenticationManager.class); + + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( + security.getUser().getName(), security.getUser().getPassword()); + assertNotNull(manager.authenticate(token)); + } + + @Test + public void testCustomAuthenticationDoesNotAuthenticateWithBootSecurityUser() + throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + + this.context.register(AuthenticationManagerCustomizer.class, + SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class); + this.context.refresh(); + + SecurityProperties security = this.context.getBean(SecurityProperties.class); + AuthenticationManager manager = this.context.getBean(AuthenticationManager.class); + + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( + security.getUser().getName(), security.getUser().getPassword()); + try { + manager.authenticate(token); + fail("Expected Exception"); + } + catch (AuthenticationException success) { + } + + token = new UsernamePasswordAuthenticationToken("foo", "bar"); + assertNotNull(manager.authenticate(token)); + } + + private static final class AuthenticationListener implements + ApplicationListener { + + private ApplicationEvent event; + + @Override + public void onApplicationEvent(AbstractAuthenticationEvent event) { + this.event = event; + } + } + @Configuration @TestAutoConfigurationPackage(City.class) protected static class EntityConfiguration {