Skip to content

Commit 4ef91a4

Browse files
committed
Add AuthorizationManagerFactory
Signed-off-by: Steve Riesenberg <[email protected]>
1 parent a5c38bd commit 4ef91a4

File tree

18 files changed

+979
-176
lines changed

18 files changed

+979
-176
lines changed

config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
3838
import org.springframework.security.aot.hint.PrePostAuthorizeHintsRegistrar;
3939
import org.springframework.security.aot.hint.SecurityHintsRegistrar;
40+
import org.springframework.security.authentication.AuthenticationTrustResolver;
4041
import org.springframework.security.authorization.AuthorizationEventPublisher;
4142
import org.springframework.security.authorization.AuthorizationManager;
43+
import org.springframework.security.authorization.AuthorizationManagerFactory;
4244
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
4345
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
4446
import org.springframework.security.authorization.method.MethodInvocationResult;
@@ -121,6 +123,16 @@ void setRoleHierarchy(RoleHierarchy roleHierarchy) {
121123
this.expressionHandler.setRoleHierarchy(roleHierarchy);
122124
}
123125

126+
@Autowired(required = false)
127+
void setTrustResolver(AuthenticationTrustResolver trustResolver) {
128+
this.expressionHandler.setTrustResolver(trustResolver);
129+
}
130+
131+
@Autowired(required = false)
132+
void setAuthorizationManagerFactory(AuthorizationManagerFactory<MethodInvocation> authorizationManagerFactory) {
133+
this.expressionHandler.setAuthorizationManagerFactory(authorizationManagerFactory);
134+
}
135+
124136
@Autowired(required = false)
125137
void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) {
126138
this.preFilterMethodInterceptor.setTemplateDefaults(templateDefaults);

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

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.util.List;
2020
import java.util.function.Function;
21-
import java.util.function.Supplier;
2221

2322
import jakarta.servlet.http.HttpServletRequest;
2423

@@ -27,13 +26,12 @@
2726
import org.springframework.core.ResolvableType;
2827
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
2928
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
30-
import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
31-
import org.springframework.security.authorization.AuthorityAuthorizationManager;
3229
import org.springframework.security.authorization.AuthorizationDecision;
3330
import org.springframework.security.authorization.AuthorizationEventPublisher;
3431
import org.springframework.security.authorization.AuthorizationManager;
32+
import org.springframework.security.authorization.AuthorizationManagerFactory;
3533
import org.springframework.security.authorization.AuthorizationManagers;
36-
import org.springframework.security.authorization.SingleResultAuthorizationManager;
34+
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory;
3735
import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
3836
import org.springframework.security.config.ObjectPostProcessor;
3937
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
@@ -46,7 +44,6 @@
4644
import org.springframework.security.web.util.matcher.RequestMatcher;
4745
import org.springframework.security.web.util.matcher.RequestMatcherEntry;
4846
import 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

Comments
 (0)