Initial commit.

This commit is contained in:
Ben Alex
2004-03-16 23:57:17 +00:00
commit 35fe1e7b73
267 changed files with 17812 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.aopalliance.intercept.MethodInvocation;
import java.util.Iterator;
/**
* Implementation of an {@link AccessDecisionVoter} that provides a token
* example of application-specific security.
*
* <p>
* If the {@link ConfigAttribute#getAttribute()} has a value of
* <code>BANKSECURITY_CUSTOMER</code>, the account number subject of the
* method call to be compared with any granted authority prefixed with
* <code>ACCOUNT_</code> and followed by that account number. For example, if
* account number 12 was subject of the call, a search would be conducted for
* a granted authority named <code>ACCOUNT_12</code>.
* </p>
*
* <p>
* All comparisons are case sensitive.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class BankSecurityVoter implements AccessDecisionVoter {
//~ Methods ================================================================
public boolean supports(ConfigAttribute attribute) {
if ("BANKSECURITY_CUSTOMER".equals(attribute.getAttribute())) {
return true;
} else {
return false;
}
}
public int vote(Authentication authentication, MethodInvocation invocation,
ConfigAttributeDefinition config) {
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
// Lookup the account number being passed
Integer accountNumber = null;
for (int i = 0; i < invocation.getArgumentCount(); i++) {
Class argClass = invocation.getArgument(i).getClass();
if (Integer.class.isAssignableFrom(argClass)) {
accountNumber = (Integer) invocation.getArgument(i);
}
}
if (accountNumber != null) {
// Attempt to find a matching granted authority
String targetAttribute = "ACCOUNT_"
+ accountNumber.toString();
for (int i = 0; i < authentication.getAuthorities().length;
i++) {
if (targetAttribute.equals(
authentication.getAuthorities()[i].getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
}
return result;
}
}

View File

@@ -0,0 +1,43 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity;
import net.sf.acegisecurity.context.ContextInvalidException;
import net.sf.acegisecurity.context.SecureContextImpl;
/**
* Demonstrates subclassing the {@link SecureContextImpl} with
* application-specific requirements.
*
* @author Ben Alex
* @version $Id$
*/
public class ExoticSecureContext extends SecureContextImpl {
//~ Instance fields ========================================================
private int magicNumber;
//~ Methods ================================================================
public void setMagicNumber(int magicNumber) {
this.magicNumber = magicNumber;
}
public int getMagicNumber() {
return magicNumber;
}
public void validate() throws ContextInvalidException {
super.validate();
if (magicNumber != 7) {
throw new ContextInvalidException("Magic number is not 7");
}
}
}

View File

@@ -0,0 +1,217 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity;
import junit.framework.TestCase;
import net.sf.acegisecurity.context.Account;
import net.sf.acegisecurity.context.BankManager;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.ContextImpl;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests security objects.
*
* @author Ben Alex
* @version $Id$
*/
public class SecurityTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public SecurityTests() {
super();
}
public SecurityTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(SecurityTests.class);
}
public void testDetectsInvalidConfigAttribute() throws Exception {
try {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/badContext.xml");
fail("Should have thrown BeanCreationException");
} catch (BeanCreationException expected) {
assertTrue(true);
}
}
public void testSecurityInterceptorCustomVoter() throws Exception {
Account marissa = new Account(2, "marissa");
BankManager bank = (BankManager) ctx.getBean("bankManager");
// Indicate the authenticated user holds an account number of 65
GrantedAuthority[] useless = {new GrantedAuthorityImpl("ACCOUNT_65")};
TestingAuthenticationToken auth = new TestingAuthenticationToken("Peter",
"emu", useless);
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
// Confirm the absence of holding a valid account number rejects access
try {
bank.saveAccount(marissa);
fail("Should have thrown an AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
// Now setup a user with the correct account number
GrantedAuthority[] account2 = {new GrantedAuthorityImpl("ACCOUNT_2")};
auth = new TestingAuthenticationToken("Kristy", "opal", account2);
secureContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
// Check the user can perform operations related to their account number
bank.loadAccount(marissa.getId());
ContextHolder.setContext(null);
}
public void testSecurityInterceptorDetectsInvalidContexts()
throws Exception {
// Normally the security interceptor does not need to detect these conditions,
// because the context interceptor should with its validate method. However,
// the security interceptor still checks it is passed the correct objects.
Account ben = new Account(1, "ben");
BankManager bank = (BankManager) ctx.getBean("bankManager");
// First try with a totally empty ContextHolder
try {
bank.saveAccount(ben);
fail(
"Should have thrown AuthenticationCredentialsNotFoundException");
} catch (AuthenticationCredentialsNotFoundException expected) {
assertTrue(true);
}
// Now try with a ContextHolder but of the wrong type (not a SecureContext)
Context context = new ContextImpl();
ContextHolder.setContext(context);
try {
bank.saveAccount(ben);
fail(
"Should have thrown AuthenticationCredentialsNotFoundException");
} catch (AuthenticationCredentialsNotFoundException expected) {
assertTrue(true);
}
// Next try with a SecureContext but without an authentication object in it
SecureContext secureContext = new SecureContextImpl();
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(ben);
fail(
"Should have thrown AuthenticationCredentialsNotFoundException");
} catch (AuthenticationCredentialsNotFoundException expected) {
assertTrue(true);
}
// Now try with a SecureContext, correctly setup, which should work
GrantedAuthority[] granted = {new GrantedAuthorityImpl(
"ROLE_SUPERVISOR")};
TestingAuthenticationToken auth = new TestingAuthenticationToken("Jeni",
"kangaroo", granted);
secureContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
Account marissa = new Account(2, "marissa");
marissa.deposit(2000);
bank.saveAccount(marissa);
assertTrue(2000 == bank.getBalance(marissa.getId()));
// Now confirm if we subclass SecureContextImpl it still works.
// Note the validate method in our ExoticSecureContext will not be
// called, as we do not have the context interceptor defined.
ExoticSecureContext exoticContext = new ExoticSecureContext();
exoticContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
Account scott = new Account(3, "scott");
scott.deposit(50);
bank.saveAccount(scott);
assertTrue(50 == bank.getBalance(scott.getId()));
ContextHolder.setContext(null);
}
public void testSecurityInterceptorEnforcesRoles()
throws Exception {
Account ben = new Account(1, "ben");
ben.deposit(25);
BankManager bank = (BankManager) ctx.getBean("bankManager");
// Indicate the authenticated user holds a role that is not useful
GrantedAuthority[] useless = {new GrantedAuthorityImpl(
"ROLE_NOTHING_USEFUL")};
TestingAuthenticationToken auth = new TestingAuthenticationToken("George",
"koala", useless);
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
// Confirm the absence of holding a valid role rejects access
try {
bank.saveAccount(ben);
fail("Should have thrown an AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
// Now try to call a public method (getBankFundsUnderControl)
bank.getBankFundsUnderControl();
// Now setup a user with only a teller role
GrantedAuthority[] teller = {new GrantedAuthorityImpl("ROLE_TELLER")};
auth = new TestingAuthenticationToken("Michelle", "wombat", teller);
secureContext.setAuthentication(auth);
ContextHolder.setContext((Context) secureContext);
// Confirm the absence of ROLE_SUPERVISOR prevents calling deleteAccount
try {
bank.deleteAccount(ben.getId());
fail("Should have thrown an AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
// Check the teller can perform ROLE_TELLER secured operations
bank.saveAccount(ben);
assertTrue(25 == bank.getBalance(ben.getId()));
ContextHolder.setContext(null);
}
}

View File

@@ -0,0 +1,76 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.adapters;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationManager;
import net.sf.acegisecurity.adapters.jetty.JettyAcegiUserToken;
import net.sf.acegisecurity.providers.ProviderNotFoundException;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests {@link AuthByAdapterProvider}
*
* @author Ben Alex
* @version $Id$
*/
public class AuthByAdapterTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public AuthByAdapterTests() {
super();
}
public AuthByAdapterTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/adapters/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(AuthByAdapterTests.class);
}
public void testAdapterProvider() throws Exception {
AuthenticationManager authMgr = (AuthenticationManager) ctx.getBean(
"providerManager");
// Should authenticate as JettySpringUser is interface of AuthByAdapter
JettyAcegiUserToken jetty = new JettyAcegiUserToken("my_password",
"Test", "Password", null);
Authentication response = authMgr.authenticate(jetty);
jetty = null;
assertTrue(true);
// Should fail as UsernamePassword is not interface of AuthByAdapter
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("Test",
"Password");
try {
Authentication response2 = authMgr.authenticate(user);
fail("Should have thrown ProviderNotFoundException");
} catch (ProviderNotFoundException expected) {
assertTrue(true);
}
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- Authentication provider that accepts as valid any adapter-created Authentication token -->
<bean id="authByAdapterProvider" class="net.sf.acegisecurity.adapters.AuthByAdapterProvider">
<property name="key"><value>my_password</value></property>
</bean>
<!-- The authentication manager that iterates through our authentication providers -->
<bean id="providerManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="authByAdapterProvider"/>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- This authentication provider accepts any presented TestingAuthenticationToken -->
<bean id="testingAuthenticationProvider" class="net.sf.acegisecurity.providers.TestingAuthenticationProvider"/>
<!-- The authentication manager that iterates through our only authentication provider -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="testingAuthenticationProvider"/>
</list>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An access decision voter that reads BANKSECURITY_CUSTOMER configuaration settings -->
<bean id="bankSecurityVoter" class="net.sf.acegisecurity.BankSecurityVoter"/>
<!-- An affirmative access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="bankSecurityVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<!-- No declaration for BankManager.getBankFundsUnderControl() makes it public -->
<bean id="bankManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER
net.sf.acegisecurity.context.BankManager.loadAccount=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER
net.sf.acegisecurity.context.BankManager.saveAccount=ROLE_TELLER,ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.transferFunds=ROLE_SUPERVISOR
</value>
</property>
</bean>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="bankManagerTarget" class="net.sf.acegisecurity.context.BankManagerImpl"/>
<!-- We don't include any context interceptor, although we should do so prior to the security interceptor -->
<bean id="bankManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>net.sf.acegisecurity.context.BankManager</value></property>
<property name="interceptorNames">
<list>
<value>bankManagerSecurity</value>
<value>bankManagerTarget</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,141 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MethodDefinitionAttributes;
import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public class AttributesTests extends TestCase {
//~ Instance fields ========================================================
ClassPathXmlApplicationContext applicationContext;
//~ Constructors ===========================================================
/**
*
*/
public AttributesTests(String a) {
super(a);
}
//~ Methods ================================================================
public void testAttributesForImpl() throws Exception {
ConfigAttributeDefinition def = getConfigAttributeDefinition(TestServiceImpl.class);
Set set = toSet(def);
assertTrue(set.contains(new SecurityConfig("ROLE_INTERFACE")));
assertTrue(set.contains(new SecurityConfig("ROLE_INTERFACE_METHOD")));
assertTrue(set.contains(new SecurityConfig("ROLE_CLASS")));
assertTrue(set.contains(new SecurityConfig("ROLE_CLASS_METHOD")));
}
public void testAttributesForInterface() throws Exception {
ConfigAttributeDefinition def = getConfigAttributeDefinition(TestService.class);
Set set = toSet(def);
System.out.println(set.toString());
assertTrue(set.contains(new SecurityConfig("ROLE_INTERFACE")));
assertTrue(set.contains(new SecurityConfig("ROLE_INTERFACE_METHOD")));
}
public void testInterceptionWithMockAttributesAndSecureContext()
throws Exception {
applicationContext = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/attribute/applicationContext.xml");
TestService service = (TestService) applicationContext.getBean(
"testService");
SecureContextImpl context = new SecureContextImpl();
ContextHolder.setContext(context);
Authentication auth;
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_CLASS"), new GrantedAuthorityImpl(
"ROLE_INTERFACE"), new GrantedAuthorityImpl(
"ROLE_CLASS_METHOD"), new GrantedAuthorityImpl(
"ROLE_INTERFACE_METHOD")});
context.setAuthentication(auth);
service.myMethod();
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {});
context.setAuthentication(auth);
try {
service.myMethod();
fail(
"security interceptor should have detected insufficient permissions");
} catch (Exception e) {}
applicationContext.close();
ContextHolder.setContext(null);
}
private ConfigAttributeDefinition getConfigAttributeDefinition(Class clazz)
throws Exception {
final Method method = clazz.getMethod("myMethod", null);
MethodDefinitionAttributes source = new MethodDefinitionAttributes();
source.setAttributes(new TestAttributes());
ConfigAttributeDefinition config = source.getAttributes(new MockMethodInvocation() {
public Method getMethod() {
return method;
}
});
return config;
}
/**
* convert a ConfigAttributeDefinition into a set of
* <code>ConfigAttribute</code>(s)
*
* @param def DOCUMENT ME!
*
* @return
*/
private Set toSet(ConfigAttributeDefinition def) {
Set set = new HashSet();
Iterator i = def.getConfigAttributes();
while (i.hasNext()) {
ConfigAttribute a = (ConfigAttribute) i.next();
set.add(a);
}
return set;
}
}

View File

@@ -0,0 +1,67 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
import org.springframework.metadata.Attributes;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public class MockAttributes implements Attributes {
//~ Methods ================================================================
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.Class, java.lang.Class)
*/
public Collection getAttributes(Class arg0, Class arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.Class)
*/
public Collection getAttributes(Class arg0) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.reflect.Field, java.lang.Class)
*/
public Collection getAttributes(Field arg0, Class arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.reflect.Field)
*/
public Collection getAttributes(Field arg0) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.reflect.Method, java.lang.Class)
*/
public Collection getAttributes(Method arg0, Class arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.springframework.metadata.Attributes#getAttributes(java.lang.reflect.Method)
*/
public Collection getAttributes(Method arg0) {
throw new UnsupportedOperationException("mock method not implemented");
}
}

View File

@@ -0,0 +1,109 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
import org.aopalliance.intercept.AttributeRegistry;
import org.aopalliance.intercept.Invocation;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public class MockMethodInvocation implements MethodInvocation {
//~ Methods ================================================================
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#setArgument(int, java.lang.Object)
*/
public void setArgument(int arg0, Object arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#getArgument(int)
*/
public Object getArgument(int arg0) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#getArgumentCount()
*/
public int getArgumentCount() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#getArguments()
*/
public Object[] getArguments() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#getAttachment(java.lang.String)
*/
public Object getAttachment(String arg0) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#getAttributeRegistry()
*/
public AttributeRegistry getAttributeRegistry() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInvocation#getMethod()
*/
public Method getMethod() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Joinpoint#getStaticPart()
*/
public AccessibleObject getStaticPart() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Joinpoint#getThis()
*/
public Object getThis() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#addAttachment(java.lang.String, java.lang.Object)
*/
public Object addAttachment(String arg0, Object arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Invocation#cloneInstance()
*/
public Invocation cloneInstance() {
throw new UnsupportedOperationException("mock method not implemented");
}
/* (non-Javadoc)
* @see org.aopalliance.intercept.Joinpoint#proceed()
*/
public Object proceed() throws Throwable {
throw new UnsupportedOperationException("mock method not implemented");
}
}

View File

@@ -0,0 +1,65 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
import net.sf.acegisecurity.SecurityConfig;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public class TestAttributes extends MockAttributes {
//~ Instance fields ========================================================
List classAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig(
"ROLE_CLASS")});
List classMethodAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig(
"ROLE_CLASS_METHOD")});
List intrefaceAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig(
"ROLE_INTERFACE")});
List intrefaceMethodAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig(
"ROLE_INTERFACE_METHOD")});
//~ Methods ================================================================
public Collection getAttributes(Class clazz) {
// interface
if (clazz.equals(TestServiceImpl.class)) {
return classAttributes;
}
// class
if (clazz.equals(TestService.class)) {
return intrefaceAttributes;
}
return null;
}
public Collection getAttributes(Method method) {
// interface
if (method.getDeclaringClass().equals(TestService.class)) {
return intrefaceMethodAttributes;
}
// class
if (method.getDeclaringClass().equals(TestServiceImpl.class)) {
return classMethodAttributes;
}
return null;
}
}

View File

@@ -0,0 +1,19 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public interface TestService {
//~ Methods ================================================================
public abstract void myMethod();
}

View File

@@ -0,0 +1,19 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.attribute;
/**
* DOCUMENT ME!
*
* @author CameronBraid
*/
public class TestServiceImpl implements TestService {
//~ Methods ================================================================
public void myMethod() {}
}

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- This authentication provider accepts any presented TestingAuthenticationToken -->
<bean id="testingAuthenticationProvider" class="net.sf.acegisecurity.providers.TestingAuthenticationProvider"/>
<!-- The authentication manager that iterates through our only authentication provider -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="testingAuthenticationProvider"/>
</list>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An affirmative access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<bean id="attributes" class="net.sf.acegisecurity.attribute.TestAttributes"/>
<bean id="methodDefinitionSource" class="net.sf.acegisecurity.MethodDefinitionAttributes">
<property name="attributes"><ref local="attributes"/></property>
</bean>
<!-- We don't validate config attributes, as it's unsupported by MethodDefinitionAttributes -->
<bean id="securityInterceptor" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="validateConfigAttributes"><value>false</value></property>
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource"><ref bean="methodDefinitionSource"/></property>
</bean>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="testService" class="net.sf.acegisecurity.attribute.TestServiceImpl"/>
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- names of the interceptors that will be applied by the proxy -->
<property name="interceptorNames">
<list>
<value>securityInterceptor</value>
</list>
</property>
<!-- the bean names to automatically generate proxies for -->
<property name="beanNames">
<list>
<value>testService</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- This authentication provider accepts any presented TestingAuthenticationToken -->
<bean id="testingAuthenticationProvider" class="net.sf.acegisecurity.providers.TestingAuthenticationProvider"/>
<!-- The authentication manager that iterates through our only authentication provider -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="testingAuthenticationProvider"/>
</list>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An access decision voter that reads BANKSECURITY_CUSTOMER configuaration settings -->
<bean id="bankSecurityVoter" class="net.sf.acegisecurity.BankSecurityVoter"/>
<!-- An affirmative access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="bankSecurityVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<!-- Note the INVALID_ATTRIBUTE should be detected at bean context startup time -->
<bean id="bankManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,INVALID_ATTRIBUTE,BANKSECURITY_CUSTOMER
</value>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,57 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.context;
/**
* Models a bank account.
*/
public class Account {
//~ Instance fields ========================================================
private Integer id;
private String owningUserName;
private float balance;
//~ Constructors ===========================================================
public Account(Integer id, String owningUserName) {
this.id = id;
this.owningUserName = owningUserName;
}
public Account(int id, String owningUserName) {
this.id = new Integer(id);
this.owningUserName = owningUserName;
}
private Account() {
super();
}
//~ Methods ================================================================
public float getBalance() {
return this.balance;
}
public Integer getId() {
return this.id;
}
public String getOwningUserName() {
return this.owningUserName;
}
public void deposit(float amount) {
this.balance = this.balance + amount;
}
public void withdraw(float amount) {
this.balance = this.balance - amount;
}
}

View File

@@ -0,0 +1,36 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.context;
/**
* Simple business object of an in-memory banking system.
*
* <p>
* We'll spare you from <code>InsufficientFundsExceptions</code> etc. After
* all, this is intended to test security features rather than OO design!
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public interface BankManager {
//~ Methods ================================================================
public float getBalance(Integer accountNumber);
public float getBankFundsUnderControl();
public void deleteAccount(Integer accountNumber);
public Account loadAccount(Integer accountNumber);
public void saveAccount(Account account);
public void transferFunds(Integer fromAccountNumber,
Integer toAccountNumber, float amount);
}

View File

@@ -0,0 +1,67 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.context;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Implementation of {@link BankManager}.
*
* @author Ben Alex
* @version $Id$
*/
public class BankManagerImpl implements BankManager {
//~ Instance fields ========================================================
private Map accounts = new HashMap();
//~ Methods ================================================================
public float getBalance(Integer accountNumber) {
Account account = this.loadAccount(accountNumber);
return account.getBalance();
}
public float getBankFundsUnderControl() {
float total = 0;
Iterator iter = this.accounts.keySet().iterator();
while (iter.hasNext()) {
Integer account = (Integer) iter.next();
total = total + this.getBalance(account);
}
return total;
}
public void deleteAccount(Integer accountNumber) {
this.accounts.remove(accountNumber);
}
public Account loadAccount(Integer accountNumber) {
return (Account) accounts.get(accountNumber);
}
public void saveAccount(Account account) {
this.accounts.put(account.getId(), account);
}
public void transferFunds(Integer fromAccountNumber,
Integer toAccountNumber, float amount) {
Account from = this.loadAccount(fromAccountNumber);
Account to = this.loadAccount(toAccountNumber);
from.withdraw(amount);
to.deposit(amount);
this.saveAccount(from);
this.saveAccount(to);
}
}

View File

@@ -0,0 +1,120 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.context;
import junit.framework.TestCase;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests context objects.
*
* @author Ben Alex
* @version $Id$
*/
public class ContextTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public ContextTests() {
super();
}
public ContextTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/context/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(ContextTests.class);
}
public void testContextInterceptorDetectsEmptyContexts()
throws Exception {
Account ben = new Account(1, "ben");
BankManager bank = (BankManager) ctx.getBean("bankManager");
try {
bank.saveAccount(ben);
fail("Should have thrown ContextHolderEmptyException");
} catch (ContextHolderEmptyException expected) {
assertTrue(true);
}
Context context = new ContextImpl();
ContextHolder.setContext(context);
Account marissa = new Account(2, "marissa");
bank.saveAccount(marissa);
ContextHolder.setContext(null);
}
public void testContextInterceptorProcessesValidations()
throws Exception {
ExoticContext context = new ExoticContext();
ContextHolder.setContext(context);
Account ben = new Account(1, "ben");
BankManager bank = (BankManager) ctx.getBean("bankManager");
try {
bank.saveAccount(ben);
fail(
"Should have thrown ContextInvalidException (magic number is incorrect)");
} catch (ContextInvalidException expected) {
assertTrue(true);
}
context.setMagicNumber(7);
ContextHolder.setContext(context);
Account marissa = new Account(2, "marissa");
bank.saveAccount(marissa);
ContextHolder.setContext(null);
}
public void testContextInterceptorValidatesASecureContext()
throws Exception {
SecureContext context = new SecureContextImpl();
ContextHolder.setContext((Context) context);
Account ben = new Account(1, "ben");
BankManager bank = (BankManager) ctx.getBean("bankManager");
try {
bank.saveAccount(ben);
fail(
"Should have thrown ContextInvalidException (no authentication object)");
} catch (ContextInvalidException expected) {
assertTrue(true);
}
context.setAuthentication(new TestingAuthenticationToken("a", "b", null));
ContextHolder.setContext((Context) context);
Account marissa = new Account(2, "marissa");
bank.saveAccount(marissa);
ContextHolder.setContext(null);
}
}

View File

@@ -0,0 +1,41 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.context;
/**
* Exotic implementation of a {@link Context}.
*
* <p>
* Requires the context to be set with a <code>magicNumber</code> of 7. Tests
* validation in the unit tests.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ExoticContext implements Context {
//~ Instance fields ========================================================
private int magicNumber;
//~ Methods ================================================================
public void setMagicNumber(int magicNumber) {
this.magicNumber = magicNumber;
}
public int getMagicNumber() {
return magicNumber;
}
public void validate() throws ContextInvalidException {
if (magicNumber != 7) {
throw new ContextInvalidException("Magic number is not 7");
}
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== CONTEXT RELATED DEFINITIONS ================== -->
<bean id="contextInterceptor" class="net.sf.acegisecurity.context.ContextInterceptor"/>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="bankManagerTarget" class="net.sf.acegisecurity.context.BankManagerImpl"/>
<bean id="bankManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>net.sf.acegisecurity.context.BankManager</value></property>
<property name="interceptorNames">
<list>
<value>contextInterceptor</value>
<value>bankManagerTarget</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,189 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.providers.dao.memory;
import junit.framework.TestCase;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.DisabledException;
import net.sf.acegisecurity.context.Account;
import net.sf.acegisecurity.context.BankManager;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests {@link DaoAuthenticationProvider} with {@link InMemoryDaoImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class InMemoryDaoTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public InMemoryDaoTests() {
super();
}
public InMemoryDaoTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/providers/dao/memory/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(InMemoryDaoTests.class);
}
public void testAuthentication() throws Exception {
Account account = new Account(1, "someone");
BankManager bank = (BankManager) ctx.getBean("bankManager");
// Try with an invalid username and password
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("jennifer",
"zebra");
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a BadCredentialsException");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
// Check our token represents itself properly as a String
System.out.println(token.toString());
assertTrue(token.toString().length() > 10);
// Now try with a valid username, but invalid password
token = new UsernamePasswordAuthenticationToken("marissa", "zebra");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a BadCredentialsException");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
// Now try with a valid username and password, but disabled user
token = new UsernamePasswordAuthenticationToken("dianne", "emu");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a DisabledException");
} catch (DisabledException expected) {
assertTrue(true);
}
// Now try as a user who didn't have a password defined, and thus
// would have been considered invalid at time of creation
token = new UsernamePasswordAuthenticationToken("someoneelse", "");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a BadCredentialsException");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
// Now try as a user who had a password, but no granted authorities,
// and thus would have been considered invalid at time of creation
token = new UsernamePasswordAuthenticationToken("someone", "password");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a BadCredentialsException");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
// Now try with a valid mixed case username, valid mixed case password,
// (application context requires passwords to be case matched)
token = new UsernamePasswordAuthenticationToken("MaRiSsA", "kOaLa");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown a BadCredentialsException");
} catch (BadCredentialsException expected) {
assertTrue(true);
}
// Now try with a valid mixed case username, correct case password,
// (application context does not require usernames to be case matched)
token = new UsernamePasswordAuthenticationToken("MaRiSsA", "koala");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
bank.saveAccount(account);
ContextHolder.setContext(null);
}
public void testAuthorization() throws Exception {
Account account = new Account(45, "someone");
BankManager bank = (BankManager) ctx.getBean("bankManager");
// Try as a user without access to the account
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
"opal");
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
// NB: account number 45 != granted authority for account 77
bank.loadAccount(account.getId());
fail("Should have thrown an AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
// Now try as user with access to account number 45
token = new UsernamePasswordAuthenticationToken("scott", "wombat");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
bank.loadAccount(account.getId());
assertTrue(true);
// Now try as user with ROLE_SUPERVISOR access to the account
token = new UsernamePasswordAuthenticationToken("marissa", "koala");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
bank.loadAccount(account.getId());
assertTrue(true);
ContextHolder.setContext(null);
}
}

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- Data access object which stores authentication information -->
<!-- The two invalid entries at the bottom are provided for testing purposes -->
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,disabled,ROLE_TELLER
scott=wombat,ACCOUNT_45
peter=opal,ACCOUNT_77
someone=password
someoneelse=
</value>
</property>
</bean>
<!-- Authentication provider that queries our data access object -->
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
<property name="ignorePasswordCase"><value>false</value></property>
<property name="ignoreUsernameCase"><value>true</value></property>
</bean>
<!-- Authentication provider that accepts as valid our RunAsManagerImpl created tokens -->
<bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthenticationProvider">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- The authentication manager that iterates through our authentication providers -->
<!-- Strictly we don't need runAsAuthenticationProvider given we haven't defined any RUN_AS configurations -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref bean="runAsAuthenticationProvider"/>
</list>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An access decision voter that reads BANKSECURITY_CUSTOMER configuaration settings -->
<bean id="bankSecurityVoter" class="net.sf.acegisecurity.BankSecurityVoter"/>
<!-- An affirmative access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="bankSecurityVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<!-- No declaration for BankManager.getBankFundsUnderControl() makes it public -->
<bean id="bankManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER
net.sf.acegisecurity.context.BankManager.loadAccount=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER
net.sf.acegisecurity.context.BankManager.saveAccount=ROLE_TELLER,ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.transferFunds=ROLE_SUPERVISOR
</value>
</property>
</bean>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="bankManagerTarget" class="net.sf.acegisecurity.context.BankManagerImpl"/>
<!-- We don't include any context interceptor, although we should do so prior to the security interceptor -->
<bean id="bankManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>net.sf.acegisecurity.context.BankManager</value></property>
<property name="interceptorNames">
<list>
<value>bankManagerSecurity</value>
<value>bankManagerTarget</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,75 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.runas;
import net.sf.acegisecurity.context.Account;
import net.sf.acegisecurity.context.BankManager;
import org.springframework.beans.factory.InitializingBean;
/**
* Acts as the "public facade" to a <code>BankManager</code>.
*
* <P>
* The security configuration of this, the public facade, specifies authorities
* that should be held by the end user. The security configuration of the
* "backend", which is not accessible to the general public, specifies certain
* authorities that are granted by the RunAsManagerImpl.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class BankManagerPublicFacade implements BankManager, InitializingBean {
//~ Instance fields ========================================================
private BankManager backend;
//~ Methods ================================================================
public void setBackend(BankManager backend) {
this.backend = backend;
}
public BankManager getBackend() {
return backend;
}
public float getBalance(Integer accountNumber) {
return backend.getBalance(accountNumber);
}
public float getBankFundsUnderControl() {
return backend.getBankFundsUnderControl();
}
public void afterPropertiesSet() throws Exception {
if (backend == null) {
throw new IllegalArgumentException(
"A backend BankManager implementation is required");
}
}
public void deleteAccount(Integer accountNumber) {
backend.deleteAccount(accountNumber);
}
public Account loadAccount(Integer accountNumber) {
return backend.loadAccount(accountNumber);
}
public void saveAccount(Account account) {
backend.saveAccount(account);
}
public void transferFunds(Integer fromAccountNumber,
Integer toAccountNumber, float amount) {
backend.transferFunds(fromAccountNumber, toAccountNumber, amount);
}
}

View File

@@ -0,0 +1,106 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.runas;
import junit.framework.TestCase;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.context.Account;
import net.sf.acegisecurity.context.BankManager;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests {@link RunAsManagerImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class RunAsTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public RunAsTests() {
super();
}
public RunAsTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/runas/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(RunAsTests.class);
}
public void testRunAs() throws Exception {
Account account = new Account(45, "someone");
BankManager bank = (BankManager) ctx.getBean("bankManager");
// Try as a user without access to the account
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter",
"opal");
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
// NB: account number 45 != granted authority for account 77
bank.loadAccount(account.getId());
fail("Should have thrown an AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
// Now try as user with access to account number 45
// Proves ROLE_RUN_AS_SERVER is being allocated
token = new UsernamePasswordAuthenticationToken("scott", "wombat");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
bank.loadAccount(account.getId());
assertTrue(true);
// Now try as user with ROLE_SUPERVISOR access to the account
// Proves ROLE_RUN_AS_SERVER is being allocated
token = new UsernamePasswordAuthenticationToken("marissa", "koala");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
bank.loadAccount(account.getId());
assertTrue(true);
// Now try to call a method that ROLE_RUN_AS_BACKEND not granted for
token = new UsernamePasswordAuthenticationToken("marissa", "koala");
secureContext.setAuthentication(token);
ContextHolder.setContext((Context) secureContext);
try {
bank.saveAccount(account);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
ContextHolder.setContext(null);
}
}

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->
<!-- Data access object which stores authentication information -->
<!-- The two invalid entries at the bottom are provided for testing purposes -->
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,disabled,ROLE_TELLER
scott=wombat,ACCOUNT_45
peter=opal,ACCOUNT_77
someone=password
someoneelse=
</value>
</property>
</bean>
<!-- Authentication provider that queries our data access object -->
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
<property name="ignorePasswordCase"><value>false</value></property>
<property name="ignoreUsernameCase"><value>true</value></property>
</bean>
<!-- Authentication provider that accepts as valid our RunAsManagerImpl created tokens -->
<bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthenticationProvider">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<!-- The authentication manager that iterates through our authentication providers -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref bean="runAsAuthenticationProvider"/>
</list>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An access decision voter that reads BANKSECURITY_CUSTOMER configuaration settings -->
<bean id="bankSecurityVoter" class="net.sf.acegisecurity.BankSecurityVoter"/>
<!-- An affirmative access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="bankSecurityVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<!-- Note we don't specify to grant RUN_AS_SERVER to saveAccount invocations -->
<bean id="publicBankManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.loadAccount=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.saveAccount=ROLE_TELLER,ROLE_SUPERVISOR
net.sf.acegisecurity.context.BankManager.transferFunds=ROLE_SUPERVISOR,RUN_AS_SERVER
</value>
</property>
</bean>
<!-- We expect all callers of the backend object to hold the role ROLE_RUN_AS_SERVER -->
<bean id="backendBankManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=ROLE_RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.getBalance=ROLE_RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.loadAccount=ROLE_RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.saveAccount=ROLE_RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.transferFunds=ROLE_RUN_AS_SERVER
</value>
</property>
</bean>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="bankManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>net.sf.acegisecurity.context.BankManager</value></property>
<property name="interceptorNames">
<list>
<value>publicBankManagerSecurity</value>
<value>publicBankManagerTarget</value>
</list>
</property>
</bean>
<bean id="publicBankManagerTarget" class="net.sf.acegisecurity.runas.BankManagerPublicFacade">
<property name="backend"><ref bean="backendBankManager"/></property>
</bean>
<bean id="backendBankManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>net.sf.acegisecurity.context.BankManager</value></property>
<property name="interceptorNames">
<list>
<value>backendBankManagerSecurity</value>
<value>backendBankManagerTarget</value>
</list>
</property>
</bean>
<bean id="backendBankManagerTarget" class="net.sf.acegisecurity.context.BankManagerImpl"/>
</beans>

View File

@@ -0,0 +1,268 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.vote;
import junit.framework.TestCase;
import net.sf.acegisecurity.AccessDecisionManager;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests voter decision managers.
*
* @author Ben Alex
* @version $Id$
*/
public class VoterManagerTests extends TestCase {
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public VoterManagerTests() {
super();
}
public VoterManagerTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext(
"/net/sf/acegisecurity/vote/applicationContext.xml");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(VoterManagerTests.class);
}
public void testAffirmative() throws Exception {
AccessDecisionManager mgr = (AccessDecisionManager) ctx.getBean(
"affirmativeBased");
ConfigAttributeDefinition config;
TestingAuthenticationToken auth;
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"), new GrantedAuthorityImpl("ROLE_MAGIC")});
// Check if we'd get access if ROLE_2 was all that is acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if YYYY was all that is acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if everything was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
config.addConfigAttribute(new SecurityConfig("XXXX")); // grant
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if ROLE_9 was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_9")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"),});
// Check if we'd get access if ROLE_1 and 2 was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get granted access even if one returned deny
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
config.addConfigAttribute(new SecurityConfig("XXXX")); // deny
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if all returned deny
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("YYYY")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
public void testConsensus() throws Exception {
AccessDecisionManager mgr = (AccessDecisionManager) ctx.getBean(
"consensusBased");
ConfigAttributeDefinition config;
TestingAuthenticationToken auth;
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"), new GrantedAuthorityImpl("ROLE_MAGIC")});
// Check if we'd get access if ROLE_2 was all that is acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if YYYY was all that is acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if everything was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
config.addConfigAttribute(new SecurityConfig("XXXX")); // grant
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if ROLE_9 was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_9")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"),});
// Check if we'd get access if ROLE_1 and 2 was acceptable
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get granted access even if one returned deny
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant and return
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // not tested
config.addConfigAttribute(new SecurityConfig("XXXX")); // deny
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if all returned deny
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("XXXX")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
public void testUnanimous() throws Exception {
AccessDecisionManager mgr = (AccessDecisionManager) ctx.getBean(
"unanimousBased");
ConfigAttributeDefinition config;
TestingAuthenticationToken auth;
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"), new GrantedAuthorityImpl("ROLE_MAGIC")});
// Check if we'd get access if ROLE_2 was all that is required
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if YYYY was all that is required
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get access if everything was required
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
config.addConfigAttribute(new SecurityConfig("XXXX")); // grant
config.addConfigAttribute(new SecurityConfig("YYYY")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if ROLE_9 was required
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_9")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
auth = new TestingAuthenticationToken("test", "test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
"ROLE_2"),});
// Check if we'd get access if ROLE_1 and 2 was required
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
mgr.decide(auth, null, config);
assertTrue(true);
// Check if we'd get denied access if all any return deny at all
config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
config.addConfigAttribute(new SecurityConfig("XXXX")); // deny
try {
mgr.decide(auth, null, config);
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.vote;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import org.aopalliance.intercept.MethodInvocation;
import java.util.Iterator;
/**
* Implementation of an {@link AccessDecisionVoter} for unit testing.
*
* <p>
* If the {@link ConfigAttribute#getAttribute()} has a value of
* <code>XXXX</code>, a granted authority that equals <code>ROLE_MAGIC</code>
* will cause a grant vote. The voter will abstain if there is no
* configuration attribute named <code>XXXX</code>.
* </p>
*
* <p>
* All comparisons are case sensitive.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class XVoter implements AccessDecisionVoter {
//~ Methods ================================================================
public boolean supports(ConfigAttribute attribute) {
if ("XXXX".equals(attribute.getAttribute())) {
return true;
} else {
return false;
}
}
public int vote(Authentication authentication, MethodInvocation invocation,
ConfigAttributeDefinition config) {
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
for (int i = 0; i < authentication.getAuthorities().length;
i++) {
if ("ROLE_MAGIC".equals(
authentication.getAuthorities()[i].getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
}

View File

@@ -0,0 +1,70 @@
/*
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
*
* Visit http://acegisecurity.sourceforge.net for further details.
*/
package net.sf.acegisecurity.vote;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import org.aopalliance.intercept.MethodInvocation;
import java.util.Iterator;
/**
* Implementation of an {@link AccessDecisionVoter} for unit testing.
*
* <p>
* If the {@link ConfigAttribute#getAttribute()} has a value of
* <code>YYYY</code>, a granted authority that equals <code>ROLE_MAGIC</code>
* will cause a grant vote. The voter will abstain if there is no
* configuration attribute named <code>YYYY</code>.
* </p>
*
* <p>
* All comparisons are case sensitive.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class YVoter implements AccessDecisionVoter {
//~ Methods ================================================================
public boolean supports(ConfigAttribute attribute) {
if ("YYYY".equals(attribute.getAttribute())) {
return true;
} else {
return false;
}
}
public int vote(Authentication authentication, MethodInvocation invocation,
ConfigAttributeDefinition config) {
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
for (int i = 0; i < authentication.getAuthorities().length;
i++) {
if ("ROLE_MAGIC".equals(
authentication.getAuthorities()[i].getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
}

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* The Acegi Security System for Spring is published under the terms
* of the Apache Software License.
* $Id$
-->
<beans>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<!-- An access decision voter that reads XXXX configuaration settings -->
<bean id="xVoter" class="net.sf.acegisecurity.vote.XVoter"/>
<!-- An access decision voter that reads YYYY configuaration settings -->
<bean id="yVoter" class="net.sf.acegisecurity.vote.YVoter"/>
<bean id="unanimousBased" class="net.sf.acegisecurity.vote.UnanimousBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="xVoter"/>
<ref bean="yVoter"/>
</list>
</property>
</bean>
<bean id="affirmativeBased" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="xVoter"/>
<ref bean="yVoter"/>
</list>
</property>
</bean>
<bean id="consensusBased" class="net.sf.acegisecurity.vote.ConsensusBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="allowIfEqualGrantedDeniedDecisions"><value>true</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
<ref bean="xVoter"/>
<ref bean="yVoter"/>
</list>
</property>
</bean>
</beans>