|
26 | 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
27 | 27 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
28 | 28 | import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
|
| 29 | +import org.springframework.context.ApplicationContext; |
29 | 30 | import org.springframework.context.ApplicationListener;
|
30 | 31 | import org.springframework.context.annotation.Bean;
|
31 | 32 | import org.springframework.context.annotation.Configuration;
|
|
41 | 42 | import org.springframework.security.config.annotation.SecurityConfigurer;
|
42 | 43 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
43 | 44 | import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
|
| 45 | +import org.springframework.stereotype.Component; |
44 | 46 |
|
45 | 47 | /**
|
46 |
| - * Configuration for a Spring Security in-memory {@link AuthenticationManager}. |
| 48 | + * Configuration for a Spring Security in-memory {@link AuthenticationManager}. Can be |
| 49 | + * disabled by providing a bean of type AuthenticationManager. The value provided by this |
| 50 | + * configuration will become the "global" authentication manager (from Spring Security), |
| 51 | + * or the parent of the global instance. Thus it acts as a fallback when no others are |
| 52 | + * provided, is used by method security if enabled, and as a parent authentication manager |
| 53 | + * for "local" authentication managers in individual filter chains. |
47 | 54 | *
|
48 | 55 | * @author Dave Syer
|
49 | 56 | * @author Rob Winch
|
|
53 | 60 | @ConditionalOnMissingBean(AuthenticationManager.class)
|
54 | 61 | @Order(Ordered.LOWEST_PRECEDENCE - 3)
|
55 | 62 | public class AuthenticationManagerConfiguration extends
|
56 |
| - GlobalAuthenticationConfigurerAdapter implements |
57 |
| - ApplicationListener<ContextRefreshedEvent> { |
| 63 | + GlobalAuthenticationConfigurerAdapter { |
| 64 | + |
| 65 | + /* |
| 66 | + * Yes, this class is a GlobalAuthenticationConfigurerAdapter, even though none of |
| 67 | + * those methods are overridden: we want Spring Security to instantiate us early, so |
| 68 | + * we can in turn force the SecurityPrequisites to be instantiated. This will prevent |
| 69 | + * ordering issues between Spring Boot modules when they need to influence the default |
| 70 | + * security configuration. |
| 71 | + */ |
58 | 72 |
|
59 | 73 | private static Log logger = LogFactory
|
60 | 74 | .getLog(AuthenticationManagerConfiguration.class);
|
61 | 75 |
|
62 | 76 | @Autowired
|
63 | 77 | private List<SecurityPrequisite> dependencies;
|
64 | 78 |
|
65 |
| - @Autowired |
66 |
| - private ObjectPostProcessor<Object> objectPostProcessor; |
67 |
| - |
68 | 79 | @Autowired
|
69 | 80 | private SecurityProperties security;
|
70 | 81 |
|
71 | 82 | @Autowired
|
72 |
| - private AuthenticationEventPublisher authenticationEventPublisher; |
73 |
| - |
74 |
| - private BootDefaultingAuthenticationConfigurerAdapter configurer = new BootDefaultingAuthenticationConfigurerAdapter(); |
75 |
| - |
76 |
| - @Override |
77 |
| - public void init(AuthenticationManagerBuilder auth) throws Exception { |
78 |
| - auth.apply(this.configurer); |
79 |
| - } |
80 |
| - |
81 |
| - @Override |
82 |
| - public void configure(AuthenticationManagerBuilder auth) throws Exception { |
83 |
| - this.configurer.configureParent(auth); |
84 |
| - } |
| 83 | + private ObjectPostProcessor<Object> objectPostProcessor; |
85 | 84 |
|
86 | 85 | @Bean
|
87 | 86 | @Primary
|
88 |
| - public AuthenticationManager authenticationManager() { |
89 |
| - AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder() |
| 87 | + public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) |
| 88 | + throws Exception { |
| 89 | + /* |
| 90 | + * This AuthenticationManagerBuilder is for the global AuthenticationManager |
| 91 | + */ |
| 92 | + BootDefaultingAuthenticationConfigurerAdapter configurer = new BootDefaultingAuthenticationConfigurerAdapter(); |
| 93 | + configurer.init(auth); |
| 94 | + configurer.configure(auth); |
| 95 | + AuthenticationManager manager = configurer.getAuthenticationManagerBuilder() |
90 | 96 | .getOrBuild();
|
| 97 | + configurer.configureParent(auth); |
91 | 98 | return manager;
|
92 | 99 | }
|
93 | 100 |
|
94 |
| - @Override |
95 |
| - public void onApplicationEvent(ContextRefreshedEvent event) { |
96 |
| - AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder() |
97 |
| - .getOrBuild(); |
98 |
| - if (manager instanceof ProviderManager) { |
99 |
| - ((ProviderManager) manager) |
100 |
| - .setAuthenticationEventPublisher(this.authenticationEventPublisher); |
| 101 | + @Component |
| 102 | + protected static class AuthenticationManagerConfigurationListener implements |
| 103 | + ApplicationListener<ContextRefreshedEvent> { |
| 104 | + |
| 105 | + @Autowired |
| 106 | + private AuthenticationEventPublisher authenticationEventPublisher; |
| 107 | + |
| 108 | + @Override |
| 109 | + public void onApplicationEvent(ContextRefreshedEvent event) { |
| 110 | + ApplicationContext context = event.getApplicationContext(); |
| 111 | + if (context.getBeanNamesForType(AuthenticationManager.class).length == 0) { |
| 112 | + return; |
| 113 | + } |
| 114 | + AuthenticationManager manager = context.getBean(AuthenticationManager.class); |
| 115 | + if (manager instanceof ProviderManager) { |
| 116 | + ((ProviderManager) manager) |
| 117 | + .setAuthenticationEventPublisher(this.authenticationEventPublisher); |
| 118 | + } |
101 | 119 | }
|
| 120 | + |
102 | 121 | }
|
103 | 122 |
|
104 | 123 | /**
|
@@ -163,7 +182,8 @@ public void configure(AuthenticationManagerBuilder auth) throws Exception {
|
163 | 182 | .roles(roles.toArray(new String[roles.size()])).and().and().build();
|
164 | 183 |
|
165 | 184 | // Defer actually setting the parent on the AuthenticationManagerBuilder
|
166 |
| - // because it makes it "configured" and we are only in the init() phase here. |
| 185 | + // because it makes it "configured" and we are only in the init() phase |
| 186 | + // here. |
167 | 187 |
|
168 | 188 | }
|
169 | 189 | }
|
|
0 commit comments