No longer required.
This commit is contained in:
parent
91432bc78b
commit
6a2870d8f0
|
@ -1,96 +0,0 @@
|
|||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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.getArguments().length; i++) {
|
||||
Class argClass = invocation.getArguments()[i].getClass();
|
||||
|
||||
if (Integer.class.isAssignableFrom(argClass)) {
|
||||
accountNumber = (Integer) invocation.getArguments()[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;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
/* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
<?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>
|
|
@ -1,66 +0,0 @@
|
|||
<?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>
|
Loading…
Reference in New Issue