1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Add AuthorizationManagerFactory

Signed-off-by: Steve Riesenberg <5248162+sjohnr@users.noreply.github.com>
This commit is contained in:
Steve Riesenberg
2025-09-02 12:47:53 -05:00
committed by Rob Winch
parent a4f813ab29
commit eeb4574bb3
37 changed files with 2719 additions and 178 deletions
@@ -27,6 +27,7 @@ import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.access.expression.SecurityExpressionOperations;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.authorization.AuthorizationManagerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.util.Assert;
@@ -36,14 +37,15 @@ import org.springframework.util.Assert;
* create a {@link WebSecurityExpressionRoot}.
*
* @author Evgeniy Cheban
* @author Steve Riesenberg
* @since 5.8
*/
public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpressionHandler<RequestAuthorizationContext>
implements SecurityExpressionHandler<RequestAuthorizationContext> {
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private static final String DEFAULT_ROLE_PREFIX = "ROLE_";
private String defaultRolePrefix = "ROLE_";
private String defaultRolePrefix = DEFAULT_ROLE_PREFIX;
@Override
@SuppressWarnings("NullAway") // https://github.com/spring-projects/spring-framework/issues/35371
@@ -64,11 +66,13 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
private WebSecurityExpressionRoot createSecurityExpressionRoot(
Supplier<? extends @Nullable Authentication> authentication, RequestAuthorizationContext context) {
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, context.getRequest());
root.setRoleHierarchy(getRoleHierarchy());
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, context);
root.setAuthorizationManagerFactory(getAuthorizationManagerFactory());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setDefaultRolePrefix(this.defaultRolePrefix);
if (!DEFAULT_ROLE_PREFIX.equals(this.defaultRolePrefix)) {
// Ensure SecurityExpressionRoot can strip the custom role prefix
root.setDefaultRolePrefix(this.defaultRolePrefix);
}
return root;
}
@@ -76,10 +80,12 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
* Sets the {@link AuthenticationTrustResolver} to be used. The default is
* {@link AuthenticationTrustResolverImpl}.
* @param trustResolver the {@link AuthenticationTrustResolver} to use
* @deprecated Use
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
*/
@Deprecated(since = "7.0")
public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
Assert.notNull(trustResolver, "trustResolver cannot be null");
this.trustResolver = trustResolver;
getDefaultAuthorizationManagerFactory().setTrustResolver(trustResolver);
}
/**
@@ -91,9 +97,13 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
* role ROLE_ADMIN will be used when the defaultRolePrefix is "ROLE_" (default).
* @param defaultRolePrefix the default prefix to add to roles. The default is
* "ROLE_".
* @deprecated Use
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
*/
@Deprecated(since = "7.0")
public void setDefaultRolePrefix(String defaultRolePrefix) {
Assert.notNull(defaultRolePrefix, "defaultRolePrefix cannot be null");
getDefaultAuthorizationManagerFactory().setRolePrefix(defaultRolePrefix);
this.defaultRolePrefix = defaultRolePrefix;
}
@@ -23,30 +23,33 @@ import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.access.expression.SecurityExpressionOperations;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.authorization.AuthorizationManagerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.util.Assert;
/**
* @author Luke Taylor
* @author Eddú Meléndez
* @author Steve Riesenberg
* @since 3.0
*/
public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpressionHandler<FilterInvocation>
implements SecurityExpressionHandler<FilterInvocation> {
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private static final String DEFAULT_ROLE_PREFIX = "ROLE_";
private String defaultRolePrefix = "ROLE_";
private String defaultRolePrefix = DEFAULT_ROLE_PREFIX;
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication,
FilterInvocation fi) {
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
FilterInvocationExpressionRoot root = new FilterInvocationExpressionRoot(() -> authentication, fi);
root.setAuthorizationManagerFactory(getAuthorizationManagerFactory());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
root.setDefaultRolePrefix(this.defaultRolePrefix);
if (!DEFAULT_ROLE_PREFIX.equals(this.defaultRolePrefix)) {
// Ensure SecurityExpressionRoot can strip the custom role prefix
root.setDefaultRolePrefix(this.defaultRolePrefix);
}
return root;
}
@@ -55,10 +58,12 @@ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpress
* {@link AuthenticationTrustResolverImpl}.
* @param trustResolver the {@link AuthenticationTrustResolver} to use. Cannot be
* null.
* @deprecated Use
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
*/
@Deprecated(since = "7.0")
public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
Assert.notNull(trustResolver, "trustResolver cannot be null");
this.trustResolver = trustResolver;
getDefaultAuthorizationManagerFactory().setTrustResolver(trustResolver);
}
/**
@@ -75,8 +80,15 @@ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpress
* If null or empty, then no default role prefix is used.
* </p>
* @param defaultRolePrefix the default prefix to add to roles. Default "ROLE_".
* @deprecated Use
* {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
*/
public void setDefaultRolePrefix(String defaultRolePrefix) {
@Deprecated(since = "7.0")
public void setDefaultRolePrefix(@Nullable String defaultRolePrefix) {
if (defaultRolePrefix == null) {
defaultRolePrefix = "";
}
getDefaultAuthorizationManagerFactory().setRolePrefix(defaultRolePrefix);
this.defaultRolePrefix = defaultRolePrefix;
}
@@ -0,0 +1,62 @@
/*
* Copyright 2004-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.access.expression;
import java.util.function.Supplier;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.IpAddressMatcher;
/**
* @author Steve Riesenberg
* @since 7.0
*/
final class FilterInvocationExpressionRoot extends SecurityExpressionRoot<FilterInvocation> {
/**
* Allows direct access to the request object
*/
public final HttpServletRequest request;
/**
* Creates an instance for the given {@link Supplier} of the {@link Authentication}
* and {@link HttpServletRequest}.
* @param authentication the {@link Supplier} of the {@link Authentication} to use
* @param fi the {@link FilterInvocation} to use
*/
FilterInvocationExpressionRoot(Supplier<Authentication> authentication, FilterInvocation fi) {
super(authentication, fi);
this.request = fi.getRequest();
}
/**
* Takes a specific IP address or a range using the IP/Netmask (e.g. 192.168.1.0/24 or
* 202.24.0.0/14).
* @param ipAddress the address or range of addresses from which the request must
* come.
* @return true if the IP address of the current request is in the required range.
*/
public boolean hasIpAddress(String ipAddress) {
IpAddressMatcher matcher = new IpAddressMatcher(ipAddress);
return matcher.matches(this.request);
}
}
@@ -24,22 +24,29 @@ import org.jspecify.annotations.Nullable;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.security.web.util.matcher.IpAddressMatcher;
/**
* @author Luke Taylor
* @author Evgeniy Cheban
* @author Steve Riesenberg
* @since 3.0
*/
public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
public class WebSecurityExpressionRoot extends SecurityExpressionRoot<RequestAuthorizationContext> {
/**
* Allows direct access to the request object
*/
public final HttpServletRequest request;
/**
* @deprecated Use
* {@link #WebSecurityExpressionRoot(Supplier, RequestAuthorizationContext)} instead
*/
@Deprecated(since = "7.0")
public WebSecurityExpressionRoot(@Nullable Authentication a, FilterInvocation fi) {
this(() -> a, fi.getRequest());
this(() -> a, new RequestAuthorizationContext(fi.getRequest()));
}
/**
@@ -48,14 +55,30 @@ public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
* @param authentication the {@link Supplier} of the {@link Authentication} to use
* @param request the {@link HttpServletRequest} to use
* @since 5.8
* @deprecated Use
* {@link #WebSecurityExpressionRoot(Supplier, RequestAuthorizationContext)} instead
*/
@Deprecated(since = "7.0")
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1246
public WebSecurityExpressionRoot(Supplier<? extends @Nullable Authentication> authentication,
HttpServletRequest request) {
super(authentication);
super(authentication, new RequestAuthorizationContext(request));
this.request = request;
}
/**
* Creates an instance for the given {@link Supplier} of the {@link Authentication}
* and {@link HttpServletRequest}.
* @param authentication the {@link Supplier} of the {@link Authentication} to use
* @param context the {@link RequestAuthorizationContext} to use
* @since 7.0
*/
public WebSecurityExpressionRoot(Supplier<? extends @Nullable Authentication> authentication,
RequestAuthorizationContext context) {
super(authentication, context);
this.request = context.getRequest();
}
/**
* Takes a specific IP address or a range using the IP/Netmask (e.g. 192.168.1.0/24 or
* 202.24.0.0/14).