16
16
17
17
package org .springframework .security .config .annotation .authentication .configuration ;
18
18
19
+ import java .util .ArrayList ;
20
+ import java .util .List ;
21
+
22
+ import org .apache .commons .logging .Log ;
23
+ import org .apache .commons .logging .LogFactory ;
24
+
19
25
import org .springframework .context .ApplicationContext ;
20
26
import org .springframework .core .Ordered ;
21
27
import org .springframework .core .annotation .Order ;
28
+ import org .springframework .core .log .LogMessage ;
22
29
import org .springframework .security .authentication .dao .DaoAuthenticationProvider ;
23
30
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
24
31
import org .springframework .security .core .userdetails .UserDetailsPasswordService ;
@@ -54,15 +61,31 @@ public void init(AuthenticationManagerBuilder auth) throws Exception {
54
61
55
62
class InitializeUserDetailsManagerConfigurer extends GlobalAuthenticationConfigurerAdapter {
56
63
64
+ private final Log logger = LogFactory .getLog (getClass ());
65
+
57
66
@ Override
58
67
public void configure (AuthenticationManagerBuilder auth ) throws Exception {
68
+ List <BeanWithName <UserDetailsService >> userDetailsServices = getBeansWithName (UserDetailsService .class );
59
69
if (auth .isConfigured ()) {
70
+ if (!userDetailsServices .isEmpty ()) {
71
+ this .logger .warn ("Global AuthenticationManager configured with an AuthenticationProvider bean. "
72
+ + "UserDetailsService beans will not be used for username/password login." );
73
+ }
74
+ return ;
75
+ }
76
+
77
+ if (userDetailsServices .isEmpty ()) {
60
78
return ;
61
79
}
62
- UserDetailsService userDetailsService = getBeanOrNull (UserDetailsService .class );
63
- if (userDetailsService == null ) {
80
+ else if (userDetailsServices .size () > 1 ) {
81
+ List <String > beanNames = userDetailsServices .stream ().map (BeanWithName ::getName ).toList ();
82
+ this .logger .warn (LogMessage .format ("Found %s UserDetailsService beans, with names %s. "
83
+ + "Global Authentication Manager will not use a UserDetailsService for username/password login." ,
84
+ userDetailsServices .size (), beanNames ));
64
85
return ;
65
86
}
87
+ var userDetailsService = userDetailsServices .get (0 ).getBean ();
88
+ var userDetailsServiceBeanName = userDetailsServices .get (0 ).getName ();
66
89
PasswordEncoder passwordEncoder = getBeanOrNull (PasswordEncoder .class );
67
90
UserDetailsPasswordService passwordManager = getBeanOrNull (UserDetailsPasswordService .class );
68
91
DaoAuthenticationProvider provider = new DaoAuthenticationProvider ();
@@ -75,6 +98,9 @@ public void configure(AuthenticationManagerBuilder auth) throws Exception {
75
98
}
76
99
provider .afterPropertiesSet ();
77
100
auth .authenticationProvider (provider );
101
+ this .logger .info (LogMessage .format (
102
+ "Global AuthenticationManager configured with UserDetailsService bean with name %s" ,
103
+ userDetailsServiceBeanName ));
78
104
}
79
105
80
106
/**
@@ -89,6 +115,41 @@ private <T> T getBeanOrNull(Class<T> type) {
89
115
return InitializeUserDetailsBeanManagerConfigurer .this .context .getBean (beanNames [0 ], type );
90
116
}
91
117
118
+ /**
119
+ * @return a list of beans of the requested class, along with their names. If
120
+ * there are no registered beans of that type, the list is empty.
121
+ */
122
+ private <T > List <BeanWithName <T >> getBeansWithName (Class <T > type ) {
123
+ List <BeanWithName <T >> beanWithNames = new ArrayList <>();
124
+ String [] beanNames = InitializeUserDetailsBeanManagerConfigurer .this .context .getBeanNamesForType (type );
125
+ for (String beanName : beanNames ) {
126
+ T bean = InitializeUserDetailsBeanManagerConfigurer .this .context .getBean (beanNames [0 ], type );
127
+ beanWithNames .add (new BeanWithName <T >(bean , beanName ));
128
+ }
129
+ return beanWithNames ;
130
+ }
131
+
132
+ static class BeanWithName <T > {
133
+
134
+ private final T bean ;
135
+
136
+ private final String name ;
137
+
138
+ BeanWithName (T bean , String name ) {
139
+ this .bean = bean ;
140
+ this .name = name ;
141
+ }
142
+
143
+ T getBean () {
144
+ return this .bean ;
145
+ }
146
+
147
+ String getName () {
148
+ return this .name ;
149
+ }
150
+
151
+ }
152
+
92
153
}
93
154
94
155
}
0 commit comments