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}.
@@ -62,9 +59,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
62
59
63
60
private final AuthorizationEventPublisher publisher ;
64
61
65
- private final Supplier <RoleHierarchy > roleHierarchy ;
66
-
67
- private String rolePrefix = "ROLE_" ;
62
+ private final AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
68
63
69
64
private ObjectPostProcessor <AuthorizationManager <HttpServletRequest >> postProcessor = ObjectPostProcessor
70
65
.identity ();
@@ -81,20 +76,36 @@ public AuthorizeHttpRequestsConfigurer(ApplicationContext context) {
81
76
else {
82
77
this .publisher = new SpringAuthorizationEventPublisher (context );
83
78
}
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
- }
79
+ this .authorizationManagerFactory = getAuthorizationManagerFactory (context );
91
80
ResolvableType type = ResolvableType .forClassWithGenerics (ObjectPostProcessor .class ,
92
81
ResolvableType .forClassWithGenerics (AuthorizationManager .class , HttpServletRequest .class ));
93
82
ObjectProvider <ObjectPostProcessor <AuthorizationManager <HttpServletRequest >>> provider = context
94
83
.getBeanProvider (type );
95
84
provider .ifUnique ((postProcessor ) -> this .postProcessor = postProcessor );
96
85
}
97
86
87
+ private AuthorizationManagerFactory <RequestAuthorizationContext > getAuthorizationManagerFactory (
88
+ ApplicationContext context ) {
89
+ ResolvableType authorizationManagerFactoryType = ResolvableType
90
+ .forClassWithGenerics (AuthorizationManagerFactory .class , RequestAuthorizationContext .class );
91
+ ObjectProvider <AuthorizationManagerFactory <RequestAuthorizationContext >> authorizationManagerFactoryProvider = context
92
+ .getBeanProvider (authorizationManagerFactoryType );
93
+
94
+ return authorizationManagerFactoryProvider .getIfAvailable (() -> {
95
+ RoleHierarchy roleHierarchy = context .getBeanProvider (RoleHierarchy .class )
96
+ .getIfAvailable (NullRoleHierarchy ::new );
97
+ GrantedAuthorityDefaults grantedAuthorityDefaults = context .getBeanProvider (GrantedAuthorityDefaults .class )
98
+ .getIfAvailable ();
99
+ String rolePrefix = (grantedAuthorityDefaults != null ) ? grantedAuthorityDefaults .getRolePrefix () : "ROLE_" ;
100
+
101
+ DefaultAuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory = new DefaultAuthorizationManagerFactory <>();
102
+ authorizationManagerFactory .setRoleHierarchy (roleHierarchy );
103
+ authorizationManagerFactory .setRolePrefix (rolePrefix );
104
+
105
+ return authorizationManagerFactory ;
106
+ });
107
+ }
108
+
98
109
/**
99
110
* The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100
111
* with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +184,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173
184
@ Override
174
185
protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175
186
this .unmappedMatchers = requestMatchers ;
176
- return new AuthorizedUrl (requestMatchers );
187
+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177
188
}
178
189
179
190
/**
@@ -201,20 +212,31 @@ public class AuthorizedUrl {
201
212
202
213
private final List <? extends RequestMatcher > matchers ;
203
214
215
+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
216
+
204
217
private boolean not ;
205
218
206
219
/**
207
220
* Creates an instance.
208
221
* @param matchers the {@link RequestMatcher} instances to map
222
+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
223
+ * creating instances of {@link AuthorizationManager}
209
224
*/
210
- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
225
+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
226
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211
227
this .matchers = matchers ;
228
+ this .authorizationManagerFactory = authorizationManagerFactory ;
212
229
}
213
230
214
231
protected List <? extends RequestMatcher > getMatchers () {
215
232
return this .matchers ;
216
233
}
217
234
235
+ void setAuthorizationManagerFactory (
236
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
237
+ this .authorizationManagerFactory = authorizationManagerFactory ;
238
+ }
239
+
218
240
/**
219
241
* Negates the following authorization rule.
220
242
* @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +253,7 @@ public AuthorizedUrl not() {
231
253
* customizations
232
254
*/
233
255
public AuthorizationManagerRequestMatcherRegistry permitAll () {
234
- return access (SingleResultAuthorizationManager .permitAll ());
256
+ return access (this . authorizationManagerFactory .permitAll ());
235
257
}
236
258
237
259
/**
@@ -240,7 +262,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240
262
* customizations
241
263
*/
242
264
public AuthorizationManagerRequestMatcherRegistry denyAll () {
243
- return access (SingleResultAuthorizationManager .denyAll ());
265
+ return access (this . authorizationManagerFactory .denyAll ());
244
266
}
245
267
246
268
/**
@@ -251,8 +273,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251
273
* customizations
252
274
*/
253
275
public AuthorizationManagerRequestMatcherRegistry hasRole (String role ) {
254
- return access (withRoleHierarchy (AuthorityAuthorizationManager
255
- .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , new String [] { role })));
276
+ return access (this .authorizationManagerFactory .hasRole (role ));
256
277
}
257
278
258
279
/**
@@ -264,8 +285,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264
285
* customizations
265
286
*/
266
287
public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267
- return access (withRoleHierarchy (
268
- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
288
+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269
289
}
270
290
271
291
/**
@@ -275,7 +295,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275
295
* customizations
276
296
*/
277
297
public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278
- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
298
+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279
299
}
280
300
281
301
/**
@@ -286,13 +306,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286
306
* customizations
287
307
*/
288
308
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 ;
309
+ return access (this .authorizationManagerFactory .hasAnyAuthority (authorities ));
296
310
}
297
311
298
312
/**
@@ -301,7 +315,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301
315
* customizations
302
316
*/
303
317
public AuthorizationManagerRequestMatcherRegistry authenticated () {
304
- return access (AuthenticatedAuthorizationManager .authenticated ());
318
+ return access (this . authorizationManagerFactory .authenticated ());
305
319
}
306
320
307
321
/**
@@ -313,7 +327,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313
327
* @see RememberMeConfigurer
314
328
*/
315
329
public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316
- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
330
+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317
331
}
318
332
319
333
/**
@@ -324,7 +338,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324
338
* @see RememberMeConfigurer
325
339
*/
326
340
public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327
- return access (AuthenticatedAuthorizationManager .rememberMe ());
341
+ return access (this . authorizationManagerFactory .rememberMe ());
328
342
}
329
343
330
344
/**
@@ -334,7 +348,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334
348
* @since 5.8
335
349
*/
336
350
public AuthorizationManagerRequestMatcherRegistry anonymous () {
337
- return access (AuthenticatedAuthorizationManager .anonymous ());
351
+ return access (this . authorizationManagerFactory .anonymous ());
338
352
}
339
353
340
354
/**
0 commit comments