SEC-1900: AbstractAuthorizeTag now compares using getAuthority()

This avoids backwards compatibility issues with other GrantedAuthority
implementations.
This commit is contained in:
Christian Hilmersson 2012-02-22 01:46:33 +01:00 committed by Rob Winch
parent c446697de3
commit d57f1d56d5
2 changed files with 86 additions and 30 deletions

View File

@ -38,7 +38,6 @@ import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionHandler; import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator; import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
@ -56,6 +55,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
* @author Francois Beausoleil * @author Francois Beausoleil
* @author Luke Taylor * @author Luke Taylor
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Rob Winch
* @since 3.1.0 * @since 3.1.0
*/ */
public abstract class AbstractAuthorizeTag { public abstract class AbstractAuthorizeTag {
@ -130,23 +130,25 @@ public abstract class AbstractAuthorizeTag {
} }
final Collection<? extends GrantedAuthority> granted = getPrincipalAuthorities(); final Collection<? extends GrantedAuthority> granted = getPrincipalAuthorities();
final Set<String> grantedRoles = authoritiesToRoles(granted);
if (hasTextAllGranted) { if (hasTextAllGranted) {
if (!granted.containsAll(toAuthorities(getIfAllGranted()))) { final Set<String> requiredRoles = splitRoles(getIfAllGranted());
if (!grantedRoles.containsAll(requiredRoles)) {
return false; return false;
} }
} }
if (hasTextAnyGranted) { if (hasTextAnyGranted) {
Set<GrantedAuthority> grantedCopy = retainAll(granted, toAuthorities(getIfAnyGranted())); final Set<String> expectOneOfRoles = splitRoles(getIfAnyGranted());
if (grantedCopy.isEmpty()) { if (!containsAnyValue(grantedRoles, expectOneOfRoles)) {
return false; return false;
} }
} }
if (hasTextNotGranted) { if (hasTextNotGranted) {
Set<GrantedAuthority> grantedCopy = retainAll(granted, toAuthorities(getIfNotGranted())); final Set<String> expectNoneOfRoles = splitRoles(getIfNotGranted());
if (!grantedCopy.isEmpty()) { if (containsAnyValue(expectNoneOfRoles, grantedRoles)) {
return false; return false;
} }
} }
@ -265,19 +267,33 @@ public abstract class AbstractAuthorizeTag {
return currentUser.getAuthorities(); return currentUser.getAuthorities();
} }
private Set<GrantedAuthority> toAuthorities(String authorizations) { /**
final Set<GrantedAuthority> requiredAuthorities = new HashSet<GrantedAuthority>(); * Splits the authorityString using "," as a delimiter into a Set.
requiredAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(authorizations)); * @param authorityString
return requiredAuthorities; * @return
*/
private Set<String> splitRoles(String authorityString) {
String[] rolesArray = StringUtils.tokenizeToStringArray(authorityString, ",");
Set<String> roles = new HashSet<String>(rolesArray.length);
for(String role : rolesArray) {
roles.add(role);
}
return roles;
} }
private Set<GrantedAuthority> retainAll(final Collection<? extends GrantedAuthority> granted, /**
final Set<GrantedAuthority> required) { * Returns true if any of the values are contained in toTest. Otherwise, false.
Set<String> grantedRoles = authoritiesToRoles(granted); * @param toTest Check this Set to see if any of the values are contained in it.
Set<String> requiredRoles = authoritiesToRoles(required); * @param values The values to check if they are in toTest.
grantedRoles.retainAll(requiredRoles); * @return
*/
return rolesToAuthorities(grantedRoles, granted); private boolean containsAnyValue(Set<String> toTest, Collection<String> values) {
for(String value : values) {
if(toTest.contains(value)) {
return true;
}
}
return false;
} }
private Set<String> authoritiesToRoles(Collection<? extends GrantedAuthority> c) { private Set<String> authoritiesToRoles(Collection<? extends GrantedAuthority> c) {
@ -293,19 +309,6 @@ public abstract class AbstractAuthorizeTag {
return target; return target;
} }
private Set<GrantedAuthority> rolesToAuthorities(Set<String> grantedRoles, Collection<? extends 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;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private SecurityExpressionHandler<FilterInvocation> getExpressionHandler() throws IOException { private SecurityExpressionHandler<FilterInvocation> getExpressionHandler() throws IOException {
ApplicationContext appContext = WebApplicationContextUtils ApplicationContext appContext = WebApplicationContextUtils

View File

@ -20,6 +20,7 @@ import static org.junit.Assert.*;
import org.junit.*; import org.junit.*;
import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspException;
@ -73,4 +74,56 @@ public class AuthorizeTagCustomGrantedAuthorityTests {
assertTrue("expected", true); assertTrue("expected", true);
} }
} }
@Test
@SuppressWarnings("serial")
public void testAuthorizeCustomGrantedAuthority() throws JspException {
authorizeTag.setIfAnyGranted(null);
authorizeTag.setIfNotGranted(null);
authorizeTag.setIfAllGranted("ROLE_TEST");
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthority() {
public String getAuthority() {
return "ROLE_TEST";
}
});
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("abc", "123", authorities));
assertEquals("Expected to be authorized", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
@Test
@SuppressWarnings("serial")
public void testAuthorizeExtendsGrantedAuthorityImpl() throws JspException {
authorizeTag.setIfAnyGranted(null);
authorizeTag.setIfNotGranted(null);
authorizeTag.setIfAllGranted("ROLE_TEST");
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl("ROLE_TEST") {});
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("abc", "123", authorities));
assertEquals("Expected to be authorized", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
// SEC-1900
@Test
public void testAuthorizeUsingGrantedAuthorityImpl() throws JspException {
authorizeTag.setIfAnyGranted(null);
authorizeTag.setIfNotGranted(null);
authorizeTag.setIfAllGranted("ROLE_TEST");
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl("ROLE_TEST"));
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("abc", "123", authorities));
assertEquals("Expected to be authorized", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
// SEC-1900
@Test
public void testNotAuthorizeUsingGrantedAuthorityImpl() throws JspException {
authorizeTag.setIfAnyGranted(null);
authorizeTag.setIfNotGranted(null);
authorizeTag.setIfAllGranted("ROLE_ADMIN");
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl("ROLE_TEST"));
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("abc", "123", authorities));
assertEquals("Expected to not be authorized", Tag.SKIP_BODY, authorizeTag.doStartTag());
}
} }