2727import org .springframework .core .ResolvableType ;
2828import org .springframework .security .access .hierarchicalroles .NullRoleHierarchy ;
2929import org .springframework .security .access .hierarchicalroles .RoleHierarchy ;
30- import org .springframework .security .authorization .AuthenticatedAuthorizationManager ;
3130import org .springframework .security .authorization .AuthorityAuthorizationManager ;
3231import org .springframework .security .authorization .AuthorizationDecision ;
3332import org .springframework .security .authorization .AuthorizationEventPublisher ;
3433import org .springframework .security .authorization .AuthorizationManager ;
34+ import org .springframework .security .authorization .AuthorizationManagerFactory ;
3535import org .springframework .security .authorization .AuthorizationManagers ;
36- import org .springframework .security .authorization .SingleResultAuthorizationManager ;
3736import org .springframework .security .authorization .SpringAuthorizationEventPublisher ;
3837import org .springframework .security .config .ObjectPostProcessor ;
3938import org .springframework .security .config .annotation .web .AbstractRequestMatcherRegistry ;
@@ -62,9 +61,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
6261
6362 private final AuthorizationEventPublisher publisher ;
6463
65- private final Supplier <RoleHierarchy > roleHierarchy ;
66-
67- private String rolePrefix = "ROLE_" ;
64+ private final AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
6865
6966 private ObjectPostProcessor <AuthorizationManager <HttpServletRequest >> postProcessor = ObjectPostProcessor
7067 .identity ();
@@ -81,20 +78,32 @@ public AuthorizeHttpRequestsConfigurer(ApplicationContext context) {
8178 else {
8279 this .publisher = new SpringAuthorizationEventPublisher (context );
8380 }
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- }
81+ this .authorizationManagerFactory = getAuthorizationManagerFactory (context );
9182 ResolvableType type = ResolvableType .forClassWithGenerics (ObjectPostProcessor .class ,
9283 ResolvableType .forClassWithGenerics (AuthorizationManager .class , HttpServletRequest .class ));
9384 ObjectProvider <ObjectPostProcessor <AuthorizationManager <HttpServletRequest >>> provider = context
9485 .getBeanProvider (type );
9586 provider .ifUnique ((postProcessor ) -> this .postProcessor = postProcessor );
9687 }
9788
89+ private AuthorizationManagerFactory <RequestAuthorizationContext > getAuthorizationManagerFactory (
90+ ApplicationContext context ) {
91+ ResolvableType authorizationManagerFactoryType = ResolvableType
92+ .forClassWithGenerics (AuthorizationManagerFactory .class , RequestAuthorizationContext .class );
93+ ObjectProvider <AuthorizationManagerFactory <RequestAuthorizationContext >> authorizationManagerFactoryProvider = context
94+ .getBeanProvider (authorizationManagerFactoryType );
95+
96+ return authorizationManagerFactoryProvider .getIfAvailable (() -> {
97+ Supplier <RoleHierarchy > roleHierarchy = SingletonSupplier
98+ .of (() -> context .getBeanProvider (RoleHierarchy .class ).getIfAvailable (NullRoleHierarchy ::new ));
99+ GrantedAuthorityDefaults grantedAuthorityDefaults = context .getBeanProvider (GrantedAuthorityDefaults .class )
100+ .getIfAvailable ();
101+ String rolePrefix = (grantedAuthorityDefaults != null ) ? grantedAuthorityDefaults .getRolePrefix () : "ROLE_" ;
102+
103+ return new RequestAuthorizationContextAuthorizationManagerFactory (roleHierarchy , rolePrefix );
104+ });
105+ }
106+
98107 /**
99108 * The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100109 * with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +182,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173182 @ Override
174183 protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175184 this .unmappedMatchers = requestMatchers ;
176- return new AuthorizedUrl (requestMatchers );
185+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177186 }
178187
179188 /**
@@ -201,20 +210,31 @@ public class AuthorizedUrl {
201210
202211 private final List <? extends RequestMatcher > matchers ;
203212
213+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
214+
204215 private boolean not ;
205216
206217 /**
207218 * Creates an instance.
208219 * @param matchers the {@link RequestMatcher} instances to map
220+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
221+ * creating instances of {@link AuthorizationManager}
209222 */
210- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
223+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
224+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211225 this .matchers = matchers ;
226+ this .authorizationManagerFactory = authorizationManagerFactory ;
212227 }
213228
214229 protected List <? extends RequestMatcher > getMatchers () {
215230 return this .matchers ;
216231 }
217232
233+ void setAuthorizationManagerFactory (
234+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
235+ this .authorizationManagerFactory = authorizationManagerFactory ;
236+ }
237+
218238 /**
219239 * Negates the following authorization rule.
220240 * @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +251,7 @@ public AuthorizedUrl not() {
231251 * customizations
232252 */
233253 public AuthorizationManagerRequestMatcherRegistry permitAll () {
234- return access (SingleResultAuthorizationManager .permitAll ());
254+ return access (this . authorizationManagerFactory .permitAll ());
235255 }
236256
237257 /**
@@ -240,7 +260,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240260 * customizations
241261 */
242262 public AuthorizationManagerRequestMatcherRegistry denyAll () {
243- return access (SingleResultAuthorizationManager .denyAll ());
263+ return access (this . authorizationManagerFactory .denyAll ());
244264 }
245265
246266 /**
@@ -251,8 +271,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251271 * customizations
252272 */
253273 public AuthorizationManagerRequestMatcherRegistry hasRole (String role ) {
254- return access (withRoleHierarchy (AuthorityAuthorizationManager
255- .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , new String [] { role })));
274+ return access (this .authorizationManagerFactory .hasRole (role ));
256275 }
257276
258277 /**
@@ -264,8 +283,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264283 * customizations
265284 */
266285 public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267- return access (withRoleHierarchy (
268- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
286+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269287 }
270288
271289 /**
@@ -275,7 +293,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275293 * customizations
276294 */
277295 public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
296+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279297 }
280298
281299 /**
@@ -286,13 +304,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286304 * customizations
287305 */
288306 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 ;
307+ return access (this .authorizationManagerFactory .hasAnyAuthority (authorities ));
296308 }
297309
298310 /**
@@ -301,7 +313,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301313 * customizations
302314 */
303315 public AuthorizationManagerRequestMatcherRegistry authenticated () {
304- return access (AuthenticatedAuthorizationManager .authenticated ());
316+ return access (this . authorizationManagerFactory .authenticated ());
305317 }
306318
307319 /**
@@ -313,7 +325,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313325 * @see RememberMeConfigurer
314326 */
315327 public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
328+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317329 }
318330
319331 /**
@@ -324,7 +336,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324336 * @see RememberMeConfigurer
325337 */
326338 public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327- return access (AuthenticatedAuthorizationManager .rememberMe ());
339+ return access (this . authorizationManagerFactory .rememberMe ());
328340 }
329341
330342 /**
@@ -334,7 +346,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334346 * @since 5.8
335347 */
336348 public AuthorizationManagerRequestMatcherRegistry anonymous () {
337- return access (AuthenticatedAuthorizationManager .anonymous ());
349+ return access (this . authorizationManagerFactory .anonymous ());
338350 }
339351
340352 /**
@@ -403,4 +415,45 @@ public AuthorizationManagerRequestMatcherRegistry equalTo(Function<Authenticatio
403415
404416 }
405417
418+ static final class RequestAuthorizationContextAuthorizationManagerFactory
419+ implements AuthorizationManagerFactory <RequestAuthorizationContext > {
420+
421+ private final Supplier <RoleHierarchy > roleHierarchy ;
422+
423+ private final String rolePrefix ;
424+
425+ RequestAuthorizationContextAuthorizationManagerFactory (Supplier <RoleHierarchy > roleHierarchy ,
426+ String rolePrefix ) {
427+ this .roleHierarchy = roleHierarchy ;
428+ this .rolePrefix = rolePrefix ;
429+ }
430+
431+ @ Override
432+ public AuthorizationManager <RequestAuthorizationContext > hasRole (String role ) {
433+ return withRoleHierarchy (AuthorityAuthorizationManager .hasAnyRole (this .rolePrefix , new String [] { role }));
434+ }
435+
436+ @ Override
437+ public AuthorizationManager <RequestAuthorizationContext > hasAnyRole (String ... roles ) {
438+ return withRoleHierarchy (AuthorityAuthorizationManager .hasAnyRole (this .rolePrefix , roles ));
439+ }
440+
441+ @ Override
442+ public AuthorizationManager <RequestAuthorizationContext > hasAuthority (String authority ) {
443+ return withRoleHierarchy (AuthorityAuthorizationManager .hasAuthority (authority ));
444+ }
445+
446+ @ Override
447+ public AuthorizationManager <RequestAuthorizationContext > hasAnyAuthority (String ... authorities ) {
448+ return withRoleHierarchy (AuthorityAuthorizationManager .hasAnyAuthority (authorities ));
449+ }
450+
451+ private AuthorityAuthorizationManager <RequestAuthorizationContext > withRoleHierarchy (
452+ AuthorityAuthorizationManager <RequestAuthorizationContext > manager ) {
453+ manager .setRoleHierarchy (this .roleHierarchy .get ());
454+ return manager ;
455+ }
456+
457+ }
458+
406459}
0 commit comments