Skip to content

Commit df4da33

Browse files
committed
Use AuthorizationManagerFactory for authorizeHttpRequests
Issue gh-17585 Signed-off-by: Steve Riesenberg <[email protected]>
1 parent bfa78c3 commit df4da33

File tree

2 files changed

+409
-34
lines changed

2 files changed

+409
-34
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurer.java

Lines changed: 85 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@
2727
import org.springframework.core.ResolvableType;
2828
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
2929
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
30-
import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
3130
import org.springframework.security.authorization.AuthorityAuthorizationManager;
3231
import org.springframework.security.authorization.AuthorizationDecision;
3332
import org.springframework.security.authorization.AuthorizationEventPublisher;
3433
import org.springframework.security.authorization.AuthorizationManager;
34+
import org.springframework.security.authorization.AuthorizationManagerFactory;
3535
import org.springframework.security.authorization.AuthorizationManagers;
36-
import org.springframework.security.authorization.SingleResultAuthorizationManager;
3736
import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
3837
import org.springframework.security.config.ObjectPostProcessor;
3938
import 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

Comments
 (0)