diff --git a/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java b/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java index 82f295ab23d..9dc9037a780 100644 --- a/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java +++ b/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java @@ -56,27 +56,42 @@ public boolean before(Authentication authentication, MethodInvocation mi, PreInv } private Object findFilterTarget(String filterTargetName, EvaluationContext ctx, MethodInvocation invocation) { - Object filterTarget = null; + Object filterTarget; + if (filterTargetName.length() > 0) { filterTarget = ctx.lookupVariable(filterTargetName); Assert.notNull(filterTarget, - () -> "Filter target was null, or no argument with name " + filterTargetName + " found in method"); - } - else if (invocation.getArguments().length == 1) { - Object arg = invocation.getArguments()[0]; - if (arg.getClass().isArray() || arg instanceof Collection) { - filterTarget = arg; - } - Assert.notNull(filterTarget, () -> "A PreFilter expression was set but the method argument type" - + arg.getClass() + " is not filterable"); + () -> new StringBuilder("Filter target was null, or no argument with name ").append(filterTargetName).append(" found in method").toString()); + assertIsNotOfTypeArray(filterTarget); + + return filterTarget; } - else if (invocation.getArguments().length > 1) { + + Object[] args = invocation.getArguments(); + + if (args.length > 1) { throw new IllegalArgumentException( "Unable to determine the method argument for filtering. Specify the filter target."); } + + if (args.length == 1 && firstArgIsArrayOrCollection(args[0])) { + filterTarget = args[0]; + Assert.notNull(filterTarget, () -> new StringBuilder("A PreFilter expression was set but the method argument type") + .append(args[0].getClass()).append(" is not filterable").toString()); + assertIsNotOfTypeArray(filterTarget); + return filterTarget; + } + + throw new IllegalStateException("Unexpected either filterTargetName or invocation arguments provided. Provide either the target name or invocation argument with one argument"); + } + + private boolean firstArgIsArrayOrCollection(Object arg) { + return arg.getClass().isArray() || arg instanceof Collection; + } + + private void assertIsNotOfTypeArray(Object filterTarget) { Assert.isTrue(!filterTarget.getClass().isArray(), "Pre-filtering on array types is not supported. Using a Collection will solve this problem"); - return filterTarget; } public void setExpressionHandler(MethodSecurityExpressionHandler expressionHandler) {