17
17
package org .springframework .boot .actuate .autoconfigure ;
18
18
19
19
import java .util .ArrayList ;
20
+ import java .util .Arrays ;
21
+ import java .util .LinkedHashSet ;
20
22
import java .util .List ;
23
+ import java .util .Set ;
21
24
22
25
import org .apache .commons .logging .Log ;
23
26
import org .apache .commons .logging .LogFactory ;
24
27
import org .springframework .beans .factory .annotation .Autowired ;
25
28
import org .springframework .boot .actuate .endpoint .Endpoint ;
26
29
import org .springframework .boot .actuate .endpoint .mvc .EndpointHandlerMapping ;
27
30
import org .springframework .boot .actuate .properties .ManagementServerProperties ;
28
- import org .springframework .boot .actuate .properties .ManagementServerProperties .User ;
29
31
import org .springframework .boot .actuate .properties .SecurityProperties ;
32
+ import org .springframework .boot .actuate .properties .SecurityProperties .User ;
30
33
import org .springframework .boot .actuate .web .ErrorController ;
31
34
import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
32
35
import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
40
43
import org .springframework .security .authentication .AuthenticationManager ;
41
44
import org .springframework .security .authentication .DefaultAuthenticationEventPublisher ;
42
45
import org .springframework .security .authentication .ProviderManager ;
46
+ import org .springframework .security .config .annotation .ObjectPostProcessor ;
43
47
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
48
+ import org .springframework .security .config .annotation .authentication .configurers .provisioning .InMemoryUserDetailsManagerConfigurer ;
44
49
import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
45
50
import org .springframework .security .config .annotation .web .builders .WebSecurity ;
46
51
import org .springframework .security .config .annotation .web .builders .WebSecurity .IgnoredRequestConfigurer ;
47
52
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
48
53
import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
49
- import org .springframework .security .config .annotation .web .configurers .ExpressionUrlAuthorizationConfigurer ;
50
54
import org .springframework .security .web .AuthenticationEntryPoint ;
51
55
import org .springframework .security .web .authentication .www .BasicAuthenticationEntryPoint ;
52
56
85
89
@ Configuration
86
90
@ ConditionalOnClass ({ EnableWebSecurity .class })
87
91
@ EnableWebSecurity
92
+ // (debug = true)
88
93
@ EnableConfigurationProperties
89
94
public class SecurityAutoConfiguration {
90
95
@@ -101,27 +106,25 @@ public AuthenticationEventPublisher authenticationEventPublisher() {
101
106
}
102
107
103
108
@ Bean
104
- @ ConditionalOnMissingBean ({ BoostrapWebSecurityConfigurerAdapter .class })
105
- public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter () {
106
- return new BoostrapWebSecurityConfigurerAdapter ();
109
+ @ ConditionalOnMissingBean ({ ApplicationWebSecurityConfigurerAdapter .class })
110
+ public WebSecurityConfigurerAdapter applicationWebSecurityConfigurerAdapter () {
111
+ return new ApplicationWebSecurityConfigurerAdapter ();
112
+ }
113
+
114
+ @ Bean
115
+ @ ConditionalOnMissingBean ({ ManagementWebSecurityConfigurerAdapter .class })
116
+ public WebSecurityConfigurerAdapter managementWebSecurityConfigurerAdapter () {
117
+ return new ManagementWebSecurityConfigurerAdapter ();
107
118
}
108
119
109
120
// Give user-supplied filters a chance to be last in line
110
- @ Order (Ordered .LOWEST_PRECEDENCE - 10 )
111
- private static class BoostrapWebSecurityConfigurerAdapter extends
121
+ @ Order (Ordered .LOWEST_PRECEDENCE - 5 )
122
+ private static class ApplicationWebSecurityConfigurerAdapter extends
112
123
WebSecurityConfigurerAdapter {
113
124
114
- private static final String [] NO_PATHS = new String [0 ];
115
-
116
125
@ Autowired
117
126
private SecurityProperties security ;
118
127
119
- @ Autowired
120
- private ManagementServerProperties management ;
121
-
122
- @ Autowired (required = false )
123
- private EndpointHandlerMapping endpointHandlerMapping ;
124
-
125
128
@ Autowired
126
129
private AuthenticationEventPublisher authenticationEventPublisher ;
127
130
@@ -135,26 +138,20 @@ protected void configure(HttpSecurity http) throws Exception {
135
138
http .requiresChannel ().anyRequest ().requiresSecure ();
136
139
}
137
140
138
- if (this .security .getBasic ().isEnabled ()) {
141
+ String [] paths = getSecureApplicationPaths ();
142
+ if (this .security .getBasic ().isEnabled () && paths .length > 0 ) {
139
143
http .exceptionHandling ().authenticationEntryPoint (entryPoint ());
140
- http .httpBasic ().and ().anonymous ().disable ();
141
- ExpressionUrlAuthorizationConfigurer <HttpSecurity > authorizeUrls = http
142
- .authorizeUrls ();
143
- String [] paths = getEndpointPaths (true );
144
- if (paths .length > 0 ) {
145
- authorizeUrls .antMatchers (getEndpointPaths (true )).hasRole (
146
- this .management .getUser ().getRole ());
147
- }
148
- paths = getSecureApplicationPaths ();
149
- if (paths .length > 0 ) {
150
- authorizeUrls .antMatchers (getSecureApplicationPaths ()).hasRole (
151
- this .security .getBasic ().getRole ());
152
- }
153
- authorizeUrls .and ().httpBasic ();
144
+ http .requestMatchers ().antMatchers (paths );
145
+ http .authorizeRequests ().anyRequest ()
146
+ .hasRole (this .security .getUser ().getRole ()) //
147
+ .and ().httpBasic () //
148
+ .and ().anonymous ().disable ();
154
149
}
155
-
156
- // No cookies for service endpoints by default
150
+ // Remove this when session creation is disabled by default
151
+ http .csrf ().disable ();
152
+ // No cookies for application endpoints by default
157
153
http .sessionManagement ().sessionCreationPolicy (this .security .getSessions ());
154
+
158
155
}
159
156
160
157
private String [] getSecureApplicationPaths () {
@@ -181,12 +178,74 @@ private AuthenticationEntryPoint entryPoint() {
181
178
public void configure (WebSecurity builder ) throws Exception {
182
179
IgnoredRequestConfigurer ignoring = builder .ignoring ();
183
180
ignoring .antMatchers (this .security .getIgnored ());
184
- ignoring .antMatchers (getEndpointPaths (false ));
185
181
if (this .errorController != null ) {
186
182
ignoring .antMatchers (this .errorController .getErrorPath ());
187
183
}
188
184
}
189
185
186
+ @ Override
187
+ protected AuthenticationManager authenticationManager () throws Exception {
188
+ AuthenticationManager manager = super .authenticationManager ();
189
+ if (manager instanceof ProviderManager ) {
190
+ ((ProviderManager ) manager )
191
+ .setAuthenticationEventPublisher (this .authenticationEventPublisher );
192
+ }
193
+ return manager ;
194
+ }
195
+
196
+ }
197
+
198
+ // Give user-supplied filters a chance to be last in line
199
+ @ Order (Ordered .LOWEST_PRECEDENCE - 10 )
200
+ private static class ManagementWebSecurityConfigurerAdapter extends
201
+ WebSecurityConfigurerAdapter {
202
+
203
+ private static final String [] NO_PATHS = new String [0 ];
204
+
205
+ @ Autowired
206
+ private SecurityProperties security ;
207
+
208
+ @ Autowired
209
+ private ManagementServerProperties management ;
210
+
211
+ @ Autowired (required = false )
212
+ private EndpointHandlerMapping endpointHandlerMapping ;
213
+
214
+ @ Override
215
+ protected void configure (HttpSecurity http ) throws Exception {
216
+
217
+ if (this .security .isRequireSsl ()) {
218
+ http .requiresChannel ().anyRequest ().requiresSecure ();
219
+ }
220
+
221
+ String [] paths = getEndpointPaths (true );
222
+ if (this .security .getBasic ().isEnabled () && paths .length > 0 ) {
223
+ http .exceptionHandling ().authenticationEntryPoint (entryPoint ());
224
+ http .requestMatchers ().antMatchers (paths );
225
+ http .authorizeRequests ().anyRequest ()
226
+ .hasRole (this .security .getManagement ().getRole ()) //
227
+ .and ().httpBasic () //
228
+ .and ().anonymous ().disable ();
229
+ }
230
+ // No cookies for management endpoints by default
231
+ http .csrf ().disable ();
232
+ http .sessionManagement ().sessionCreationPolicy (
233
+ this .security .getManagement ().getSessions ());
234
+
235
+ }
236
+
237
+ @ Override
238
+ public void configure (WebSecurity builder ) throws Exception {
239
+ IgnoredRequestConfigurer ignoring = builder .ignoring ();
240
+ ignoring .antMatchers (getEndpointPaths (false ));
241
+ }
242
+
243
+ private AuthenticationEntryPoint entryPoint () {
244
+ BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint ();
245
+ entryPoint .setRealmName (this .security .getBasic ().getRealm ());
246
+ return entryPoint ;
247
+ }
248
+
190
249
private String [] getEndpointPaths (boolean secure ) {
191
250
if (this .endpointHandlerMapping == null ) {
192
251
return NO_PATHS ;
@@ -202,16 +261,6 @@ private String[] getEndpointPaths(boolean secure) {
202
261
return paths .toArray (new String [paths .size ()]);
203
262
}
204
263
205
- @ Override
206
- protected AuthenticationManager authenticationManager () throws Exception {
207
- AuthenticationManager manager = super .authenticationManager ();
208
- if (manager instanceof ProviderManager ) {
209
- ((ProviderManager ) manager )
210
- .setAuthenticationEventPublisher (this .authenticationEventPublisher );
211
- }
212
- return manager ;
213
- }
214
-
215
264
}
216
265
217
266
@ ConditionalOnMissingBean (AuthenticationManager .class )
@@ -222,23 +271,28 @@ public static class AuthenticationManagerConfiguration {
222
271
.getLog (AuthenticationManagerConfiguration .class );
223
272
224
273
@ Autowired
225
- private ManagementServerProperties management ;
274
+ private SecurityProperties security ;
226
275
227
276
@ Bean
228
277
public AuthenticationManager authenticationManager () throws Exception {
229
- User user = this .management .getUser ();
278
+
279
+ InMemoryUserDetailsManagerConfigurer <AuthenticationManagerBuilder > builder = new AuthenticationManagerBuilder (
280
+ ObjectPostProcessor .QUIESCENT_POSTPROCESSOR ).inMemoryAuthentication ();
281
+ User user = this .security .getUser ();
282
+
230
283
if (user .isDefaultPassword ()) {
231
- logger .info ("Using default password for management endpoints: "
284
+ logger .info ("Using default password for application endpoints: "
232
285
+ user .getPassword ());
233
286
}
234
- List <String > roles = new ArrayList <String >();
235
- roles .add ("USER" );
236
- if (!"USER" .equals (user .getRole ())) {
237
- roles .add (user .getRole ());
238
- }
239
- return new AuthenticationManagerBuilder ().inMemoryAuthentication ()
240
- .withUser (user .getName ()).password (user .getPassword ())
241
- .roles (roles .toArray (new String [roles .size ()])).and ().and ().build ();
287
+
288
+ Set <String > roles = new LinkedHashSet <String >(Arrays .asList (this .security
289
+ .getManagement ().getRole (), user .getRole ()));
290
+
291
+ builder .withUser (user .getName ()).password (user .getPassword ())
292
+ .roles (roles .toArray (new String [roles .size ()]));
293
+
294
+ return builder .and ().build ();
295
+
242
296
}
243
297
244
298
}
0 commit comments