SEC-525: [PATCH] Add AccessCheckerTag based on URL resource access permissions. Added functionality to "authorize" tag to allow evaluation of whether a particual url is accessible to the user. Uses a WebInvocationPrivilegeEvaluator registered in the application context.
This commit is contained in:
@@ -8,6 +8,7 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.jsp.JspException;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -17,31 +18,43 @@ import org.springframework.security.access.expression.ExpressionUtils;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
|
||||
import org.springframework.security.web.access.expression.WebSecurityExpressionHandler;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Expression-based access control tag.
|
||||
*
|
||||
* Access control tag which evaluates its body based either on
|
||||
* <ul>
|
||||
* <li>an access expression (the "access" attribute), or</li>
|
||||
* <li>by evaluating the current user's right to access a particular URL (set using the "url" attribute).</li>
|
||||
* </ul>
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AuthorizeTag extends LegacyAuthorizeTag {
|
||||
private String access;
|
||||
private String url;
|
||||
private String method;
|
||||
|
||||
// If access expression evaluates to "true" return
|
||||
public int doStartTag() throws JspException {
|
||||
if (access == null || access.length() == 0) {
|
||||
return super.doStartTag();
|
||||
}
|
||||
|
||||
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (currentUser == null) {
|
||||
return SKIP_BODY;
|
||||
}
|
||||
|
||||
if (access != null && access.length() > 0) {
|
||||
return authorizeUsingAccessExpression(currentUser);
|
||||
} else if (url != null && url.length() > 0) {
|
||||
return authorizeUsingUrlCheck(currentUser);
|
||||
}
|
||||
|
||||
return super.doStartTag();
|
||||
}
|
||||
|
||||
private int authorizeUsingAccessExpression(Authentication currentUser) throws JspException {
|
||||
// Get web expression
|
||||
WebSecurityExpressionHandler handler = getExpressionHandler();
|
||||
|
||||
@@ -62,10 +75,23 @@ public class AuthorizeTag extends LegacyAuthorizeTag {
|
||||
return SKIP_BODY;
|
||||
}
|
||||
|
||||
private int authorizeUsingUrlCheck(Authentication currentUser) throws JspException {
|
||||
return getPrivilegeEvaluator().isAllowed(((HttpServletRequest)pageContext.getRequest()).getContextPath(),
|
||||
url, method, currentUser) ? EVAL_BODY_INCLUDE : SKIP_BODY;
|
||||
}
|
||||
|
||||
public void setAccess(String access) {
|
||||
this.access = access;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
WebSecurityExpressionHandler getExpressionHandler() throws JspException {
|
||||
ServletContext servletContext = pageContext.getServletContext();
|
||||
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
|
||||
@@ -73,12 +99,25 @@ public class AuthorizeTag extends LegacyAuthorizeTag {
|
||||
|
||||
if (expressionHdlrs.size() == 0) {
|
||||
throw new JspException("No visible WebSecurityExpressionHandler instance could be found in the application " +
|
||||
"context. There must be at least one in order to use expressions with taglib support.");
|
||||
"context. There must be at least one in order to support expressions in JSP 'authorize' tags.");
|
||||
}
|
||||
|
||||
return (WebSecurityExpressionHandler) expressionHdlrs.values().toArray()[0];
|
||||
}
|
||||
|
||||
WebInvocationPrivilegeEvaluator getPrivilegeEvaluator() throws JspException {
|
||||
ServletContext servletContext = pageContext.getServletContext();
|
||||
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
|
||||
Map<String, WebInvocationPrivilegeEvaluator> wipes = ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
|
||||
|
||||
if (wipes.size() == 0) {
|
||||
throw new JspException("No visible WebInvocationPrivilegeEvaluator instance could be found in the application " +
|
||||
"context. There must be at least one in order to support the use of URL access checks in 'authorize' tags.");
|
||||
}
|
||||
|
||||
return (WebInvocationPrivilegeEvaluator) wipes.values().toArray()[0];
|
||||
}
|
||||
|
||||
private static final FilterChain DUMMY_CHAIN = new FilterChain() {
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
@@ -30,6 +30,28 @@
|
||||
</description>
|
||||
</attribute>
|
||||
|
||||
<attribute>
|
||||
<name>url</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
<description>
|
||||
A URL within the application. If the user has access to this URL (as determined by
|
||||
the AccessDecisionManager), the tag body will be evaluated. If not, it will
|
||||
be skipped.
|
||||
</description>
|
||||
</attribute>
|
||||
|
||||
<attribute>
|
||||
<name>method</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
<description>
|
||||
Can optionally be used to narrow down the HTTP method (typically GET or POST) to which the URL
|
||||
applies to. Only has any meaning when used in combination with the "url" attribute.
|
||||
</description>
|
||||
</attribute>
|
||||
|
||||
|
||||
<attribute>
|
||||
<name>ifNotGranted</name>
|
||||
<required>false</required>
|
||||
|
||||
Reference in New Issue
Block a user