From df81b3145f8e0986b4100d43bfd04de53033af79 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 19 Feb 2015 11:21:28 +0000 Subject: [PATCH] Backport to 1.1.x the fix for gh-2474 (originally made in e42fa79f7) --- .../AuthenticationManagerConfiguration.java | 106 ++++-------------- 1 file changed, 24 insertions(+), 82 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 08b01c2261..ff71eb5dcb 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 @@ -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. @@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; @@ -40,9 +41,8 @@ import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.annotation.ObjectPostProcessor; 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.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Component; /** @@ -60,16 +60,7 @@ import org.springframework.stereotype.Component; @ConditionalOnBean(ObjectPostProcessor.class) @ConditionalOnMissingBean({ AuthenticationManager.class }) @Order(0) -public class AuthenticationManagerConfiguration extends - GlobalAuthenticationConfigurerAdapter { - - /* - * Yes, this class is a GlobalAuthenticationConfigurerAdapter, even though none of - * those methods are overridden: we want Spring Security to instantiate us early, so - * we can in turn force the SecurityPrequisites to be instantiated. This will prevent - * ordering issues between Spring Boot modules when they need to influence the default - * security configuration. - */ +public class AuthenticationManagerConfiguration { private static Log logger = LogFactory .getLog(AuthenticationManagerConfiguration.class); @@ -77,35 +68,17 @@ public class AuthenticationManagerConfiguration extends @Autowired private List dependencies; - @Autowired - private SecurityProperties security; - - @Autowired - private ObjectPostProcessor objectPostProcessor; - @Bean @Primary - public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth, - ApplicationContext context) throws Exception { - - if (isAuthenticationManagerAlreadyConfigured(context)) { - return new LazyAuthenticationManager(auth); - } - - /* - * This AuthenticationManagerBuilder is for the global AuthenticationManager - */ - BootDefaultingAuthenticationConfigurerAdapter configurer = new BootDefaultingAuthenticationConfigurerAdapter(); - configurer.configure(auth); - AuthenticationManager manager = configurer.getAuthenticationManagerBuilder() - .getOrBuild(); - configurer.configureParent(auth); - return manager; - + public AuthenticationManager authenticationManager(AuthenticationConfiguration auth) + throws Exception { + return auth.getAuthenticationManager(); } - private boolean isAuthenticationManagerAlreadyConfigured(ApplicationContext context) { - return context.getBeanNamesForType(GlobalAuthenticationConfigurerAdapter.class).length > 2; + @Bean + public static BootDefaultingAuthenticationConfigurerAdapter bootDefaultingAuthenticationConfigurerAdapter( + SecurityProperties security, List dependencies) { + return new BootDefaultingAuthenticationConfigurerAdapter(security); } @Component @@ -152,64 +125,33 @@ public class AuthenticationManagerConfiguration extends * methods are invoked before configure, which cannot be guaranteed at this point. * */ - private class BootDefaultingAuthenticationConfigurerAdapter { - - private AuthenticationManagerBuilder defaultAuth; - - private AuthenticationManager parent; - - public void configureParent(AuthenticationManagerBuilder auth) { - if (!auth.isConfigured() && this.parent != null) { - auth.parentAuthenticationManager(this.parent); - } - } + @Order(Ordered.LOWEST_PRECEDENCE - 100) + private static class BootDefaultingAuthenticationConfigurerAdapter extends + GlobalAuthenticationConfigurerAdapter { + private final SecurityProperties security; - public AuthenticationManagerBuilder getAuthenticationManagerBuilder() { - return this.defaultAuth; + @Autowired + public BootDefaultingAuthenticationConfigurerAdapter(SecurityProperties security) { + this.security = security; } - public void configure(AuthenticationManagerBuilder auth) throws Exception { + @Override + public void init(AuthenticationManagerBuilder auth) throws Exception { if (auth.isConfigured()) { - this.defaultAuth = auth; return; } - User user = AuthenticationManagerConfiguration.this.security.getUser(); + User user = this.security.getUser(); if (user.isDefaultPassword()) { logger.info("\n\nUsing default security password: " + user.getPassword() + "\n\n"); } - this.defaultAuth = new AuthenticationManagerBuilder( - AuthenticationManagerConfiguration.this.objectPostProcessor); - Set roles = new LinkedHashSet(user.getRole()); - - this.parent = this.defaultAuth.inMemoryAuthentication() - .withUser(user.getName()).password(user.getPassword()) - .roles(roles.toArray(new String[roles.size()])).and().and().build(); - - // Defer actually setting the parent on the AuthenticationManagerBuilder - // because it makes it "configured" and we are only in the init() phase - // here. - + auth.inMemoryAuthentication().withUser(user.getName()) + .password(user.getPassword()) + .roles(roles.toArray(new String[roles.size()])); } } - private static class LazyAuthenticationManager implements AuthenticationManager { - - private AuthenticationManagerBuilder builder; - - public LazyAuthenticationManager(AuthenticationManagerBuilder builder) { - this.builder = builder; - } - - @Override - public Authentication authenticate(Authentication authentication) - throws AuthenticationException { - return this.builder.getOrBuild().authenticate(authentication); - } - - } - }