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,43 @@ 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
+
93
+ // Handle fallback to generic type
94
+ if (context .getBeanNamesForType (authorizationManagerFactoryType ).length == 0 ) {
95
+ authorizationManagerFactoryType = ResolvableType .forClassWithGenerics (AuthorizationManagerFactory .class ,
96
+ Object .class );
97
+ }
98
+
99
+ ObjectProvider <AuthorizationManagerFactory <RequestAuthorizationContext >> authorizationManagerFactoryProvider = context
100
+ .getBeanProvider (authorizationManagerFactoryType );
101
+
102
+ return authorizationManagerFactoryProvider .getIfAvailable (() -> {
103
+ RoleHierarchy roleHierarchy = context .getBeanProvider (RoleHierarchy .class )
104
+ .getIfAvailable (NullRoleHierarchy ::new );
105
+ GrantedAuthorityDefaults grantedAuthorityDefaults = context .getBeanProvider (GrantedAuthorityDefaults .class )
106
+ .getIfAvailable ();
107
+ String rolePrefix = (grantedAuthorityDefaults != null ) ? grantedAuthorityDefaults .getRolePrefix () : "ROLE_" ;
108
+
109
+ DefaultAuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory = new DefaultAuthorizationManagerFactory <>();
110
+ authorizationManagerFactory .setRoleHierarchy (roleHierarchy );
111
+ authorizationManagerFactory .setRolePrefix (rolePrefix );
112
+
113
+ return authorizationManagerFactory ;
114
+ });
115
+ }
116
+
98
117
/**
99
118
* The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100
119
* with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +192,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173
192
@ Override
174
193
protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175
194
this .unmappedMatchers = requestMatchers ;
176
- return new AuthorizedUrl (requestMatchers );
195
+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177
196
}
178
197
179
198
/**
@@ -201,20 +220,31 @@ public class AuthorizedUrl {
201
220
202
221
private final List <? extends RequestMatcher > matchers ;
203
222
223
+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
224
+
204
225
private boolean not ;
205
226
206
227
/**
207
228
* Creates an instance.
208
229
* @param matchers the {@link RequestMatcher} instances to map
230
+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
231
+ * creating instances of {@link AuthorizationManager}
209
232
*/
210
- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
233
+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
234
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211
235
this .matchers = matchers ;
236
+ this .authorizationManagerFactory = authorizationManagerFactory ;
212
237
}
213
238
214
239
protected List <? extends RequestMatcher > getMatchers () {
215
240
return this .matchers ;
216
241
}
217
242
243
+ void setAuthorizationManagerFactory (
244
+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
245
+ this .authorizationManagerFactory = authorizationManagerFactory ;
246
+ }
247
+
218
248
/**
219
249
* Negates the following authorization rule.
220
250
* @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +261,7 @@ public AuthorizedUrl not() {
231
261
* customizations
232
262
*/
233
263
public AuthorizationManagerRequestMatcherRegistry permitAll () {
234
- return access (SingleResultAuthorizationManager .permitAll ());
264
+ return access (this . authorizationManagerFactory .permitAll ());
235
265
}
236
266
237
267
/**
@@ -240,7 +270,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240
270
* customizations
241
271
*/
242
272
public AuthorizationManagerRequestMatcherRegistry denyAll () {
243
- return access (SingleResultAuthorizationManager .denyAll ());
273
+ return access (this . authorizationManagerFactory .denyAll ());
244
274
}
245
275
246
276
/**
@@ -251,8 +281,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251
281
* customizations
252
282
*/
253
283
public AuthorizationManagerRequestMatcherRegistry hasRole (String role ) {
254
- return access (withRoleHierarchy (AuthorityAuthorizationManager
255
- .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , new String [] { role })));
284
+ return access (this .authorizationManagerFactory .hasRole (role ));
256
285
}
257
286
258
287
/**
@@ -264,8 +293,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264
293
* customizations
265
294
*/
266
295
public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267
- return access (withRoleHierarchy (
268
- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
296
+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269
297
}
270
298
271
299
/**
@@ -275,7 +303,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275
303
* customizations
276
304
*/
277
305
public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278
- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
306
+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279
307
}
280
308
281
309
/**
@@ -286,13 +314,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286
314
* customizations
287
315
*/
288
316
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 ;
317
+ return access (this .authorizationManagerFactory .hasAnyAuthority (authorities ));
296
318
}
297
319
298
320
/**
@@ -301,7 +323,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301
323
* customizations
302
324
*/
303
325
public AuthorizationManagerRequestMatcherRegistry authenticated () {
304
- return access (AuthenticatedAuthorizationManager .authenticated ());
326
+ return access (this . authorizationManagerFactory .authenticated ());
305
327
}
306
328
307
329
/**
@@ -313,7 +335,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313
335
* @see RememberMeConfigurer
314
336
*/
315
337
public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316
- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
338
+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317
339
}
318
340
319
341
/**
@@ -324,7 +346,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324
346
* @see RememberMeConfigurer
325
347
*/
326
348
public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327
- return access (AuthenticatedAuthorizationManager .rememberMe ());
349
+ return access (this . authorizationManagerFactory .rememberMe ());
328
350
}
329
351
330
352
/**
@@ -334,7 +356,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334
356
* @since 5.8
335
357
*/
336
358
public AuthorizationManagerRequestMatcherRegistry anonymous () {
337
- return access (AuthenticatedAuthorizationManager .anonymous ());
359
+ return access (this . authorizationManagerFactory .anonymous ());
338
360
}
339
361
340
362
/**
0 commit comments