Browse Source

SEC-1749: Add support for PageContext lookup of objects and use of PermissionEvaluator when using web access expressions.

pull/1/head
Luke Taylor 15 years ago
parent
commit
63f160dc72
  1. 10
      core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java
  2. 4
      core/src/main/java/org/springframework/security/access/expression/DenyAllPermissionEvaluator.java
  3. 8
      core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java
  4. 13
      core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContext.java
  5. 13
      taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java
  6. 76
      taglibs/src/main/java/org/springframework/security/taglibs/authz/JspAuthorizeTag.java
  7. 10
      taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagTests.java
  8. 4
      web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java

10
core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java

@ -8,6 +8,7 @@ import org.springframework.expression.EvaluationContext; @@ -8,6 +8,7 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
@ -25,6 +26,7 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx @@ -25,6 +26,7 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx
private final ExpressionParser expressionParser = new SpelExpressionParser();
private BeanResolver br;
private RoleHierarchy roleHierarchy;
private PermissionEvaluator permissionEvaluator = new DenyAllPermissionEvaluator();
public final ExpressionParser getExpressionParser() {
return expressionParser;
@ -77,6 +79,14 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx @@ -77,6 +79,14 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx
this.roleHierarchy = roleHierarchy;
}
protected PermissionEvaluator getPermissionEvaluator() {
return permissionEvaluator;
}
public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) {
this.permissionEvaluator = permissionEvaluator;
}
public void setApplicationContext(ApplicationContext applicationContext) {
br = new BeanFactoryResolver(applicationContext);
}

4
core/src/main/java/org/springframework/security/access/expression/method/DenyAllPermissionEvaluator.java → core/src/main/java/org/springframework/security/access/expression/DenyAllPermissionEvaluator.java

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package org.springframework.security.access.expression.method;
package org.springframework.security.access.expression;
import java.io.Serializable;
@ -14,7 +14,7 @@ import org.springframework.security.core.Authentication; @@ -14,7 +14,7 @@ import org.springframework.security.core.Authentication;
* @author Luke Taylor
* @since 3.0
*/
class DenyAllPermissionEvaluator implements PermissionEvaluator {
public class DenyAllPermissionEvaluator implements PermissionEvaluator {
private final Log logger = LogFactory.getLog(getClass());

8
core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java

@ -14,6 +14,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -14,6 +14,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.PermissionCacheOptimizer;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.AbstractSecurityExpressionHandler;
import org.springframework.security.access.expression.DenyAllPermissionEvaluator;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.core.Authentication;
@ -31,7 +32,6 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr @@ -31,7 +32,6 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
protected final Log logger = LogFactory.getLog(getClass());
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
private PermissionEvaluator permissionEvaluator = new DenyAllPermissionEvaluator();
private PermissionCacheOptimizer permissionCacheOptimizer = null;
public DefaultMethodSecurityExpressionHandler() {
@ -48,7 +48,7 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr @@ -48,7 +48,7 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(permissionEvaluator);
root.setPermissionEvaluator(getPermissionEvaluator());
return root;
}
@ -140,10 +140,6 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr @@ -140,10 +140,6 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) {
this.permissionEvaluator = permissionEvaluator;
}
public void setPermissionCacheOptimizer(PermissionCacheOptimizer permissionCacheOptimizer) {
this.permissionCacheOptimizer = permissionCacheOptimizer;
}

13
core/src/main/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContext.java

@ -7,8 +7,6 @@ import org.apache.commons.logging.Log; @@ -7,8 +7,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@ -27,7 +25,6 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext { @@ -27,7 +25,6 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext {
private ParameterNameDiscoverer parameterNameDiscoverer;
private final MethodInvocation mi;
private ApplicationContext appContext;
private boolean argumentsAdded;
/**
@ -64,16 +61,6 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext { @@ -64,16 +61,6 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext {
return variable;
}
if (appContext != null) {
try {
super.setVariable(name, appContext.getBean(name));
return super.lookupVariable(name);
} catch (NoSuchBeanDefinitionException e) {
logger.debug("Bean lookup for variable '" + name + "' failed");
}
}
return null;
}

13
taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java

@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletRequest; @@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.context.ApplicationContext;
import org.springframework.core.GenericTypeResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ParseException;
import org.springframework.security.access.expression.ExpressionUtils;
@ -161,8 +162,7 @@ public abstract class AbstractAuthorizeTag { @@ -161,8 +162,7 @@ public abstract class AbstractAuthorizeTag {
* @throws IOException
*/
public boolean authorizeUsingAccessExpression() throws IOException {
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
if (currentUser == null) {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
return false;
}
@ -178,13 +178,20 @@ public abstract class AbstractAuthorizeTag { @@ -178,13 +178,20 @@ public abstract class AbstractAuthorizeTag {
throw ioException;
}
return ExpressionUtils.evaluateAsBoolean(accessExpression, createExpressionEvaluationContext(handler));
}
/**
* Allows the {@code EvaluationContext} to be customized for variable lookup etc.
*/
protected EvaluationContext createExpressionEvaluationContext(SecurityExpressionHandler<FilterInvocation> handler) {
FilterInvocation f = new FilterInvocation(getRequest(), getResponse(), new FilterChain() {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
throw new UnsupportedOperationException();
}
});
return ExpressionUtils.evaluateAsBoolean(accessExpression, handler.createEvaluationContext(currentUser, f));
return handler.createEvaluationContext(SecurityContextHolder.getContext().getAuthentication(), f);
}
/**

76
taglibs/src/main/java/org/springframework/security/taglibs/authz/JspAuthorizeTag.java

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
package org.springframework.security.taglibs.authz;
import java.io.IOException;
import java.util.*;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
@ -9,7 +10,19 @@ import javax.servlet.jsp.JspException; @@ -9,7 +10,19 @@ import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.ConstructorResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.MethodResolver;
import org.springframework.expression.OperatorOverloader;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypeComparator;
import org.springframework.expression.TypeConverter;
import org.springframework.expression.TypeLocator;
import org.springframework.expression.TypedValue;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.taglibs.TagLibConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.web.util.ExpressionEvaluationUtils;
/**
@ -60,6 +73,11 @@ public class JspAuthorizeTag extends AbstractAuthorizeTag implements Tag { @@ -60,6 +73,11 @@ public class JspAuthorizeTag extends AbstractAuthorizeTag implements Tag {
}
}
@Override
protected EvaluationContext createExpressionEvaluationContext(SecurityExpressionHandler<FilterInvocation> handler) {
return new PageContextVariableLookupEvaluationContext(super.createExpressionEvaluationContext(handler));
}
/**
* Default processing of the end tag returning EVAL_PAGE.
*
@ -126,4 +144,62 @@ public class JspAuthorizeTag extends AbstractAuthorizeTag implements Tag { @@ -126,4 +144,62 @@ public class JspAuthorizeTag extends AbstractAuthorizeTag implements Tag {
return pageContext.getServletContext();
}
private final class PageContextVariableLookupEvaluationContext implements EvaluationContext {
private EvaluationContext delegate;
private PageContextVariableLookupEvaluationContext(EvaluationContext delegate) {
this.delegate = delegate;
}
public TypedValue getRootObject() {
return delegate.getRootObject();
}
public List<ConstructorResolver> getConstructorResolvers() {
return delegate.getConstructorResolvers();
}
public List<MethodResolver> getMethodResolvers() {
return delegate.getMethodResolvers();
}
public List<PropertyAccessor> getPropertyAccessors() {
return delegate.getPropertyAccessors();
}
public TypeLocator getTypeLocator() {
return delegate.getTypeLocator();
}
public TypeConverter getTypeConverter() {
return delegate.getTypeConverter();
}
public TypeComparator getTypeComparator() {
return delegate.getTypeComparator();
}
public OperatorOverloader getOperatorOverloader() {
return delegate.getOperatorOverloader();
}
public BeanResolver getBeanResolver() {
return delegate.getBeanResolver();
}
public void setVariable(String name, Object value) {
delegate.setVariable(name, value);
}
public Object lookupVariable(String name) {
Object result = delegate.lookupVariable(name);
if (result == null) {
result = pageContext.findAttribute(name);
}
return result;
}
}
}

10
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagTests.java

@ -44,6 +44,7 @@ public class AuthorizeTagTests { @@ -44,6 +44,7 @@ public class AuthorizeTagTests {
//~ Instance fields ================================================================================================
private JspAuthorizeTag authorizeTag;
private MockHttpServletRequest request = new MockHttpServletRequest();
private final TestingAuthenticationToken currentUser = new TestingAuthenticationToken("abc", "123", "ROLE SUPERVISOR", "ROLE_TELLER");
//~ Methods ========================================================================================================
@ -57,7 +58,7 @@ public class AuthorizeTagTests { @@ -57,7 +58,7 @@ public class AuthorizeTagTests {
MockServletContext servletCtx = new MockServletContext();
servletCtx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
authorizeTag = new JspAuthorizeTag();
authorizeTag.setPageContext(new MockPageContext(servletCtx, new MockHttpServletRequest(), new MockHttpServletResponse()));
authorizeTag.setPageContext(new MockPageContext(servletCtx, request, new MockHttpServletResponse()));
}
@After
@ -86,6 +87,13 @@ public class AuthorizeTagTests { @@ -86,6 +87,13 @@ public class AuthorizeTagTests {
assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
@Test
public void requestAttributeIsResolvedAsElVariable() throws JspException {
request.setAttribute("blah", "blah");
authorizeTag.setAccess("#blah == 'blah'");
assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
// url attribute tests
@Test
public void skipsBodyWithUrlSetIfNoAuthenticationPresent() throws Exception {

4
web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java

@ -14,6 +14,8 @@ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpress @@ -14,6 +14,8 @@ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpress
@Override
protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
return new WebSecurityExpressionRoot(authentication, fi);
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
root.setPermissionEvaluator(getPermissionEvaluator());
return root;
}
}

Loading…
Cancel
Save