SEC-1640: Add support for "this" property to MethodSecurityExpressionRoot object, representing the object on which the method is actually being invoked.

This commit is contained in:
Luke Taylor 2011-02-17 17:50:46 +00:00
parent 0b1beee432
commit 4a7608b7a9
3 changed files with 41 additions and 3 deletions

View File

@ -47,6 +47,7 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
@Override
protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(permissionEvaluator);
return root;

View File

@ -1,8 +1,5 @@
package org.springframework.security.access.expression.method;
import java.io.Serializable;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.core.Authentication;
@ -16,6 +13,7 @@ import org.springframework.security.core.Authentication;
class MethodSecurityExpressionRoot extends SecurityExpressionRoot {
private Object filterObject;
private Object returnObject;
private Object target;
MethodSecurityExpressionRoot(Authentication a) {
super(a);
@ -37,4 +35,17 @@ class MethodSecurityExpressionRoot extends SecurityExpressionRoot {
return returnObject;
}
/**
* Sets the "this" property for use in expressions. Typically this will be the "this" property of
* the {@code JoinPoint} representing the method invocation which is being protected.
*
* @param target the target object on which the method in is being invoked.
*/
void setThis(Object target) {
this.target = target;
}
public Object getThis() {
return target;
}
}

View File

@ -15,6 +15,8 @@ import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import java.util.*;
/**
* Tests for {@link MethodSecurityExpressionRoot}
*
@ -102,4 +104,28 @@ public class MethodSecurityExpressionRootTests {
// evaluator returns false, make sure return value matches
assertFalse(ExpressionUtils.evaluateAsBoolean(e, ctx));
}
@Test
public void hasPermissionWorksWithThisObject() throws Exception {
Object targetObject = new Object() {
public String getX() {
return "x";
}
};
root.setThis(targetObject);
Integer i = 2;
PermissionEvaluator pe = mock(PermissionEvaluator.class);
root.setPermissionEvaluator(pe);
when(pe.hasPermission(user, targetObject, i)).thenReturn(true)
.thenReturn(false);
when(pe.hasPermission(user, "x", i)).thenReturn(true);
Expression e = parser.parseExpression("hasPermission(this, 2)");
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(this, 2)");
assertFalse(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(this.x, 2)");
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
}
}