Skip to content

Commit d8d5eb7

Browse files
committed
Add AuthorizationManagerFactory
Signed-off-by: Steve Riesenberg <[email protected]>
1 parent 36f1de9 commit d8d5eb7

File tree

20 files changed

+1148
-175
lines changed

20 files changed

+1148
-175
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: 50 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,13 +44,13 @@
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}.
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
*/
5856
public 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

Comments
 (0)