diff --git a/core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java b/core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java index 697cffba65..7e21b481bb 100644 --- a/core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java +++ b/core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java @@ -37,6 +37,9 @@ public class Jsr250Voter implements AccessDecisionVoter { /** * Votes according to JSR 250. + *

+ * If no JSR-250 attributes are found, it will abstain, otherwise it will grant or deny access + * based on the attributes that are found. * * @param authentication The authentication object. * @param object The access object. @@ -44,6 +47,8 @@ public class Jsr250Voter implements AccessDecisionVoter { * @return The vote. */ public int vote(Authentication authentication, Object object, Collection definition) { + boolean jsr250AttributeFound = false; + for (ConfigAttribute attribute : definition) { if (Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE.equals(attribute)) { return ACCESS_GRANTED; @@ -54,18 +59,17 @@ public class Jsr250Voter implements AccessDecisionVoter { } if (supports(attribute)) { + jsr250AttributeFound = true; // Attempt to find a matching granted authority for (GrantedAuthority authority : authentication.getAuthorities()) { if (attribute.getAttribute().equals(authority.getAuthority())) { return ACCESS_GRANTED; } } - // No match - deny access - return ACCESS_DENIED; } } - return ACCESS_ABSTAIN; + return jsr250AttributeFound ? ACCESS_DENIED : ACCESS_ABSTAIN; } } diff --git a/core/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java b/core/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java new file mode 100644 index 0000000000..96004cd040 --- /dev/null +++ b/core/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java @@ -0,0 +1,44 @@ +package org.springframework.security.access.annotation; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.authentication.TestingAuthenticationToken; + +/** + * + * @author Luke Taylor + */ +public class Jsr250VoterTests { + + // SEC-1443 + @Test + public void supportsMultipleRolesCorrectly() throws Exception { + List attrs = new ArrayList(); + Jsr250Voter voter = new Jsr250Voter(); + + attrs.add(new Jsr250SecurityConfig("A")); + attrs.add(new Jsr250SecurityConfig("B")); + attrs.add(new Jsr250SecurityConfig("C")); + + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, + voter.vote(new TestingAuthenticationToken("user", "pwd", "A"), new Object(), attrs)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, + voter.vote(new TestingAuthenticationToken("user", "pwd", "B"), new Object(), attrs)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, + voter.vote(new TestingAuthenticationToken("user", "pwd", "C"), new Object(), attrs)); + + assertEquals(AccessDecisionVoter.ACCESS_DENIED, + voter.vote(new TestingAuthenticationToken("user", "pwd", "NONE"), new Object(), attrs)); + + assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN, + voter.vote(new TestingAuthenticationToken("user", "pwd", "A"), new Object(), + SecurityConfig.createList("A","B","C"))); + } +}