SEC-1749: Add support for PageContext lookup of objects and use of PermissionEvaluator when using web access expressions.
This commit is contained in:
+10
-3
@@ -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 {
|
||||
* @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 {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-1
@@ -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 {
|
||||
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 {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user