Skip to content

Commit 04fdabe

Browse files
committed
Update SecurityExpressionRoot to use AuthorizationManagerFactory
Signed-off-by: Steve Riesenberg <[email protected]>
1 parent 2cea5f9 commit 04fdabe

File tree

1 file changed

+78
-65
lines changed

1 file changed

+78
-65
lines changed
Lines changed: 78 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,19 +17,18 @@
1717
package org.springframework.security.access.expression;
1818

1919
import java.io.Serializable;
20-
import java.util.Collection;
21-
import java.util.Set;
2220
import java.util.function.Supplier;
2321

2422
import org.jspecify.annotations.Nullable;
2523

2624
import org.springframework.security.access.PermissionEvaluator;
2725
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
2826
import org.springframework.security.authentication.AuthenticationTrustResolver;
29-
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
27+
import org.springframework.security.authorization.AuthorizationManager;
28+
import org.springframework.security.authorization.AuthorizationManagerFactory;
29+
import org.springframework.security.authorization.AuthorizationResult;
30+
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory;
3031
import org.springframework.security.core.Authentication;
31-
import org.springframework.security.core.GrantedAuthority;
32-
import org.springframework.security.core.authority.AuthorityUtils;
3332
import org.springframework.util.Assert;
3433
import org.springframework.util.function.SingletonSupplier;
3534

@@ -42,15 +41,17 @@
4241
*/
4342
public abstract class SecurityExpressionRoot implements SecurityExpressionOperations {
4443

45-
private final Supplier<Authentication> authentication;
44+
private static final AuthorizationManagerFactory<Object> DEFAULT_AUTHORIZATION_MANAGER_FACTORY = new DefaultAuthorizationManagerFactory<>();
45+
46+
private static final Object DEFAULT_OBJECT = new Object();
4647

47-
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
48+
private final Supplier<Authentication> authentication;
4849

49-
private @Nullable RoleHierarchy roleHierarchy;
50+
private final Object object;
5051

51-
private @Nullable Set<String> roles;
52+
private @Nullable DefaultAuthorizationManagerFactory<Object> defaultAuthorizationManagerFactory;
5253

53-
private String defaultRolePrefix = "ROLE_";
54+
private AuthorizationManagerFactory<Object> authorizationManagerFactory = DEFAULT_AUTHORIZATION_MANAGER_FACTORY;
5455

5556
/**
5657
* Allows "permitAll" expression
@@ -77,9 +78,11 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat
7778
/**
7879
* Creates a new instance
7980
* @param authentication the {@link Authentication} to use. Cannot be null.
81+
* @deprecated use {@link #SecurityExpressionRoot(Supplier, Object)} instead
8082
*/
83+
@Deprecated(since = "7.0")
8184
public SecurityExpressionRoot(Authentication authentication) {
82-
this(() -> authentication);
85+
this(() -> authentication, DEFAULT_OBJECT);
8386
}
8487

8588
/**
@@ -88,44 +91,48 @@ public SecurityExpressionRoot(Authentication authentication) {
8891
* @param authentication the {@link Supplier} of the {@link Authentication} to use.
8992
* Cannot be null.
9093
* @since 5.8
94+
* @deprecated use {@link #SecurityExpressionRoot(Supplier, Object)} instead
9195
*/
96+
@Deprecated(since = "7.0")
9297
public SecurityExpressionRoot(Supplier<Authentication> authentication) {
98+
this(authentication, DEFAULT_OBJECT);
99+
}
100+
101+
/**
102+
* Creates a new instance that uses lazy initialization of the {@link Authentication}
103+
* object.
104+
* @param authentication the {@link Supplier} of the {@link Authentication} to use.
105+
* Cannot be null.
106+
* @param object the object being authorized
107+
* @since 7.0
108+
*/
109+
public SecurityExpressionRoot(Supplier<Authentication> authentication, Object object) {
93110
this.authentication = SingletonSupplier.of(() -> {
94111
Authentication value = authentication.get();
95112
Assert.notNull(value, "Authentication object cannot be null");
96113
return value;
97114
});
115+
this.object = object;
98116
}
99117

100118
@Override
101119
public final boolean hasAuthority(String authority) {
102-
return hasAnyAuthority(authority);
120+
return isGranted(this.authorizationManagerFactory.hasAnyAuthority(authority));
103121
}
104122

105123
@Override
106124
public final boolean hasAnyAuthority(String... authorities) {
107-
return hasAnyAuthorityName(null, authorities);
125+
return isGranted(this.authorizationManagerFactory.hasAnyAuthority(authorities));
108126
}
109127

110128
@Override
111129
public final boolean hasRole(String role) {
112-
return hasAnyRole(role);
130+
return isGranted(this.authorizationManagerFactory.hasRole(role));
113131
}
114132

115133
@Override
116134
public final boolean hasAnyRole(String... roles) {
117-
return hasAnyAuthorityName(this.defaultRolePrefix, roles);
118-
}
119-
120-
private boolean hasAnyAuthorityName(@Nullable String prefix, String... roles) {
121-
Set<String> roleSet = getAuthoritySet();
122-
for (String role : roles) {
123-
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
124-
if (roleSet.contains(defaultedRole)) {
125-
return true;
126-
}
127-
}
128-
return false;
135+
return isGranted(this.authorizationManagerFactory.hasAnyRole(roles));
129136
}
130137

131138
@Override
@@ -135,33 +142,37 @@ public final Authentication getAuthentication() {
135142

136143
@Override
137144
public final boolean permitAll() {
138-
return true;
145+
return isGranted(this.authorizationManagerFactory.permitAll());
139146
}
140147

141148
@Override
142149
public final boolean denyAll() {
143-
return false;
150+
return isGranted(this.authorizationManagerFactory.denyAll());
144151
}
145152

146153
@Override
147154
public final boolean isAnonymous() {
148-
return this.trustResolver.isAnonymous(getAuthentication());
155+
return isGranted(this.authorizationManagerFactory.anonymous());
149156
}
150157

151158
@Override
152159
public final boolean isAuthenticated() {
153-
return this.trustResolver.isAuthenticated(getAuthentication());
160+
return isGranted(this.authorizationManagerFactory.authenticated());
154161
}
155162

156163
@Override
157164
public final boolean isRememberMe() {
158-
return this.trustResolver.isRememberMe(getAuthentication());
165+
return isGranted(this.authorizationManagerFactory.rememberMe());
159166
}
160167

161168
@Override
162169
public final boolean isFullyAuthenticated() {
163-
Authentication authentication = getAuthentication();
164-
return this.trustResolver.isFullyAuthenticated(authentication);
170+
return isGranted(this.authorizationManagerFactory.fullyAuthenticated());
171+
}
172+
173+
private boolean isGranted(AuthorizationManager<Object> authorizationManager) {
174+
AuthorizationResult authorizationResult = authorizationManager.authorize(this.authentication, this.object);
175+
return (authorizationResult != null && authorizationResult.isGranted());
165176
}
166177

167178
/**
@@ -173,12 +184,22 @@ public final boolean isFullyAuthenticated() {
173184
return getAuthentication().getPrincipal();
174185
}
175186

187+
/**
188+
* @deprecated Use
189+
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
190+
*/
191+
@Deprecated(since = "7.0")
176192
public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
177-
this.trustResolver = trustResolver;
193+
getDefaultAuthorizationManagerFactory().setTrustResolver(trustResolver);
178194
}
179195

196+
/**
197+
* @deprecated Use
198+
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
199+
*/
200+
@Deprecated(since = "7.0")
180201
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
181-
this.roleHierarchy = roleHierarchy;
202+
getDefaultAuthorizationManagerFactory().setRoleHierarchy(roleHierarchy);
182203
}
183204

184205
/**
@@ -193,20 +214,32 @@ public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
193214
* If null or empty, then no default role prefix is used.
194215
* </p>
195216
* @param defaultRolePrefix the default prefix to add to roles. Default "ROLE_".
217+
* @deprecated Use
218+
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
196219
*/
220+
@Deprecated(since = "7.0")
197221
public void setDefaultRolePrefix(String defaultRolePrefix) {
198-
this.defaultRolePrefix = defaultRolePrefix;
222+
getDefaultAuthorizationManagerFactory().setRolePrefix(defaultRolePrefix);
223+
}
224+
225+
/**
226+
* Sets the {@link AuthorizationManagerFactory} to use for creating instances of
227+
* {@link AuthorizationManager}.
228+
* @param authorizationManagerFactory the {@link AuthorizationManagerFactory} to use
229+
* @since 7.0
230+
*/
231+
public void setAuthorizationManagerFactory(AuthorizationManagerFactory<Object> authorizationManagerFactory) {
232+
Assert.notNull(authorizationManagerFactory, "authorizationManagerFactory cannot be null");
233+
this.authorizationManagerFactory = authorizationManagerFactory;
199234
}
200235

201-
private Set<String> getAuthoritySet() {
202-
if (this.roles == null) {
203-
Collection<? extends GrantedAuthority> userAuthorities = getAuthentication().getAuthorities();
204-
if (this.roleHierarchy != null) {
205-
userAuthorities = this.roleHierarchy.getReachableGrantedAuthorities(userAuthorities);
206-
}
207-
this.roles = AuthorityUtils.authorityListToSet(userAuthorities);
236+
private DefaultAuthorizationManagerFactory<Object> getDefaultAuthorizationManagerFactory() {
237+
if (this.defaultAuthorizationManagerFactory == null) {
238+
this.defaultAuthorizationManagerFactory = new DefaultAuthorizationManagerFactory<>();
239+
this.authorizationManagerFactory = this.defaultAuthorizationManagerFactory;
208240
}
209-
return this.roles;
241+
242+
return this.defaultAuthorizationManagerFactory;
210243
}
211244

212245
@Override
@@ -225,24 +258,4 @@ public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) {
225258
this.permissionEvaluator = permissionEvaluator;
226259
}
227260

228-
/**
229-
* Prefixes role with defaultRolePrefix if defaultRolePrefix is non-null and if role
230-
* does not already start with defaultRolePrefix.
231-
* @param defaultRolePrefix
232-
* @param role
233-
* @return
234-
*/
235-
private static String getRoleWithDefaultPrefix(@Nullable String defaultRolePrefix, String role) {
236-
if (role == null) {
237-
return role;
238-
}
239-
if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
240-
return role;
241-
}
242-
if (role.startsWith(defaultRolePrefix)) {
243-
return role;
244-
}
245-
return defaultRolePrefix + role;
246-
}
247-
248261
}

0 commit comments

Comments
 (0)