18
18
19
19
import java .util .List ;
20
20
import java .util .function .Function ;
21
- import java .util .function .Supplier ;
22
21
23
22
import jakarta .servlet .http .HttpServletRequest ;
24
23
27
26
import org .springframework .core .ResolvableType ;
28
27
import org .springframework .security .access .hierarchicalroles .NullRoleHierarchy ;
29
28
import org .springframework .security .access .hierarchicalroles .RoleHierarchy ;
30
- import org .springframework .security .authorization .AuthenticatedAuthorizationManager ;
31
- import org .springframework .security .authorization .AuthorityAuthorizationManager ;
32
29
import org .springframework .security .authorization .AuthorizationDecision ;
33
30
import org .springframework .security .authorization .AuthorizationEventPublisher ;
34
31
import org .springframework .security .authorization .AuthorizationManager ;
32
+ import org .springframework .security .authorization .AuthorizationManagerFactory ;
35
33
import org .springframework .security .authorization .AuthorizationManagers ;
36
- import org .springframework .security .authorization .SingleResultAuthorizationManager ;
34
+ import org .springframework .security .authorization .DefaultAuthorizationManagerFactory ;
37
35
import org .springframework .security .authorization .SpringAuthorizationEventPublisher ;
38
36
import org .springframework .security .config .ObjectPostProcessor ;
39
37
import org .springframework .security .config .annotation .web .AbstractRequestMatcherRegistry ;
46
44
import org .springframework .security .web .util .matcher .RequestMatcher ;
47
45
import org .springframework .security .web .util .matcher .RequestMatcherEntry ;
48
46
import org .springframework .util .Assert ;
49
- import org .springframework .util .function .SingletonSupplier ;
50
47
51
48
/**
52
49
* Adds a URL based authorization using {@link AuthorizationManager}.
53
50
*
54
51
* @param <H> the type of {@link HttpSecurityBuilder} that is being configured.
55
52
* @author Evgeniy Cheban
53
+ * @author Steve Riesenberg
56
54
* @since 5.5
57
55
*/
58
56
public final class AuthorizeHttpRequestsConfigurer <H extends HttpSecurityBuilder <H >>
@@ -62,9 +60,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
62
60
63
61
private final AuthorizationEventPublisher publisher ;
64
62
65
- private final Supplier <RoleHierarchy > roleHierarchy ;
66
-
67
- private String rolePrefix = "ROLE_" ;
63
+ private final AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
68
64
69
65
private ObjectPostProcessor <AuthorizationManager <HttpServletRequest >> postProcessor = ObjectPostProcessor
70
66
.identity ();
@@ -81,20 +77,36 @@ public AuthorizeHttpRequestsConfigurer(ApplicationContext context) {
81
77
else {
82
78
this .publisher = new SpringAuthorizationEventPublisher (context );
83
79
}
84
- this .roleHierarchy = SingletonSupplier .of (() -> (context .getBeanNamesForType (RoleHierarchy .class ).length > 0 )
85
- ? context .getBean (RoleHierarchy .class ) : new NullRoleHierarchy ());
86
- String [] grantedAuthorityDefaultsBeanNames = context .getBeanNamesForType (GrantedAuthorityDefaults .class );
87
- if (grantedAuthorityDefaultsBeanNames .length > 0 ) {
88
- GrantedAuthorityDefaults grantedAuthorityDefaults = context .getBean (GrantedAuthorityDefaults .class );
89
- this .rolePrefix = grantedAuthorityDefaults .getRolePrefix ();
90
- }
80
+ this .authorizationManagerFactory = getAuthorizationManagerFactory (context );
91
81
ResolvableType type = ResolvableType .forClassWithGenerics (ObjectPostProcessor .class ,
92
82
ResolvableType .forClassWithGenerics (AuthorizationManager .class , HttpServletRequest .class ));
93
83
ObjectProvider <ObjectPostProcessor <AuthorizationManager <HttpServletRequest >>> provider = context
94
84
.getBeanProvider (type );
95
85
provider .ifUnique ((postProcessor ) -> this .postProcessor = postProcessor );
96
86
}
97
87
88
+ private AuthorizationManagerFactory <RequestAuthorizationContext > getAuthorizationManagerFactory (
89
+ ApplicationContext context ) {
90
+ ResolvableType authorizationManagerFactoryType = ResolvableType
91
+ .forClassWithGenerics (AuthorizationManagerFactory .class , RequestAuthorizationContext .class );
92
+ ObjectProvider <AuthorizationManagerFactory <RequestAuthorizationContext >> authorizationManagerFactoryProvider = context
93
+ .getBeanProvider (authorizationManagerFactoryType );
94
+
95
+ return authorizationManagerFactoryProvider .getIfAvailable (() -> {
96
+ RoleHierarchy roleHierarchy = context .getBeanProvider (RoleHierarchy .class )
97
+ .getIfAvailable (NullRoleHierarchy ::new );
98
+ GrantedAuthorityDefaults grantedAuthorityDefaults = context .getBeanProvider (GrantedAuthorityDefaults .class )
99
+ .getIfAvailable ();
100
+ String rolePrefix = (grantedAuthorityDefaults != null ) ? grantedAuthorityDefaults .getRolePrefix () : "ROLE_" ;
101
+
102
+ DefaultAuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory = new DefaultAuthorizationManagerFactory <>();
103
+ authorizationManagerFactory .setRoleHierarchy (roleHierarchy );
104
+ authorizationManagerFactory .setRolePrefix (rolePrefix );
105
+
106
+ return authorizationManagerFactory ;
107
+ });
108
+ }
109
+
98
110
/**
99
111
* The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100
112
* with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +185,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173
185
@ Override
174
186
protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175
187
this .unmappedMatchers = requestMatchers ;
176
- return new AuthorizedUrl (requestMatchers );
188
+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177
189
}
178
190
179
191
/**
@@ -201,20 +213,31 @@ public class AuthorizedUrl {
201
213
202
214
private final List <? extends RequestMatcher > matchers ;
203
215
216
+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
217
+
204
218
private boolean not ;
205
219
206
220
/**
207
221
* Creates an instance.
208
222
* @param matchers the {@link RequestMatcher} instances to map
223
+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
224
+ * creating instances of {@link AuthorizationManager}
209
225
*/
210
- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
226
+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
227
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211
228
this .matchers = matchers ;
229
+ this .authorizationManagerFactory = authorizationManagerFactory ;
212
230
}
213
231
214
232
protected List <? extends RequestMatcher > getMatchers () {
215
233
return this .matchers ;
216
234
}
217
235
236
+ void setAuthorizationManagerFactory (
237
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
238
+ this .authorizationManagerFactory = authorizationManagerFactory ;
239
+ }
240
+
218
241
/**
219
242
* Negates the following authorization rule.
220
243
* @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +254,7 @@ public AuthorizedUrl not() {
231
254
* customizations
232
255
*/
233
256
public AuthorizationManagerRequestMatcherRegistry permitAll () {
234
- return access (SingleResultAuthorizationManager .permitAll ());
257
+ return access (this . authorizationManagerFactory .permitAll ());
235
258
}
236
259
237
260
/**
@@ -240,7 +263,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240
263
* customizations
241
264
*/
242
265
public AuthorizationManagerRequestMatcherRegistry denyAll () {
243
- return access (SingleResultAuthorizationManager .denyAll ());
266
+ return access (this . authorizationManagerFactory .denyAll ());
244
267
}
245
268
246
269
/**
@@ -251,8 +274,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251
274
* customizations
252
275
*/
253
276
public AuthorizationManagerRequestMatcherRegistry hasRole (String role ) {
254
- return access (withRoleHierarchy (AuthorityAuthorizationManager
255
- .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , new String [] { role })));
277
+ return access (this .authorizationManagerFactory .hasRole (role ));
256
278
}
257
279
258
280
/**
@@ -264,8 +286,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264
286
* customizations
265
287
*/
266
288
public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267
- return access (withRoleHierarchy (
268
- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
289
+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269
290
}
270
291
271
292
/**
@@ -275,7 +296,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275
296
* customizations
276
297
*/
277
298
public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278
- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
299
+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279
300
}
280
301
281
302
/**
@@ -286,13 +307,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286
307
* customizations
287
308
*/
288
309
public AuthorizationManagerRequestMatcherRegistry hasAnyAuthority (String ... authorities ) {
289
- return access (withRoleHierarchy (AuthorityAuthorizationManager .hasAnyAuthority (authorities )));
290
- }
291
-
292
- private AuthorityAuthorizationManager <RequestAuthorizationContext > withRoleHierarchy (
293
- AuthorityAuthorizationManager <RequestAuthorizationContext > manager ) {
294
- manager .setRoleHierarchy (AuthorizeHttpRequestsConfigurer .this .roleHierarchy .get ());
295
- return manager ;
310
+ return access (this .authorizationManagerFactory .hasAnyAuthority (authorities ));
296
311
}
297
312
298
313
/**
@@ -301,7 +316,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301
316
* customizations
302
317
*/
303
318
public AuthorizationManagerRequestMatcherRegistry authenticated () {
304
- return access (AuthenticatedAuthorizationManager .authenticated ());
319
+ return access (this . authorizationManagerFactory .authenticated ());
305
320
}
306
321
307
322
/**
@@ -313,7 +328,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313
328
* @see RememberMeConfigurer
314
329
*/
315
330
public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316
- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
331
+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317
332
}
318
333
319
334
/**
@@ -324,7 +339,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324
339
* @see RememberMeConfigurer
325
340
*/
326
341
public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327
- return access (AuthenticatedAuthorizationManager .rememberMe ());
342
+ return access (this . authorizationManagerFactory .rememberMe ());
328
343
}
329
344
330
345
/**
@@ -334,7 +349,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334
349
* @since 5.8
335
350
*/
336
351
public AuthorizationManagerRequestMatcherRegistry anonymous () {
337
- return access (AuthenticatedAuthorizationManager .anonymous ());
352
+ return access (this . authorizationManagerFactory .anonymous ());
338
353
}
339
354
340
355
/**
0 commit comments