1818
1919import java .util .List ;
2020import java .util .function .Function ;
21- import java .util .function .Supplier ;
2221
2322import jakarta .servlet .http .HttpServletRequest ;
2423
2726import org .springframework .core .ResolvableType ;
2827import org .springframework .security .access .hierarchicalroles .NullRoleHierarchy ;
2928import org .springframework .security .access .hierarchicalroles .RoleHierarchy ;
30- import org .springframework .security .authorization .AuthenticatedAuthorizationManager ;
31- import org .springframework .security .authorization .AuthorityAuthorizationManager ;
3229import org .springframework .security .authorization .AuthorizationDecision ;
3330import org .springframework .security .authorization .AuthorizationEventPublisher ;
3431import org .springframework .security .authorization .AuthorizationManager ;
32+ import org .springframework .security .authorization .AuthorizationManagerFactory ;
3533import org .springframework .security .authorization .AuthorizationManagers ;
36- import org .springframework .security .authorization .SingleResultAuthorizationManager ;
34+ import org .springframework .security .authorization .DefaultAuthorizationManagerFactory ;
3735import org .springframework .security .authorization .SpringAuthorizationEventPublisher ;
3836import org .springframework .security .config .ObjectPostProcessor ;
3937import org .springframework .security .config .annotation .web .AbstractRequestMatcherRegistry ;
4644import org .springframework .security .web .util .matcher .RequestMatcher ;
4745import org .springframework .security .web .util .matcher .RequestMatcherEntry ;
4846import org .springframework .util .Assert ;
49- import org .springframework .util .function .SingletonSupplier ;
5047
5148/**
5249 * Adds a URL based authorization using {@link AuthorizationManager}.
@@ -62,9 +59,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
6259
6360 private final AuthorizationEventPublisher publisher ;
6461
65- private final Supplier <RoleHierarchy > roleHierarchy ;
66-
67- private String rolePrefix = "ROLE_" ;
62+ private final AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
6863
6964 private ObjectPostProcessor <AuthorizationManager <HttpServletRequest >> postProcessor = ObjectPostProcessor
7065 .identity ();
@@ -81,20 +76,36 @@ public AuthorizeHttpRequestsConfigurer(ApplicationContext context) {
8176 else {
8277 this .publisher = new SpringAuthorizationEventPublisher (context );
8378 }
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 );
9180 ResolvableType type = ResolvableType .forClassWithGenerics (ObjectPostProcessor .class ,
9281 ResolvableType .forClassWithGenerics (AuthorizationManager .class , HttpServletRequest .class ));
9382 ObjectProvider <ObjectPostProcessor <AuthorizationManager <HttpServletRequest >>> provider = context
9483 .getBeanProvider (type );
9584 provider .ifUnique ((postProcessor ) -> this .postProcessor = postProcessor );
9685 }
9786
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+
98109 /**
99110 * The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100111 * with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +184,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173184 @ Override
174185 protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175186 this .unmappedMatchers = requestMatchers ;
176- return new AuthorizedUrl (requestMatchers );
187+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177188 }
178189
179190 /**
@@ -201,20 +212,31 @@ public class AuthorizedUrl {
201212
202213 private final List <? extends RequestMatcher > matchers ;
203214
215+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
216+
204217 private boolean not ;
205218
206219 /**
207220 * Creates an instance.
208221 * @param matchers the {@link RequestMatcher} instances to map
222+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
223+ * creating instances of {@link AuthorizationManager}
209224 */
210- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
225+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
226+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211227 this .matchers = matchers ;
228+ this .authorizationManagerFactory = authorizationManagerFactory ;
212229 }
213230
214231 protected List <? extends RequestMatcher > getMatchers () {
215232 return this .matchers ;
216233 }
217234
235+ void setAuthorizationManagerFactory (
236+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
237+ this .authorizationManagerFactory = authorizationManagerFactory ;
238+ }
239+
218240 /**
219241 * Negates the following authorization rule.
220242 * @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +253,7 @@ public AuthorizedUrl not() {
231253 * customizations
232254 */
233255 public AuthorizationManagerRequestMatcherRegistry permitAll () {
234- return access (SingleResultAuthorizationManager .permitAll ());
256+ return access (this . authorizationManagerFactory .permitAll ());
235257 }
236258
237259 /**
@@ -240,7 +262,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240262 * customizations
241263 */
242264 public AuthorizationManagerRequestMatcherRegistry denyAll () {
243- return access (SingleResultAuthorizationManager .denyAll ());
265+ return access (this . authorizationManagerFactory .denyAll ());
244266 }
245267
246268 /**
@@ -251,8 +273,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251273 * customizations
252274 */
253275 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 ));
256277 }
257278
258279 /**
@@ -264,8 +285,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264285 * customizations
265286 */
266287 public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267- return access (withRoleHierarchy (
268- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
288+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269289 }
270290
271291 /**
@@ -275,7 +295,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275295 * customizations
276296 */
277297 public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
298+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279299 }
280300
281301 /**
@@ -286,13 +306,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286306 * customizations
287307 */
288308 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 ));
296310 }
297311
298312 /**
@@ -301,7 +315,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301315 * customizations
302316 */
303317 public AuthorizationManagerRequestMatcherRegistry authenticated () {
304- return access (AuthenticatedAuthorizationManager .authenticated ());
318+ return access (this . authorizationManagerFactory .authenticated ());
305319 }
306320
307321 /**
@@ -313,7 +327,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313327 * @see RememberMeConfigurer
314328 */
315329 public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
330+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317331 }
318332
319333 /**
@@ -324,7 +338,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324338 * @see RememberMeConfigurer
325339 */
326340 public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327- return access (AuthenticatedAuthorizationManager .rememberMe ());
341+ return access (this . authorizationManagerFactory .rememberMe ());
328342 }
329343
330344 /**
@@ -334,7 +348,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334348 * @since 5.8
335349 */
336350 public AuthorizationManagerRequestMatcherRegistry anonymous () {
337- return access (AuthenticatedAuthorizationManager .anonymous ());
351+ return access (this . authorizationManagerFactory .anonymous ());
338352 }
339353
340354 /**
0 commit comments