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}.
5350 *
5451 * @param <H> the type of {@link HttpSecurityBuilder} that is being configured.
5552 * @author Evgeniy Cheban
53+ * @author Steve Riesenberg
5654 * @since 5.5
5755 */
5856public final class AuthorizeHttpRequestsConfigurer <H extends HttpSecurityBuilder <H >>
@@ -62,9 +60,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
6260
6361 private final AuthorizationEventPublisher publisher ;
6462
65- private final Supplier <RoleHierarchy > roleHierarchy ;
66-
67- private String rolePrefix = "ROLE_" ;
63+ private final AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
6864
6965 private ObjectPostProcessor <AuthorizationManager <HttpServletRequest >> postProcessor = ObjectPostProcessor
7066 .identity ();
@@ -81,20 +77,36 @@ public AuthorizeHttpRequestsConfigurer(ApplicationContext context) {
8177 else {
8278 this .publisher = new SpringAuthorizationEventPublisher (context );
8379 }
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 );
9181 ResolvableType type = ResolvableType .forClassWithGenerics (ObjectPostProcessor .class ,
9282 ResolvableType .forClassWithGenerics (AuthorizationManager .class , HttpServletRequest .class ));
9383 ObjectProvider <ObjectPostProcessor <AuthorizationManager <HttpServletRequest >>> provider = context
9484 .getBeanProvider (type );
9585 provider .ifUnique ((postProcessor ) -> this .postProcessor = postProcessor );
9686 }
9787
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+
98110 /**
99111 * The {@link AuthorizationManagerRequestMatcherRegistry} is what users will interact
100112 * with after applying the {@link AuthorizeHttpRequestsConfigurer}.
@@ -173,7 +185,7 @@ private AuthorizationManager<HttpServletRequest> createAuthorizationManager() {
173185 @ Override
174186 protected AuthorizedUrl chainRequestMatchers (List <RequestMatcher > requestMatchers ) {
175187 this .unmappedMatchers = requestMatchers ;
176- return new AuthorizedUrl (requestMatchers );
188+ return new AuthorizedUrl (requestMatchers , AuthorizeHttpRequestsConfigurer . this . authorizationManagerFactory );
177189 }
178190
179191 /**
@@ -201,20 +213,31 @@ public class AuthorizedUrl {
201213
202214 private final List <? extends RequestMatcher > matchers ;
203215
216+ private AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ;
217+
204218 private boolean not ;
205219
206220 /**
207221 * Creates an instance.
208222 * @param matchers the {@link RequestMatcher} instances to map
223+ * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} for
224+ * creating instances of {@link AuthorizationManager}
209225 */
210- AuthorizedUrl (List <? extends RequestMatcher > matchers ) {
226+ AuthorizedUrl (List <? extends RequestMatcher > matchers ,
227+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
211228 this .matchers = matchers ;
229+ this .authorizationManagerFactory = authorizationManagerFactory ;
212230 }
213231
214232 protected List <? extends RequestMatcher > getMatchers () {
215233 return this .matchers ;
216234 }
217235
236+ void setAuthorizationManagerFactory (
237+ AuthorizationManagerFactory <RequestAuthorizationContext > authorizationManagerFactory ) {
238+ this .authorizationManagerFactory = authorizationManagerFactory ;
239+ }
240+
218241 /**
219242 * Negates the following authorization rule.
220243 * @return the {@link AuthorizedUrl} for further customization
@@ -231,7 +254,7 @@ public AuthorizedUrl not() {
231254 * customizations
232255 */
233256 public AuthorizationManagerRequestMatcherRegistry permitAll () {
234- return access (SingleResultAuthorizationManager .permitAll ());
257+ return access (this . authorizationManagerFactory .permitAll ());
235258 }
236259
237260 /**
@@ -240,7 +263,7 @@ public AuthorizationManagerRequestMatcherRegistry permitAll() {
240263 * customizations
241264 */
242265 public AuthorizationManagerRequestMatcherRegistry denyAll () {
243- return access (SingleResultAuthorizationManager .denyAll ());
266+ return access (this . authorizationManagerFactory .denyAll ());
244267 }
245268
246269 /**
@@ -251,8 +274,7 @@ public AuthorizationManagerRequestMatcherRegistry denyAll() {
251274 * customizations
252275 */
253276 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 ));
256278 }
257279
258280 /**
@@ -264,8 +286,7 @@ public AuthorizationManagerRequestMatcherRegistry hasRole(String role) {
264286 * customizations
265287 */
266288 public AuthorizationManagerRequestMatcherRegistry hasAnyRole (String ... roles ) {
267- return access (withRoleHierarchy (
268- AuthorityAuthorizationManager .hasAnyRole (AuthorizeHttpRequestsConfigurer .this .rolePrefix , roles )));
289+ return access (this .authorizationManagerFactory .hasAnyRole (roles ));
269290 }
270291
271292 /**
@@ -275,7 +296,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAnyRole(String... roles) {
275296 * customizations
276297 */
277298 public AuthorizationManagerRequestMatcherRegistry hasAuthority (String authority ) {
278- return access (withRoleHierarchy ( AuthorityAuthorizationManager . hasAuthority (authority ) ));
299+ return access (this . authorizationManagerFactory . hasAuthority (authority ));
279300 }
280301
281302 /**
@@ -286,13 +307,7 @@ public AuthorizationManagerRequestMatcherRegistry hasAuthority(String authority)
286307 * customizations
287308 */
288309 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 ));
296311 }
297312
298313 /**
@@ -301,7 +316,7 @@ private AuthorityAuthorizationManager<RequestAuthorizationContext> withRoleHiera
301316 * customizations
302317 */
303318 public AuthorizationManagerRequestMatcherRegistry authenticated () {
304- return access (AuthenticatedAuthorizationManager .authenticated ());
319+ return access (this . authorizationManagerFactory .authenticated ());
305320 }
306321
307322 /**
@@ -313,7 +328,7 @@ public AuthorizationManagerRequestMatcherRegistry authenticated() {
313328 * @see RememberMeConfigurer
314329 */
315330 public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated () {
316- return access (AuthenticatedAuthorizationManager .fullyAuthenticated ());
331+ return access (this . authorizationManagerFactory .fullyAuthenticated ());
317332 }
318333
319334 /**
@@ -324,7 +339,7 @@ public AuthorizationManagerRequestMatcherRegistry fullyAuthenticated() {
324339 * @see RememberMeConfigurer
325340 */
326341 public AuthorizationManagerRequestMatcherRegistry rememberMe () {
327- return access (AuthenticatedAuthorizationManager .rememberMe ());
342+ return access (this . authorizationManagerFactory .rememberMe ());
328343 }
329344
330345 /**
@@ -334,7 +349,7 @@ public AuthorizationManagerRequestMatcherRegistry rememberMe() {
334349 * @since 5.8
335350 */
336351 public AuthorizationManagerRequestMatcherRegistry anonymous () {
337- return access (AuthenticatedAuthorizationManager .anonymous ());
352+ return access (this . authorizationManagerFactory .anonymous ());
338353 }
339354
340355 /**
0 commit comments