SEC-1023: Add hasPermission() support to SecurityExpressionRoot

http://jira.springframework.org/browse/SEC-1023.

hasPermission() now delegates to a PermissionEvaluator interface, with a default implementation provided by the Acl module. The contacts sample now uses expressions on the ContactManager interface. The permission-evaluator element on global-method-security can be used to set the instance to an AclPermissionEvaluator. If not set, all hasPermission() expressions will evaluate to 'false'.
This commit is contained in:
Luke Taylor
2008-11-10 04:27:25 +00:00
parent fa6f57e3dd
commit e11114ce77
34 changed files with 392 additions and 357 deletions

View File

@@ -14,22 +14,24 @@
*/
package sample.contact;
import org.springframework.security.Authentication;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.sid.PrincipalSid;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.test.AbstractTransactionalSpringContextTests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.Iterator;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.Authentication;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.sid.PrincipalSid;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Tests {@link ContactManager}.
@@ -37,9 +39,15 @@ import java.util.List;
* @author David Leal
* @author Ben Alex
*/
public class GetAllContactsTests extends AbstractTransactionalSpringContextTests {
@ContextConfiguration(locations={
"/applicationContext-common-authorization.xml",
"/applicationContext-common-business.xml",
"/applicationContext-contacts-test.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class GetAllContactsTests {
//~ Instance fields ================================================================================================
@Autowired
protected ContactManager contactManager;
//~ Methods ========================================================================================================
@@ -59,7 +67,7 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
fail("List of contacts should have contained: " + id);
}
protected void assertNotContainsContact(String id, List contacts) {
void assertDoestNotContainContact(String id, List contacts) {
Iterator iter = contacts.iterator();
while (iter.hasNext()) {
@@ -71,15 +79,6 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
}
}
protected String[] getConfigLocations() {
setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
return new String[] {
"applicationContext-common-authorization.xml", "applicationContext-common-business.xml",
"applicationContext-contacts-test.xml"
};
}
/**
* Locates the first <code>Contact</code> of the exact name specified.<p>Uses the {@link
* ContactManager#getAll()} method.</p>
@@ -120,14 +119,12 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
SecurityContextHolder.getContext().setAuthentication(authRequest);
}
protected void onTearDownInTransaction() {
@After
public void onTearDownInTransaction() {
SecurityContextHolder.clearContext();
}
public void setContactManager(ContactManager contactManager) {
this.contactManager = contactManager;
}
@Test
public void testDianne() {
makeActiveUser("dianne"); // has ROLE_USER
@@ -139,11 +136,12 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
assertContainsContact(Long.toString(6), contacts);
assertContainsContact(Long.toString(8), contacts);
assertNotContainsContact(Long.toString(1), contacts);
assertNotContainsContact(Long.toString(2), contacts);
assertNotContainsContact(Long.toString(3), contacts);
assertDoestNotContainContact(Long.toString(1), contacts);
assertDoestNotContainContact(Long.toString(2), contacts);
assertDoestNotContainContact(Long.toString(3), contacts);
}
@Test
public void testrod() {
makeActiveUser("rod"); // has ROLE_SUPERVISOR
@@ -156,13 +154,14 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
assertContainsContact(Long.toString(3), contacts);
assertContainsContact(Long.toString(4), contacts);
assertNotContainsContact(Long.toString(5), contacts);
assertDoestNotContainContact(Long.toString(5), contacts);
Contact c1 = contactManager.getById(new Long(4));
contactManager.deletePermission(c1, new PrincipalSid("bob"), BasePermission.ADMINISTRATION);
}
@Test
public void testScott() {
makeActiveUser("scott"); // has ROLE_USER
@@ -176,6 +175,6 @@ public class GetAllContactsTests extends AbstractTransactionalSpringContextTests
assertContainsContact(Long.toString(8), contacts);
assertContainsContact(Long.toString(9), contacts);
assertNotContainsContact(Long.toString(1), contacts);
assertDoestNotContainContact(Long.toString(1), contacts);
}
}

View File

@@ -10,9 +10,12 @@
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.5.xsd">
<global-method-security expression-annotations="enabled">
<permission-evaluator ref="permissionEvaluator"/>
</global-method-security>
<!-- ======================== AUTHENTICATION ======================= -->
@@ -21,8 +24,8 @@
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
<!-- Automatically receives AuthenticationEvent messages -->
<b:bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>
<b:bean id="permissionEvaluator" class="org.springframework.security.acls.AclPermissionEvaluator">
<b:constructor-arg ref="aclService" />
</b:bean>
</b:beans>