SEC-1900: AbstractAuthorizeTag now compares using getAuthority()
This avoids backwards compatibility issues with other GrantedAuthority implementations.
This commit is contained in:
parent
c446697de3
commit
d57f1d56d5
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue