2
0
Эх сурвалжийг харах

SEC-1246: Introduce EL-based authorization tag. Added optional access expression to authorize tag.

Luke Taylor 16 жил өмнө
parent
commit
b531a81176

+ 2 - 2
samples/tutorial/src/main/webapp/secure/extreme/index.jsp

@@ -5,11 +5,11 @@
 <h1>VERY Secure Page</h1>
 This is a protected page. You can only see me if you are a supervisor.
 
-<authz:authorize ifAllGranted="ROLE_SUPERVISOR">
+<authz:authorize access="hasRole('ROLE_SUPERVISOR')">
    You have "ROLE_SUPERVISOR" (this text is surrounded by &lt;authz:authorize&gt; tags).
 </authz:authorize>
 
 <p><a href="../../">Home</a>
 <p><a href="../../j_spring_security_logout">Logout</a>
 </body>
-</html>
+</html>

+ 3 - 3
samples/tutorial/src/main/webapp/secure/index.jsp

@@ -8,8 +8,8 @@ This is a protected page. You can get to me if you've been remembered,
 or if you've authenticated this session.
 </p>
 
-<sec:authorize ifAllGranted="ROLE_SUPERVISOR">
-	You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
+<sec:authorize access="hasRole('ROLE_SUPERVISOR')">
+    You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
 </sec:authorize>
 
 <h3>Properties obtained using &lt;sec:authentication /&gt; tag</h3>
@@ -33,4 +33,4 @@ or if you've authenticated this session.
 <p><a href="../">Home</a>
 <p><a href="../j_spring_security_logout">Logout</a>
 </body>
-</html>
+</html>

+ 51 - 161
taglibs/src/main/java/org/springframework/security/taglibs/authz/AuthorizeTag.java

@@ -1,197 +1,87 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 package org.springframework.security.taglibs.authz;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.io.IOException;
+import java.util.Map;
 
+import javax.servlet.FilterChain;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.tagext.Tag;
-import javax.servlet.jsp.tagext.TagSupport;
 
+import org.springframework.context.ApplicationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ParseException;
+import org.springframework.security.access.expression.ExpressionUtils;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.util.ExpressionEvaluationUtils;
-
+import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.access.expression.WebSecurityExpressionHandler;
+import org.springframework.web.context.support.WebApplicationContextUtils;
 
 /**
- * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's body through if some authorizations
- * are granted to the request's principal.
+ * Expression-based access control tag.
  *
- * @author Francois Beausoleil
+ * @author Luke Taylor
  * @version $Id$
+ * @since 3.0
  */
-public class AuthorizeTag extends TagSupport {
-    //~ Instance fields ================================================================================================
-
-    private String ifAllGranted = "";
-    private String ifAnyGranted = "";
-    private String ifNotGranted = "";
-
-    //~ Methods ========================================================================================================
-
-    private Set<String> authoritiesToRoles(Collection<GrantedAuthority> c) {
-        Set<String> target = new HashSet<String>();
-
-        for (GrantedAuthority authority : c) {
-            if (null == authority.getAuthority()) {
-                throw new IllegalArgumentException(
-                    "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
-                    + authority.toString());
-            }
-
-            target.add(authority.getAuthority());
-        }
-
-        return target;
-    }
+public class AuthorizeTag extends LegacyAuthorizeTag {
+    private String access;
 
+    // If access expression evaluates to "true" return
     public int doStartTag() throws JspException {
-        if (((null == ifAllGranted) || "".equals(ifAllGranted)) && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
-            && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
-            return Tag.SKIP_BODY;
-        }
-
-        final Collection<GrantedAuthority> granted = getPrincipalAuthorities();
-
-        final String evaledIfNotGranted = ExpressionEvaluationUtils.evaluateString("ifNotGranted", ifNotGranted,
-                pageContext);
-
-        if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
-            Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfNotGranted));
-
-            if (!grantedCopy.isEmpty()) {
-                return Tag.SKIP_BODY;
-            }
+        if (access == null || access.length() == 0) {
+            return super.doStartTag();
         }
 
-        final String evaledIfAllGranted = ExpressionEvaluationUtils.evaluateString("ifAllGranted", ifAllGranted,
-                pageContext);
+        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
 
-        if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
-            if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
-                return Tag.SKIP_BODY;
-            }
+        if (currentUser == null) {
+            return SKIP_BODY;
         }
 
-        final String evaledIfAnyGranted = ExpressionEvaluationUtils.evaluateString("ifAnyGranted", ifAnyGranted,
-                pageContext);
+        // Get web expression
+        WebSecurityExpressionHandler handler = getExpressionHandler();
 
-        if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
-            Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfAnyGranted));
+        Expression accessExpression;
+        try {
+            accessExpression = handler.getExpressionParser().parseExpression(access);
 
-            if (grantedCopy.isEmpty()) {
-                return Tag.SKIP_BODY;
-            }
+        } catch (ParseException e) {
+            throw new JspException(e);
         }
 
-        return Tag.EVAL_BODY_INCLUDE;
-    }
+        FilterInvocation f = new FilterInvocation(pageContext.getRequest(), pageContext.getResponse(), DUMMY_CHAIN);
 
-    public String getIfAllGranted() {
-        return ifAllGranted;
-    }
-
-    public String getIfAnyGranted() {
-        return ifAnyGranted;
-    }
-
-    public String getIfNotGranted() {
-        return ifNotGranted;
-    }
-
-    private Collection<GrantedAuthority> getPrincipalAuthorities() {
-        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
-
-        if (null == currentUser) {
-            return Collections.emptyList();
-        }
-
-        if ((null == currentUser.getAuthorities())) {
-            return Collections.emptyList();
+        if (ExpressionUtils.evaluateAsBoolean(accessExpression, handler.createEvaluationContext(currentUser, f))) {
+            return EVAL_BODY_INCLUDE;
         }
 
-        return currentUser.getAuthorities();
+        return SKIP_BODY;
     }
 
-    private Set<GrantedAuthority> parseAuthoritiesString(String authorizationsString) {
-        final Set<GrantedAuthority> requiredAuthorities = new HashSet<GrantedAuthority>();
-        requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizationsString));
-
-        return requiredAuthorities;
-    }
-
-    /**
-     * Find the common authorities between the current authentication's {@link GrantedAuthority} and the ones
-     * that have been specified in the tag's ifAny, ifNot or ifAllGranted attributes.<p>We need to manually
-     * iterate over both collections, because the granted authorities might not implement {@link
-     * Object#equals(Object)} and {@link Object#hashCode()} in the same way as {@link GrantedAuthorityImpl}, thereby
-     * invalidating {@link Collection#retainAll(java.util.Collection)} results.</p>
-     * <p>
-     * <strong>CAVEAT</strong>:  This method <strong>will not</strong> work if the granted authorities
-     * returns a <code>null</code> string as the return value of {@link GrantedAuthority#getAuthority()}.
-     * </p>
-     *
-     * @param granted The authorities granted by the authentication. May be any implementation of {@link
-     *        GrantedAuthority} that does <strong>not</strong> return <code>null</code> from {@link
-     *        GrantedAuthority#getAuthority()}.
-     * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have been built using ifAny, ifAll or
-     *        ifNotGranted.
-     *
-     * @return A set containing only the common authorities between <var>granted</var> and <var>required</var>.
-     *
-     */
-    private Set<GrantedAuthority> retainAll(final Collection<GrantedAuthority> granted, final Set<GrantedAuthority> required) {
-        Set<String> grantedRoles = authoritiesToRoles(granted);
-        Set<String> requiredRoles = authoritiesToRoles(required);
-        grantedRoles.retainAll(requiredRoles);
-
-        return rolesToAuthorities(grantedRoles, granted);
+    public void setAccess(String access) {
+        this.access = access;
     }
 
-    private Set<GrantedAuthority> rolesToAuthorities(Set<String> grantedRoles, Collection<GrantedAuthority> granted) {
-        Set<GrantedAuthority> target = new HashSet<GrantedAuthority>();
+    WebSecurityExpressionHandler getExpressionHandler() throws JspException {
+        ServletContext servletContext = pageContext.getServletContext();
+        ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
+        Map<String, WebSecurityExpressionHandler> expressionHdlrs = ctx.getBeansOfType(WebSecurityExpressionHandler.class);
 
-        for (String role : grantedRoles) {
-            for (GrantedAuthority authority : granted) {
-                if (authority.getAuthority().equals(role)) {
-                    target.add(authority);
-
-                    break;
-                }
-            }
+        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.");
         }
 
-        return target;
-    }
-
-    public void setIfAllGranted(String ifAllGranted) throws JspException {
-        this.ifAllGranted = ifAllGranted;
-    }
-
-    public void setIfAnyGranted(String ifAnyGranted) throws JspException {
-        this.ifAnyGranted = ifAnyGranted;
+        return (WebSecurityExpressionHandler) expressionHdlrs.values().toArray()[0];
     }
 
-    public void setIfNotGranted(String ifNotGranted) throws JspException {
-        this.ifNotGranted = ifNotGranted;
-    }
+    private static final FilterChain DUMMY_CHAIN = new FilterChain() {
+        public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+           throw new UnsupportedOperationException();
+        }
+    };
 }

+ 197 - 0
taglibs/src/main/java/org/springframework/security/taglibs/authz/LegacyAuthorizeTag.java

@@ -0,0 +1,197 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.taglibs.authz;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.Tag;
+import javax.servlet.jsp.tagext.TagSupport;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.authority.GrantedAuthorityImpl;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.util.ExpressionEvaluationUtils;
+
+
+/**
+ * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's body through if some authorizations
+ * are granted to the request's principal.
+ *
+ * @author Francois Beausoleil
+ * @version $Id$
+ */
+public class LegacyAuthorizeTag extends TagSupport {
+    //~ Instance fields ================================================================================================
+
+    private String ifAllGranted = "";
+    private String ifAnyGranted = "";
+    private String ifNotGranted = "";
+
+    //~ Methods ========================================================================================================
+
+    private Set<String> authoritiesToRoles(Collection<GrantedAuthority> c) {
+        Set<String> target = new HashSet<String>();
+
+        for (GrantedAuthority authority : c) {
+            if (null == authority.getAuthority()) {
+                throw new IllegalArgumentException(
+                    "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
+                    + authority.toString());
+            }
+
+            target.add(authority.getAuthority());
+        }
+
+        return target;
+    }
+
+    public int doStartTag() throws JspException {
+        if (((null == ifAllGranted) || "".equals(ifAllGranted)) && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
+            && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
+            return Tag.SKIP_BODY;
+        }
+
+        final Collection<GrantedAuthority> granted = getPrincipalAuthorities();
+
+        final String evaledIfNotGranted = ExpressionEvaluationUtils.evaluateString("ifNotGranted", ifNotGranted,
+                pageContext);
+
+        if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
+            Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfNotGranted));
+
+            if (!grantedCopy.isEmpty()) {
+                return Tag.SKIP_BODY;
+            }
+        }
+
+        final String evaledIfAllGranted = ExpressionEvaluationUtils.evaluateString("ifAllGranted", ifAllGranted,
+                pageContext);
+
+        if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
+            if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
+                return Tag.SKIP_BODY;
+            }
+        }
+
+        final String evaledIfAnyGranted = ExpressionEvaluationUtils.evaluateString("ifAnyGranted", ifAnyGranted,
+                pageContext);
+
+        if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
+            Set<GrantedAuthority> grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfAnyGranted));
+
+            if (grantedCopy.isEmpty()) {
+                return Tag.SKIP_BODY;
+            }
+        }
+
+        return Tag.EVAL_BODY_INCLUDE;
+    }
+
+    public String getIfAllGranted() {
+        return ifAllGranted;
+    }
+
+    public String getIfAnyGranted() {
+        return ifAnyGranted;
+    }
+
+    public String getIfNotGranted() {
+        return ifNotGranted;
+    }
+
+    private Collection<GrantedAuthority> getPrincipalAuthorities() {
+        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
+
+        if (null == currentUser) {
+            return Collections.emptyList();
+        }
+
+        if ((null == currentUser.getAuthorities())) {
+            return Collections.emptyList();
+        }
+
+        return currentUser.getAuthorities();
+    }
+
+    private Set<GrantedAuthority> parseAuthoritiesString(String authorizationsString) {
+        final Set<GrantedAuthority> requiredAuthorities = new HashSet<GrantedAuthority>();
+        requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizationsString));
+
+        return requiredAuthorities;
+    }
+
+    /**
+     * Find the common authorities between the current authentication's {@link GrantedAuthority} and the ones
+     * that have been specified in the tag's ifAny, ifNot or ifAllGranted attributes.<p>We need to manually
+     * iterate over both collections, because the granted authorities might not implement {@link
+     * Object#equals(Object)} and {@link Object#hashCode()} in the same way as {@link GrantedAuthorityImpl}, thereby
+     * invalidating {@link Collection#retainAll(java.util.Collection)} results.</p>
+     * <p>
+     * <strong>CAVEAT</strong>:  This method <strong>will not</strong> work if the granted authorities
+     * returns a <code>null</code> string as the return value of {@link GrantedAuthority#getAuthority()}.
+     * </p>
+     *
+     * @param granted The authorities granted by the authentication. May be any implementation of {@link
+     *        GrantedAuthority} that does <strong>not</strong> return <code>null</code> from {@link
+     *        GrantedAuthority#getAuthority()}.
+     * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have been built using ifAny, ifAll or
+     *        ifNotGranted.
+     *
+     * @return A set containing only the common authorities between <var>granted</var> and <var>required</var>.
+     *
+     */
+    private Set<GrantedAuthority> retainAll(final Collection<GrantedAuthority> granted, final Set<GrantedAuthority> required) {
+        Set<String> grantedRoles = authoritiesToRoles(granted);
+        Set<String> requiredRoles = authoritiesToRoles(required);
+        grantedRoles.retainAll(requiredRoles);
+
+        return rolesToAuthorities(grantedRoles, granted);
+    }
+
+    private Set<GrantedAuthority> rolesToAuthorities(Set<String> grantedRoles, Collection<GrantedAuthority> granted) {
+        Set<GrantedAuthority> target = new HashSet<GrantedAuthority>();
+
+        for (String role : grantedRoles) {
+            for (GrantedAuthority authority : granted) {
+                if (authority.getAuthority().equals(role)) {
+                    target.add(authority);
+
+                    break;
+                }
+            }
+        }
+
+        return target;
+    }
+
+    public void setIfAllGranted(String ifAllGranted) throws JspException {
+        this.ifAllGranted = ifAllGranted;
+    }
+
+    public void setIfAnyGranted(String ifAnyGranted) throws JspException {
+        this.ifAnyGranted = ifAnyGranted;
+    }
+
+    public void setIfNotGranted(String ifNotGranted) throws JspException {
+        this.ifNotGranted = ifNotGranted;
+    }
+}

+ 2 - 2
taglibs/src/main/java/org/springframework/security/taglibs/velocity/Authz.java

@@ -19,7 +19,7 @@ package org.springframework.security.taglibs.velocity;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.taglibs.authz.AuthenticationTag;
-import org.springframework.security.taglibs.authz.AuthorizeTag;
+import org.springframework.security.taglibs.authz.LegacyAuthorizeTag;
 
 
 import org.springframework.context.ApplicationContext;
@@ -27,7 +27,7 @@ import org.springframework.context.ApplicationContext;
 
 /**
  * Wrapper the implementation of Spring Security JSP tag includes:
- * {@link AuthenticationTag}, {@link AclTag}, {@link AuthorizeTag}
+ * {@link AuthenticationTag}, {@link AclTag}, {@link LegacyAuthorizeTag}
  *
  * @author Wang Qi
  * @version $Id$

+ 3 - 3
taglibs/src/main/java/org/springframework/security/taglibs/velocity/AuthzImpl.java

@@ -20,7 +20,7 @@ import javax.servlet.jsp.tagext.Tag;
 
 import org.springframework.context.ApplicationContext;
 import org.springframework.security.taglibs.authz.AuthenticationTag;
-import org.springframework.security.taglibs.authz.AuthorizeTag;
+import org.springframework.security.taglibs.authz.LegacyAuthorizeTag;
 
 
 /**
@@ -72,7 +72,7 @@ public class AuthzImpl implements Authz {
     }
 
     /**
-     * implementation of AuthorizeTag
+     * implementation of LegacyAuthorizeTag
      *
      * @param roles DOCUMENT ME!
      * @param grantType DOCUMENT ME!
@@ -82,7 +82,7 @@ public class AuthzImpl implements Authz {
      * @throws IllegalArgumentException DOCUMENT ME!
      */
     private boolean ifGranted(String roles, int grantType) {
-        AuthorizeTag authorizeTag = new AuthorizeTag();
+        LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
 
         int result = -1;
 

+ 15 - 5
taglibs/src/main/resources/META-INF/security.tld

@@ -16,17 +16,27 @@
         <name>authorize</name>
         <tag-class>org.springframework.security.taglibs.authz.AuthorizeTag</tag-class>
         <description>
-            A simple tag to output or not the body of the tag if the principal
-            has or doesn't have certain authorities.
+            A tag which outputs the body of the tag if the configured access expression
+            evaluates to true for the currently authenticated principal.
         </description>
 
+        <attribute>
+            <name>access</name>
+            <required>false</required>
+            <rtexprvalue>false</rtexprvalue>
+            <description>
+                A Spring-EL expression which is supported by the WebSecurityExpressionHandler
+                in the application context. The latter will be used to evaluate the expression.
+            </description>
+        </attribute>
+
         <attribute>
             <name>ifNotGranted</name>
             <required>false</required>
             <rtexprvalue>true</rtexprvalue>
             <description>
                 A comma separated list of roles which the user must not have
-                for the body to be output.
+                for the body to be output. Deprecated in favour of the access expression.
             </description>
         </attribute>
 
@@ -36,7 +46,7 @@
             <rtexprvalue>true</rtexprvalue>
             <description>
                 A comma separated list of roles which the user must all
-                possess for the body to be output.
+                possess for the body to be output. Deprecated in favour of the access expression.
             </description>
         </attribute>
 
@@ -46,7 +56,7 @@
             <rtexprvalue>true</rtexprvalue>
             <description>
                 A comma separated list of roles, one of which the user must
-                possess for the body to be output.
+                possess for the body to be output. Deprecated in favour of the access expression.
             </description>
         </attribute>
     </tag>

+ 1 - 1
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagAttributeTests.java

@@ -37,7 +37,7 @@ import javax.servlet.jsp.tagext.Tag;
 public class AuthorizeTagAttributeTests extends TestCase {
     //~ Instance fields ================================================================================================
 
-    private final AuthorizeTag authorizeTag = new AuthorizeTag();
+    private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
     private TestingAuthenticationToken currentUser;
 
     //~ Methods ========================================================================================================

+ 1 - 1
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagCustomGrantedAuthorityTests.java

@@ -35,7 +35,7 @@ import javax.servlet.jsp.tagext.Tag;
 public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase {
     //~ Instance fields ================================================================================================
 
-    private final AuthorizeTag authorizeTag = new AuthorizeTag();
+    private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
     private TestingAuthenticationToken currentUser;
 
     //~ Methods ========================================================================================================

+ 1 - 1
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagExpressionLanguageTests.java

@@ -36,7 +36,7 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase {
     Mockery jmock = new Mockery();
     //~ Instance fields ================================================================================================
 
-    private final AuthorizeTag authorizeTag = new AuthorizeTag();
+    private final LegacyAuthorizeTag authorizeTag = new LegacyAuthorizeTag();
     private MockPageContext pageContext;
     private TestingAuthenticationToken currentUser;
 

+ 66 - 32
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthorizeTagTests.java

@@ -15,97 +15,131 @@
 
 package org.springframework.security.taglibs.authz;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
 
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.Tag;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockPageContext;
+import org.springframework.mock.web.MockServletContext;
 import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
 import org.springframework.security.core.context.SecurityContextHolder;
-
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.tagext.Tag;
+import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.StaticWebApplicationContext;
 
 
 /**
- * DOCUMENT ME!
- *
  * @author Francois Beausoleil
  * @version $Id$
  */
-public class AuthorizeTagTests extends TestCase {
+public class AuthorizeTagTests {
     //~ Instance fields ================================================================================================
 
-    private final AuthorizeTag authorizeTag = new AuthorizeTag();
-    private TestingAuthenticationToken currentUser;
+    private AuthorizeTag authorizeTag;
+    private final TestingAuthenticationToken currentUser = new TestingAuthenticationToken("abc", "123", "ROLE SUPERVISOR", "ROLE_TELLER");
 
     //~ Methods ========================================================================================================
 
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        currentUser = new TestingAuthenticationToken("abc", "123",
-                new GrantedAuthority[] {
-                    new GrantedAuthorityImpl("ROLE SUPERVISOR"), new GrantedAuthorityImpl("ROLE_TELLER"),
-                });
-
+    @Before
+    public void setUp() throws Exception {
         SecurityContextHolder.getContext().setAuthentication(currentUser);
+        StaticWebApplicationContext ctx = new StaticWebApplicationContext();
+        ctx.registerSingleton("expressionHandler", DefaultWebSecurityExpressionHandler.class);
+        MockServletContext servletCtx = new MockServletContext();
+        servletCtx.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
+        authorizeTag = new AuthorizeTag();
+        authorizeTag.setPageContext(new MockPageContext(servletCtx, new MockHttpServletRequest(), new MockHttpServletResponse()));
     }
 
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         SecurityContextHolder.clearContext();
     }
 
-    public void testAlwaysReturnsUnauthorizedIfNoUserFound() throws JspException {
-        SecurityContextHolder.getContext().setAuthentication(null);
+    // access attribute tests
 
+    @Test
+    public void skipsBodyIfNoAuthenticationPresent() throws Exception {
+        SecurityContextHolder.clearContext();
+        authorizeTag.setAccess("permitAll");
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
+    }
+
+    @Test
+    public void skipsBodyIfAccessExpressionDeniesAccess() throws Exception {
+        authorizeTag.setAccess("denyAll");
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
+    }
+
+    @Test
+    public void showsBodyIfAccessExpressionAllowsAccess() throws Exception {
+        authorizeTag.setAccess("permitAll");
+        assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
+    }
+    // Legacy attribute tests
+
+    @Test
+    public void testAlwaysReturnsUnauthorizedIfNoUserFound() throws JspException {
+        SecurityContextHolder.clearContext();
         authorizeTag.setIfAllGranted("ROLE_TELLER");
-        assertEquals("prevents request - no principal in Context", Tag.SKIP_BODY, authorizeTag.doStartTag());
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testDefaultsToNotOutputtingBodyWhenNoRequiredAuthorities() throws JspException {
         assertEquals("", authorizeTag.getIfAllGranted());
         assertEquals("", authorizeTag.getIfAnyGranted());
         assertEquals("", authorizeTag.getIfNotGranted());
 
-        assertEquals("prevents body output - no authorities granted", Tag.SKIP_BODY, authorizeTag.doStartTag());
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testOutputsBodyIfOneRolePresent() throws JspException {
         authorizeTag.setIfAnyGranted("ROLE_TELLER");
-        assertEquals("authorized - ROLE_TELLER in both sets", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
+        assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testOutputsBodyWhenAllGranted() throws JspException {
         authorizeTag.setIfAllGranted("ROLE SUPERVISOR, \nROLE_TELLER");
-        assertEquals("allows request - all required roles granted on principal", Tag.EVAL_BODY_INCLUDE,
-            authorizeTag.doStartTag());
+        assertEquals(Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testOutputsBodyWhenNotGrantedSatisfied() throws JspException {
         authorizeTag.setIfNotGranted("ROLE_BANKER");
-        assertEquals("allows request - principal doesn't have ROLE_BANKER", Tag.EVAL_BODY_INCLUDE,
+        assertEquals(Tag.EVAL_BODY_INCLUDE,
             authorizeTag.doStartTag());
     }
 
+    @Test
     public void testPreventsBodyOutputIfNoSecurityContext() throws JspException {
         SecurityContextHolder.getContext().setAuthentication(null);
         authorizeTag.setIfAnyGranted("ROLE_BANKER");
 
-        assertEquals("prevents output - no context defined", Tag.SKIP_BODY, authorizeTag.doStartTag());
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testSkipsBodyIfNoAnyRolePresent() throws JspException {
         authorizeTag.setIfAnyGranted("ROLE_BANKER");
-        assertEquals("unauthorized - ROLE_BANKER not in granted authorities", Tag.SKIP_BODY, authorizeTag.doStartTag());
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testSkipsBodyWhenMissingAnAllGranted() throws JspException {
         authorizeTag.setIfAllGranted("ROLE SUPERVISOR, ROLE_TELLER,\n\rROLE_BANKER");
-        assertEquals("prevents request - missing ROLE_BANKER on principal", Tag.SKIP_BODY, authorizeTag.doStartTag());
+        assertEquals(Tag.SKIP_BODY, authorizeTag.doStartTag());
     }
 
+    @Test
     public void testSkipsBodyWhenNotGrantedUnsatisfied() throws JspException {
         authorizeTag.setIfNotGranted("ROLE_TELLER");
         assertEquals("prevents request - principal has ROLE_TELLER", Tag.SKIP_BODY, authorizeTag.doStartTag());