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

This commit is contained in:
Luke Taylor 2009-09-15 16:34:05 +00:00
parent 283aa1b34b
commit b531a81176
11 changed files with 348 additions and 217 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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;
if (access == null || access.length() == 0) {
return super.doStartTag();
}
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 (currentUser == null) {
return SKIP_BODY;
}
if ((null == currentUser.getAuthorities())) {
return Collections.emptyList();
// Get web expression
WebSecurityExpressionHandler handler = getExpressionHandler();
Expression accessExpression;
try {
accessExpression = handler.getExpressionParser().parseExpression(access);
} catch (ParseException e) {
throw new JspException(e);
}
return currentUser.getAuthorities();
}
FilterInvocation f = new FilterInvocation(pageContext.getRequest(), pageContext.getResponse(), DUMMY_CHAIN);
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;
}
}
if (ExpressionUtils.evaluateAsBoolean(accessExpression, handler.createEvaluationContext(currentUser, f))) {
return EVAL_BODY_INCLUDE;
}
return target;
return SKIP_BODY;
}
public void setIfAllGranted(String ifAllGranted) throws JspException {
this.ifAllGranted = ifAllGranted;
public void setAccess(String access) {
this.access = access;
}
public void setIfAnyGranted(String ifAnyGranted) throws JspException {
this.ifAnyGranted = ifAnyGranted;
WebSecurityExpressionHandler getExpressionHandler() throws JspException {
ServletContext servletContext = pageContext.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
Map<String, WebSecurityExpressionHandler> expressionHdlrs = ctx.getBeansOfType(WebSecurityExpressionHandler.class);
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 (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();
}
};
}

View File

@ -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;
}
}

View File

@ -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$

View File

@ -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;

View File

@ -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>

View File

@ -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 ========================================================================================================

View File

@ -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 ========================================================================================================

View File

@ -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;

View File

@ -15,97 +15,131 @@
package org.springframework.security.taglibs.authz;
import junit.framework.TestCase;
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 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.context.SecurityContextHolder;
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
authorizeTag.setIfAllGranted("ROLE_TELLER");
assertEquals("prevents request - no principal in Context", Tag.SKIP_BODY, authorizeTag.doStartTag());
@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(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());