1
0
mirror of synced 2026-08-05 17:57:15 +00:00

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
+4
View File
@@ -0,0 +1,4 @@
classes
generated
reports
+119
View File
@@ -0,0 +1,119 @@
<?xml version="1.0"?>
<!--
Build file for the "attributes" sample application.
Demonstrates how to compile an application that has the security
configuration defined by Commons Attributes in its Java source code.
$Id$
-->
<project name="attributes" default="all" basedir=".">
<property file="build.properties"/>
<property file="project.properties"/>
<path id="attribute-compiler-classpath">
<fileset dir="${lib.dir}">
<include name="**/commons-attributes-compiler-SNAPSHOT.jar"/>
<include name="**/commons-collections.jar"/>
<include name="**/xjavadoc-1.0.jar"/>
</fileset>
</path>
<path id="qa-portalpath">
<pathelement location="classes"/>
<fileset dir="${dist.lib.dir}">
<include name="acegi-security.jar"/>
</fileset>
<fileset dir="${lib.dir}">
<include name="**/spring.jar"/>
<include name="**/aopalliance.jar"/>
<include name="**/commons-logging.jar"/>
<include name="**/commons-attributes-api-SNAPSHOT.jar"/>
<include name="**/commons-collections.jar"/>
<include name="**/xml-apis.jar"/>
</fileset>
</path>
<path id="jalopy-classpath">
<fileset dir="${lib.dir}/jalopy">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="attribute-compiler" description="Generate Commons Attributes sources from original sources">
<taskdef name='attribute-compiler'
classname="org.apache.commons.attributes.compiler.AttributeCompiler"
classpathref="attribute-compiler-classpath"/>
<attribute-compiler
destdir="${src.generated.dir}"
attributePackages="net.sf.acegisecurity">
<fileset dir="${src.dir}"/>
</attribute-compiler>
</target>
<target name="compile-classes" description="Compile generated and original sources">
<mkdir dir="${build.dir}"/>
<javac destdir="${build.dir}" classpathref="qa-portalpath">
<src path="${src.dir}"/>
<src path="${src.generated.dir}"/>
</javac>
<copy todir="${build.dir}">
<fileset dir="${src.dir}">
<include name="*.xml"/>
</fileset>
</copy>
</target>
<target name="format" description="Formats all project source code">
<taskdef name="jalopy" classname="de.hunsicker.jalopy.plugin.ant.AntPlugin">
<classpath refid="jalopy-classpath"/>
</taskdef>
<jalopy fileformat="unix"
convention="${jalopy.xml}"
history="file"
historymethod="adler32"
loglevel="error"
threads="2"
classpathref="qa-portalpath">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</jalopy>
</target>
<target name="tests" depends="compile-classes" description="Run tests">
<delete dir="${reports.dir}"/>
<mkdir dir="${reports.dir}"/>
<junit printsummary="yes" haltonfailure="yes">
<classpath location="${build.dir}"/>
<classpath refid="qa-portalpath"/>
<formatter type="plain"/>
<batchtest fork="yes" todir="${reports.dir}">
<fileset dir="${build.dir}" includes="${test.includes}" excludes="${test.excludes}"/>
</batchtest>
</junit>
</target>
<target name="clean" description="Clean output dirs (generated, classes, reports)">
<delete dir="${src.generated.dir}"/>
<delete dir="${build.dir}"/>
<delete dir="${reports.dir}"/>
</target>
<target name="all" depends="clean, attribute-compiler, compile-classes, tests" description="Builds from scratch and runs tests"/>
<target name="execute" description="Runs application (assumes has been built)">
<java fork="true" qa-portalpathref="qa-portalpath" classname="sample.attributes.Main"/>
</target>
<target name="release" depends="all" description="Builds a clean release file"/>
</project>
+13
View File
@@ -0,0 +1,13 @@
# Ant properties for building the Attributes sample application.
# $Id$
name=attributes
src.dir=src
src.generated.dir=generated
lib.dir=${basedir}/../../lib
dist.lib.dir=${basedir}/../../dist
build.dir=classes
jalopy.xml=${basedir}/../../jalopy.xml
reports.dir=reports
test.includes=**/*TestSuite.class **/*Tests.class
test.excludes=**/Abstract*
@@ -0,0 +1,81 @@
<?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"/>
<!-- A unanimous access decision manager -->
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.UnanimousBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/>
<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>
<bean id="bankService" class="sample.attributes.BankServiceImpl"/>
<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>bankService</value>
</list>
</property>
</bean>
</beans>
@@ -0,0 +1,45 @@
/*
* 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 sample.attributes;
/**
* DOCUMENT ME!
*
* @author Cameron Braid
* @author Ben Alex
* @version $Id$
*
* @@SecurityConfig("ROLE_TELLER")
*/
public interface BankService {
//~ Methods ================================================================
/**
* The SecurityConfig below will be merged with the interface-level
* SecurityConfig above by Commons Attributes. ie: this is equivalent to
* defining BankService=ROLE_TELLER,ROLE_PERMISSION_BALANACE in the bean
* context.
*
* @return DOCUMENT ME!
*
* @@SecurityConfig("ROLE_PERMISSION_BALANCE")
*/
public float balance(String accountNumber);
/**
* The SecurityConfig below will be merged with the interface-level
* SecurityConfig above by Commons Attributes. ie: this is equivalent to
* defining BankService=ROLE_TELLER,ROLE_PERMISSION_LIST in the bean
* context.
*
* @return DOCUMENT ME!
*
* @@SecurityConfig("ROLE_PERMISSION_LIST")
*/
public String[] listAccounts();
}
@@ -0,0 +1,27 @@
/*
* 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 sample.attributes;
/**
* DOCUMENT ME!
*
* @author Cameron Braid
* @author Ben Alex
* @version $Id$
*/
public class BankServiceImpl implements BankService {
//~ Methods ================================================================
public float balance(String accountNumber) {
return 42000000;
}
public String[] listAccounts() {
return new String[] {"1", "2", "3"};
}
}
@@ -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 sample.attributes;
import junit.framework.TestCase;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Tests security objects.
*
* @author Ben Alex
* @version $Id$
*/
public class BankTests extends TestCase {
//~ Instance fields ========================================================
private BankService service;
private ClassPathXmlApplicationContext ctx;
//~ Constructors ===========================================================
public BankTests() {
super();
}
public BankTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
service = (BankService) ctx.getBean("bankService");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(BankTests.class);
}
public void testDeniedAccess() throws Exception {
createSecureContext();
try {
service.balance("1");
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
destroySecureContext();
}
public void testListAccounts() throws Exception {
createSecureContext();
service.listAccounts();
destroySecureContext();
}
private static void createSecureContext() {
TestingAuthenticationToken auth = new TestingAuthenticationToken("test",
"test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST")});
SecureContextImpl secureContext = new SecureContextImpl();
secureContext.setAuthentication(auth);
ContextHolder.setContext(secureContext);
}
private static void destroySecureContext() {
ContextHolder.setContext(null);
}
}
@@ -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 sample.attributes;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* DOCUMENT ME!
*
* @author Cameron Braid
* @author Ben Alex
* @version $Id$
*/
public class Main {
//~ Methods ================================================================
public static void main(String[] args) throws Exception {
createSecureContext();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BankService service = (BankService) context.getBean("bankService");
// will succeed
service.listAccounts();
// will fail
try {
System.out.println("We expect an AccessDeniedException now, as we do not hold the ROLE_PERMISSION_BALANCE granted authority, and we're using a unanimous access decision manager... ");
service.balance("1");
} catch (AccessDeniedException e) {
e.printStackTrace();
}
destroySecureContext();
}
/**
* This can be done in a web app by using a filter or
* <code>SpringMvcIntegrationInterceptor</code>.
*/
private static void createSecureContext() {
TestingAuthenticationToken auth = new TestingAuthenticationToken("test",
"test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST")});
SecureContextImpl secureContext = new SecureContextImpl();
secureContext.setAuthentication(auth);
ContextHolder.setContext(secureContext);
}
private static void destroySecureContext() {
ContextHolder.setContext(null);
}
}
+5
View File
@@ -0,0 +1,5 @@
classes
dist
api
build.properties
+142
View File
@@ -0,0 +1,142 @@
<?xml version="1.0"?>
<!--
Build file for the "contacts" sample application.
$Id$
-->
<project name="minimal" basedir="." default="usage">
<property file="build.properties"/>
<property file="project.properties"/>
<path id="qa-portalpath">
<fileset dir="${dist.lib.dir}">
<include name="acegi-security.jar"/>
</fileset>
<fileset dir="${lib.dir}">
<include name="**/**.jar"/>
</fileset>
</path>
<path id="jalopy-classpath">
<fileset dir="${lib.dir}/jalopy">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="usage">
<echo message=""/>
<echo message="Contacts sample application build file"/>
<echo message="*** Make sure you've copied the required JAR files to the lib directory."/>
<echo message="*** See lib/readme.txt for more information."/>
<echo message="------------------------------------------------------"/>
<echo message=""/>
<echo message="Available targets are:"/>
<echo message=""/>
<echo message="clean --> Clean output dirs"/>
<echo message="build --> Compile main Java sources and copy libraries"/>
<echo message="warfile --> Create WAR deployment units"/>
<echo message="javadoc --> Create API documentation"/>
<echo message=""/>
</target>
<target name="clean" description="Clean output dirs (build, dist)">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
<delete dir="${war.dir}/WEB-INF/lib"/>
</target>
<target name="build" description="Compile main source tree java files into class files">
<mkdir dir="${build.dir}"/>
<javac destdir="${build.dir}" target="1.3" debug="true" deprecation="false"
optimize="false" failonerror="true">
<src path="${src.dir}"/>
<classpath refid="qa-portalpath"/>
</javac>
<copy todir="${build.dir}">
<fileset dir="${src.dir}">
<include name="*.properties"/>
</fileset>
</copy>
</target>
<target name="format" description="Formats all project source code">
<taskdef name="jalopy" classname="de.hunsicker.jalopy.plugin.ant.AntPlugin">
<classpath refid="jalopy-classpath"/>
</taskdef>
<jalopy fileformat="unix"
convention="${jalopy.xml}"
history="file"
historymethod="adler32"
loglevel="error"
threads="2"
classpathref="qa-portalpath">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</jalopy>
</target>
<target name="warfile" depends="build" description="Build the web application archives">
<mkdir dir="${dist.dir}"/>
<!-- Temporary staging directory for libs -->
<delete dir="${war.dir}/WEB-INF/lib"/>
<mkdir dir="${war.dir}/WEB-INF/lib"/>
<!-- Copy required libs into temporary staging directory -->
<copy todir="${war.dir}/WEB-INF/lib">
<fileset dir="${lib.dir}/jakarta-taglibs">
<include name="standard.jar"/>
</fileset>
<fileset dir="${lib.dir}/j2ee">
<include name="jstl.jar"/>
</fileset>
</copy>
<war warfile="${dist.dir}/${name}.war" webxml="${war.dir}/WEB-INF/web.xml">
<!-- Include the JSPs and other documents -->
<fileset dir="war" excludes="WEB-INF/**"/>
<!-- Bring in Spring-specific XML configuration files -->
<webinf dir="${war.dir}/WEB-INF">
<!-- We separately include these -->
<exclude name="web.xml"/>
<exclude name="lib/**"/>
</webinf>
<!-- Include the compiled classes -->
<classes dir="${build.dir}"/>
<!-- Include the temporary staging directory for libs -->
<lib dir = "${war.dir}/WEB-INF/lib"/>
</war>
<!-- Remove temporary staging directory -->
<delete dir="${war.dir}/WEB-INF/lib"/>
</target>
<target name="javadoc" description="Generate Javadocs.">
<mkdir dir="${javadocs.dir}"/>
<javadoc sourcepath="src" destdir="${javadocs.dir}" windowtitle="Contact Sample Application"
defaultexcludes="yes" author="true" version="true" use="true">
<doctitle><![CDATA[<h1>Acegi Security System for Spring Contacts Sample</h1>]]></doctitle>
<bottom><![CDATA[<A HREF="http://acegisecurity.sourceforge.net">Acegi Security System for Spring Project]]></bottom>
<classpath refid="qa-portalpath"/>
<packageset dir="${src.dir}">
<include name="sample/contact/**"/>
</packageset>
</javadoc>
</target>
<target name="release" depends="clean,warfile,javadoc" description="Builds a clean release file"/>
</project>
+12
View File
@@ -0,0 +1,12 @@
# Ant properties for building the Contacts sample application.
# $Id$
name=contacts
src.dir=src
war.dir=war
lib.dir=${basedir}/../../lib
dist.lib.dir=${basedir}/../../dist
build.dir=classes
dist.dir=dist
javadocs.dir=api
jalopy.xml=${basedir}/../../jalopy.xml
@@ -0,0 +1,107 @@
/*
* 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 sample.contact;
/**
* Represents a contact.
*
* <P>
* <code>id</code> and <code>owner</code> are immutable.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class Contact {
//~ Instance fields ========================================================
private Integer id;
private String email;
private String name;
private String owner;
//~ Constructors ===========================================================
public Contact(Integer id, String name, String email, String owner) {
this.id = id;
this.name = name;
this.email = email;
this.owner = owner;
}
private Contact() {
super();
}
//~ Methods ================================================================
/**
* DOCUMENT ME!
*
* @param email The email to set.
*/
public void setEmail(String email) {
this.email = email;
}
/**
* DOCUMENT ME!
*
* @return Returns the email.
*/
public String getEmail() {
return email;
}
/**
* DOCUMENT ME!
*
* @return Returns the id.
*/
public Integer getId() {
return id;
}
/**
* DOCUMENT ME!
*
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* DOCUMENT ME!
*
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* DOCUMENT ME!
*
* @return Returns the owner.
*/
public String getOwner() {
return owner;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString() + ": ");
sb.append("Id: " + this.getId() + "; ");
sb.append("Name: " + this.getName() + "; ");
sb.append("Email: " + this.getEmail() + "; ");
sb.append("Owner: " + this.getOwner());
return sb.toString();
}
}
@@ -0,0 +1,30 @@
/*
* 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 sample.contact;
/**
* Iterface for the application's business object.
*
* @author Ben Alex
* @version $Id$
*/
public interface ContactManager {
//~ Methods ================================================================
public Contact[] getAllByOwner(String owner);
public Contact getById(Integer id);
public Integer getNextId();
public Contact getRandomContact();
public void delete(Contact contact);
public void save(Contact contact);
}
@@ -0,0 +1,168 @@
/*
* 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 sample.contact;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
/**
* Backend business object that manages the contacts.
*
* <P>
* As a backend, it never faces the public callers. It is always accessed via
* the {@link ContactManagerFacade}.
* </p>
*
* <P>
* This facade approach is not really necessary in this application, and is
* done simply to demonstrate granting additional authorities via the
* <code>RunAsManager</code>.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ContactManagerBackend implements ContactManager {
//~ Instance fields ========================================================
private Map contacts;
//~ Constructors ===========================================================
public ContactManagerBackend() {
this.contacts = new HashMap();
save(new Contact(this.getNextId(), "John Smith", "john@somewhere.com",
"marissa"));
save(new Contact(this.getNextId(), "Michael Citizen",
"michael@xyz.com", "marissa"));
save(new Contact(this.getNextId(), "Joe Bloggs", "joe@demo.com",
"marissa"));
save(new Contact(this.getNextId(), "Karen Sutherland",
"karen@sutherland.com", "dianne"));
save(new Contact(this.getNextId(), "Mitchell Howard",
"mitchell@abcdef.com", "dianne"));
save(new Contact(this.getNextId(), "Rose Costas", "rose@xyz.com",
"scott"));
save(new Contact(this.getNextId(), "Amanda Smith", "amanda@abcdef.com",
"scott"));
}
//~ Methods ================================================================
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param owner DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact[] getAllByOwner(String owner) {
List list = new Vector();
Iterator iter = this.contacts.keySet().iterator();
while (iter.hasNext()) {
Integer contactId = (Integer) iter.next();
Contact contact = (Contact) this.contacts.get(contactId);
if (contact.getOwner().equals(owner)) {
list.add(contact);
}
}
Contact[] resultType = {new Contact(new Integer(1), "holder", "holder",
"holder")};
if (list.size() == 0) {
return null;
} else {
return (Contact[]) list.toArray(resultType);
}
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param id DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact getById(Integer id) {
return (Contact) this.contacts.get(id);
}
/**
* Public method
*
* @return DOCUMENT ME!
*/
public Integer getNextId() {
int max = 0;
Iterator iter = this.contacts.keySet().iterator();
while (iter.hasNext()) {
Integer id = (Integer) iter.next();
if (id.intValue() > max) {
max = id.intValue();
}
}
return new Integer(max + 1);
}
/**
* This is a public method, meaning a client could call this method
* directly (ie not via a facade). If this was an issue, the public method
* on the facade should not be public but secure. Quite possibly an
* AnonymousAuthenticationToken and associated provider could be used on a
* secure method, thus allowing a RunAsManager to protect the backend.
*
* @return DOCUMENT ME!
*/
public Contact getRandomContact() {
Random rnd = new Random();
int getNumber = rnd.nextInt(this.contacts.size()) + 1;
Iterator iter = this.contacts.keySet().iterator();
int i = 0;
while (iter.hasNext()) {
i++;
Integer id = (Integer) iter.next();
if (i == getNumber) {
return (Contact) this.contacts.get(id);
}
}
return null;
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param contact DOCUMENT ME!
*/
public void delete(Contact contact) {
this.contacts.remove(contact.getId());
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param contact DOCUMENT ME!
*/
public void save(Contact contact) {
this.contacts.put(contact.getId(), contact);
}
}
@@ -0,0 +1,132 @@
/*
* 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 sample.contact;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.beans.factory.InitializingBean;
/**
* This is the public facade to the application's main business object.
*
* <p>
* Used to demonstrate security configuration in a multi-tier application. Most
* methods of this class are secured via standard security definitions in the
* bean context. There is one method that supplements these security checks.
* All methods delegate to a "backend" object. The "backend" object relies on
* the facade's <code>RunAsManager</code> assigning an additional
* <code>GrantedAuthority</code> that is required to call its methods.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ContactManagerFacade implements ContactManager, InitializingBean {
//~ Instance fields ========================================================
private ContactManager backend;
//~ Methods ================================================================
/**
* Security system will ensure the owner parameter equals the currently
* logged in user.
*
* @param owner DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact[] getAllByOwner(String owner) {
return backend.getAllByOwner(owner);
}
public void setBackend(ContactManager backend) {
this.backend = backend;
}
public ContactManager getBackend() {
return backend;
}
/**
* Security system will ensure logged in user has ROLE_TELLER.
*
* <p>
* Security system cannot ensure that only the owner can get the contact,
* as doing so would require it to specifically open the contact. Whilst
* possible, this would be expensive as the operation would be performed
* both by the security system as well as the implementation. Instead the
* facade will confirm the contact.getOwner() matches what is on the
* ContextHolder.
* </p>
*
* @param id DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws AccessDeniedException DOCUMENT ME!
*/
public Contact getById(Integer id) {
Contact result = backend.getById(id);
Authentication auth = ((SecureContext) ContextHolder.getContext())
.getAuthentication();
if (auth.getPrincipal().toString().equals(result.getOwner())) {
return result;
} else {
throw new AccessDeniedException("The requested id is not owned by the currently logged in user");
}
}
/**
* Public method.
*
* @return DOCUMENT ME!
*/
public Integer getNextId() {
return backend.getNextId();
}
/**
* Public method.
*
* @return DOCUMENT ME!
*/
public Contact getRandomContact() {
return backend.getRandomContact();
}
public void afterPropertiesSet() throws Exception {
if (backend == null) {
throw new IllegalArgumentException("A backend ContactManager implementation is required");
}
}
/**
* Security system will ensure logged in user has ROLE_SUPERVISOR.
*
* @param contact DOCUMENT ME!
*/
public void delete(Contact contact) {
backend.delete(contact);
}
/**
* Security system will ensure the owner specified via contact.getOwner()
* equals the currently logged in user.
*
* @param contact DOCUMENT ME!
*/
public void save(Contact contact) {
backend.save(contact);
}
}
@@ -0,0 +1,87 @@
/*
* 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 sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.aopalliance.intercept.MethodInvocation;
import java.util.Iterator;
/**
* Implementation of an {@link AccessDecisionVoter} that provides
* application-specific security for the Contact application.
*
* <p>
* If the {@link ConfigAttribute#getAttribute()} has a value of
* <code>CONTACT_OWNED_BY_CURRENT_USER</code>, the String or the
* Contact.getOwner() associated with the method call is compared with the
* Authentication.getPrincipal().toString() result. If it matches, the voter
* votes to grant access. If they do not match, it votes to deny access.
* </p>
*
* <p>
* All comparisons are case sensitive.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ContactSecurityVoter implements AccessDecisionVoter {
//~ Methods ================================================================
public boolean supports(ConfigAttribute attribute) {
if ("CONTACT_OWNED_BY_CURRENT_USER".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
String passedOwner = null;
for (int i = 0; i < invocation.getArgumentCount(); i++) {
Class argClass = invocation.getArgument(i).getClass();
if (String.class.isAssignableFrom(argClass)) {
passedOwner = (String) invocation.getArgument(i);
} else if (Contact.class.isAssignableFrom(argClass)) {
passedOwner = ((Contact) invocation.getArgument(i))
.getOwner();
}
}
if (passedOwner != null) {
// Check the authentication principal matches the passed owner
if (passedOwner.equals(authentication.getPrincipal()
.toString())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
}
@@ -0,0 +1,58 @@
/*
* 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 sample.contact;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller to delete a contact page.
*
* @author Ben Alex
* @version $Id$
*/
public class DeleteController implements Controller, InitializingBean {
//~ Instance fields ========================================================
private ContactManager contactManager;
//~ Methods ================================================================
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException("A ContactManager implementation is required");
}
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Integer id = new Integer(request.getParameter("id"));
Contact contact = contactManager.getById(id);
contactManager.delete(contact);
return new ModelAndView("deleted", "contact", contact);
}
}
@@ -0,0 +1,56 @@
/*
* 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 sample.contact;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller for public index page (default web app home page).
*
* @author Ben Alex
* @version $Id$
*/
public class PublicIndexController implements Controller, InitializingBean {
//~ Instance fields ========================================================
private ContactManager contactManager;
//~ Methods ================================================================
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException("A ContactManager implementation is required");
}
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Contact rnd = contactManager.getRandomContact();
return new ModelAndView("hello", "contact", rnd);
}
}
@@ -0,0 +1,82 @@
/*
* 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 sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller for secure index page.
*
* @author Ben Alex
* @version $Id$
*/
public class SecureIndexController implements Controller, InitializingBean {
//~ Instance fields ========================================================
private ContactManager contactManager;
//~ Methods ================================================================
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException("A ContactManager implementation is required");
}
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Authentication currentUser = ((SecureContext) ContextHolder.getContext())
.getAuthentication();
boolean supervisor = false;
GrantedAuthority[] granted = currentUser.getAuthorities();
for (int i = 0; i < granted.length; i++) {
if (granted[i].getAuthority().equals("ROLE_SUPERVISOR")) {
supervisor = true;
}
}
Contact[] myContacts = contactManager.getAllByOwner(currentUser.getPrincipal()
.toString());
Map model = new HashMap();
model.put("contacts", myContacts);
model.put("supervisor", new Boolean(supervisor));
model.put("user", currentUser.getPrincipal().toString());
return new ModelAndView("index", "model", model);
}
}
@@ -0,0 +1,39 @@
/*
* 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 sample.contact;
/**
* An object that represents user-editable sections of a {@link Contact}.
*
* @author Ben Alex
* @version $Id$
*/
public class WebContact {
//~ Instance fields ========================================================
private String email;
private String name;
//~ Methods ================================================================
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
@@ -0,0 +1,68 @@
/*
* 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 sample.contact;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
/**
* Controller for adding a new contact.
*
* @author Ben Alex
* @version $Id$
*/
public class WebContactAddController extends SimpleFormController {
//~ Instance fields ========================================================
private ContactManager contactManager;
//~ Methods ================================================================
public void setContactManager(ContactManager contactManager) {
this.contactManager = contactManager;
}
public ContactManager getContactManager() {
return contactManager;
}
public ModelAndView onSubmit(Object command) throws ServletException {
String name = ((WebContact) command).getName();
String email = ((WebContact) command).getEmail();
String owner = ((SecureContext) ContextHolder.getContext()).getAuthentication()
.getPrincipal().toString();
Contact contact = new Contact(contactManager.getNextId(), name, email,
owner);
contactManager.save(contact);
Map myModel = new HashMap();
myModel.put("now", new Date());
return new ModelAndView(new RedirectView(getSuccessView()));
}
protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
WebContact wc = new WebContact();
return wc;
}
}
@@ -0,0 +1,38 @@
/*
* 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 sample.contact;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* Validates {@link WebContact}.
*
* @author Ben Alex
* @version $Id$
*/
public class WebContactValidator implements Validator {
//~ Methods ================================================================
public boolean supports(Class clazz) {
return clazz.equals(WebContact.class);
}
public void validate(Object obj, Errors errors) {
WebContact wc = (WebContact) obj;
if ((wc.getName() == null) || (wc.getName().length() < 3)) {
errors.rejectValue("name", "not-used", null, "Name is required.");
}
if ((wc.getEmail() == null) || (wc.getEmail().length() < 3)) {
errors.rejectValue("email", "not-used", null, "Email is required.");
}
}
}
+2
View File
@@ -0,0 +1,2 @@
lib
@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
- Application context definition for "contacts" DispatcherServlet.
- $Id$
-->
<beans>
<!-- ========================== WEB DEFINITIONS ======================= -->
<bean id="publicIndexController" class="sample.contact.PublicIndexController">
<property name="contactManager"><ref bean="contactManager"/></property>
</bean>
<bean id="secureIndexController" class="sample.contact.SecureIndexController">
<property name="contactManager"><ref bean="contactManager"/></property>
</bean>
<bean id="secureDeleteController" class="sample.contact.DeleteController">
<property name="contactManager"><ref bean="contactManager"/></property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">publicIndexController</prop>
<prop key="/secure/add.htm">secureAddForm</prop>
<prop key="/secure/index.htm">secureIndexController</prop>
<prop key="/secure/del.htm">secureDeleteController</prop>
</props>
</property>
</bean>
<bean id="addValidator" class="sample.contact.WebContactValidator"/>
<bean id="secureAddForm" class="sample.contact.WebContactAddController">
<property name="sessionForm"><value>true</value></property>
<property name="commandName"><value>webContact</value></property>
<property name="commandClass"><value>sample.contact.WebContact</value></property>
<property name="validator"><ref bean="addValidator"/></property>
<property name="formView"><value>add</value></property>
<property name="successView"><value>index.htm</value></property>
<property name="contactManager">
<ref bean="contactManager"/>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"><value>/WEB-INF/jsp/</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>
<!-- =================== 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 ~~~~~~~~~~~~~~~~~~ -->
<!-- We rely on the Because the web container to authenticate the user -->
<!-- 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>
<!-- 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="runAsAuthenticationProvider"/>
<ref bean="authByAdapterProvider"/>
</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 CONTACT_OWNED_BY_CURRENT_USER configuaration settings -->
<bean id="contactSecurityVoter" class="sample.contact.ContactSecurityVoter"/>
<!-- An affirmative access decision manager -->
<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="contactSecurityVoter"/>
</list>
</property>
</bean>
<!-- ===================== SECURITY DEFINITIONS ======================= -->
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="providerManager"/></property>
<property name="accessDecisionManager"><ref bean="affirmativeBased"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
sample.contact.ContactManager.delete=ROLE_SUPERVISOR,RUN_AS_SERVER
sample.contact.ContactManager.getAllByOwner=CONTACT_OWNED_BY_CURRENT_USER,RUN_AS_SERVER
sample.contact.ContactManager.save=CONTACT_OWNED_BY_CURRENT_USER,RUN_AS_SERVER
sample.contact.ContactManager.getById=ROLE_TELLER,RUN_AS_SERVER
</value>
</property>
</bean>
<!-- We expect all callers of the backend object to hold the role ROLE_RUN_AS_SERVER -->
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.SecurityInterceptor">
<property name="authenticationManager"><ref bean="providerManager"/></property>
<property name="accessDecisionManager"><ref bean="affirmativeBased"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="methodDefinitionSource">
<value>
sample.contact.ContactManager.delete=ROLE_RUN_AS_SERVER
sample.contact.ContactManager.getAllByOwner=ROLE_RUN_AS_SERVER
sample.contact.ContactManager.save=ROLE_RUN_AS_SERVER
sample.contact.ContactManager.getById=ROLE_RUN_AS_SERVER
</value>
</property>
</bean>
<!-- ======================= BUSINESS DEFINITIONS ===================== -->
<bean id="contactManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>sample.contact.ContactManager</value></property>
<property name="interceptorNames">
<list>
<value>publicContactManagerSecurity</value>
<value>publicContactManagerTarget</value>
</list>
</property>
</bean>
<bean id="publicContactManagerTarget" class="sample.contact.ContactManagerFacade">
<property name="backend"><ref bean="backendContactManager"/></property>
</bean>
<bean id="backendContactManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>sample.contact.ContactManager</value></property>
<property name="interceptorNames">
<list>
<value>backendContactManagerSecurity</value>
<value>backendContactManagerTarget</value>
</list>
</property>
</bean>
<bean id="backendContactManagerTarget" class="sample.contact.ContactManagerBackend"/>
</beans>
@@ -0,0 +1,6 @@
<!--
- $Id$
-->
<jboss-web>
<security-domain>java:/jaas/SpringPoweredRealm</security-domain>
</jboss-web>
+40
View File
@@ -0,0 +1,40 @@
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<html>
<head><title>Add New Contact</title></head>
<body>
<h1>Add Contact</h1>
<form method="post">
<table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0" cellpadding="5">
<tr>
<td alignment="right" width="20%">Name:</td>
<spring:bind path="webContact.name">
<td width="20%">
<input type="text" name="name" value="<c:out value="${status.value}"/>">
</td>
<td width="60%">
<font color="red"><c:out value="${status.errorMessage}"/></font>
</td>
</spring:bind>
</tr>
<tr>
<td alignment="right" width="20%">Email:</td>
<spring:bind path="webContact.email">
<td width="20%">
<input type="text" name="email" value="<c:out value="${status.value}"/>">
</td>
<td width="60%">
<font color="red"><c:out value="${status.errorMessage}"/></font>
</td>
</spring:bind>
</tr>
</table>
<br>
<spring:hasBindErrors name="webContact">
<b>Please fix all errors!</b>
</spring:hasBindErrors>
<br><br>
<input name="execute" type="submit" alignment="center" value="Execute">
</form>
<a href="<c:url value="hello.htm"/>">Home</a>
</body>
</html>
@@ -0,0 +1,13 @@
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<html>
<head><title>Deletion completed</title></head>
<body>
<h1>Deleted</h1>
<P>
<code>
<c:out value="${contact}"/>
</code>
<p><A HREF="index.htm">Manage</a>
</body>
</html>
@@ -0,0 +1,24 @@
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<html>
<head><title>Contacts Security Demo</title></head>
<body>
<h1>Contacts Security Demo</h1>
<p>This is a very simple application to demonstrate the Acegi Security System for Spring.
The application manages contacts, partitioned based on the user that owns them.
Users may only manage their own contacts, and only users with ROLE_SUPERVISOR
are allowed to delete their contacts. The application automatically extracts
the principal from the web container (which should be configured with a
suitable Acegi Security System for Spring adapter). It also demonstrates how to configure
server-side secure objects so they can only be accessed via a public facade.
<P>This application also demonstrates a public method, which is used to select
the random contact that is shown below:
<P>
<code>
<c:out value="${contact}"/>
</code>
<p>
<p><A HREF="secure/index.htm">Manage</a> <A HREF="secure/debug.jsp">Debug</a>
</body>
</html>
@@ -0,0 +1,4 @@
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
@@ -0,0 +1,29 @@
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<html>
<head><title>Your Contacts</title></head>
<body>
<h1><c:out value="${model.user}"/>'s Contacts</h1>
<P>
<table cellpadding=3 border=0>
<tr><td><b>id</b></td><td><b>Name</b></td><td><b>Email</b></td></tr>
<c:forEach var="contact" items="${model.contacts}">
<tr>
<td>
<c:out value="${contact.id}"/>
</td>
<td>
<c:out value="${contact.name}"/>
</td>
<td>
<c:out value="${contact.email}"/>
</td>
<c:if test="${model.supervisor == true}">
<td><A HREF="del.htm?id=<c:out value="${contact.id}"/>">Del</A></td>
</c:if>
</tr>
</c:forEach>
</table>
<p><A HREF="add.htm">Add</a> <A HREF="../logoff.jsp">Logoff</A>
</body>
</html>
@@ -0,0 +1,46 @@
<?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.
*
* This springsecurity.xml file will only be used by Resin. Normally the
* springsecurity.xml is container-wide, but in the case of Resin it is
* web application specific.
*
* $Id$
-->
<beans>
<!-- ================= CONTAINER ADAPTER CONFIGURATION ================ -->
<!-- Data access object which stores authentication information -->
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,ROLE_TELLER
scott=wombat,ROLE_TELLER
peter=opal,disabled,ROLE_TELLER
</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>
<!-- 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="daoAuthenticationProvider"/>
</list>
</property>
</bean>
</beans>
@@ -0,0 +1,12 @@
<!--
- $Id$
-->
<web-app>
<authenticator>
<type>net.sf.acegisecurity.adapters.resin.ResinSpringAuthenticator</type>
<init>
<app-context-location>WEB-INF/resin-acegisecurity.xml</app-context-location>
<key>my_password</key>
</init>
</authenticator>
</web-app>
+193
View File
@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Spring</short-name>
<uri>http://www.springframework.org/tags</uri>
<description>Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller</description>
<tag>
<name>htmlEscape</name>
<tag-class>org.springframework.web.servlet.tags.HtmlEscapeTag</tag-class>
<body-content>JSP</body-content>
<description>
Sets default HTML escape value for the current page.
</description>
<attribute>
<name>defaultHtmlEscape</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>message</name>
<tag-class>org.springframework.web.servlet.tags.MessageTag</tag-class>
<body-content>JSP</body-content>
<description>
Retrieves the message with the given code, or text if code isn't resolvable.
</description>
<attribute>
<name>code</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>text</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>htmlEscape</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>theme</name>
<tag-class>org.springframework.web.servlet.tags.ThemeTag</tag-class>
<body-content>JSP</body-content>
<description>
Retrieves the theme message with the given code, or text if code isn't resolvable.
</description>
<attribute>
<name>code</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>text</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>htmlEscape</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>hasBindErrors</name>
<tag-class>org.springframework.web.servlet.tags.BindErrorsTag</tag-class>
<body-content>JSP</body-content>
<description>
Provides Errors instance in case of bind errors.
</description>
<!-- Note: Was "Integer count" in earlier version -->
<variable>
<name-given>errors</name-given>
<variable-class>org.springframework.validation.Errors</variable-class>
</variable>
<!-- Note: Now one Errors instance per bind object -> name of object needed -->
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>htmlEscape</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>bind</name>
<tag-class>org.springframework.web.servlet.tags.BindTag</tag-class>
<body-content>JSP</body-content>
<description>
Provides BindStatus instance for certain bind path.
</description>
<!-- Note: Was "bind" in earlier version -->
<variable>
<name-given>status</name-given>
<variable-class>org.springframework.web.servlet.tags.BindStatus</variable-class>
</variable>
<!-- Note: Was "value" in earlier version -->
<attribute>
<name>path</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>htmlEscape</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>transform</name>
<tag-class>org.springframework.web.servlet.tags.TransformTag</tag-class>
<body-content>JSP</body-content>
<description>
Provides transformation of variables to Strings using appropriate
Custom Editor from BindTag (can only be used inside BindTag)
</description>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>htmlEscape</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
+100
View File
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
<!--
- Contacts web application
- $Id$
-->
<web-app>
<display-name>Contacts Sample Application</display-name>
<description>
Example of an application secured using Acegi Security System for Spring.
</description>
<filter>
<filter-name>Acegi Security System for Spring</filter-name>
<filter-class>net.sf.acegisecurity.adapters.AutoIntegrationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Acegi Security System for Spring</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
- Servlet that dispatches request to registered handlers (Controller implementations).
- Has its own application context, by default defined in "{servlet-name}-servlet.xml",
- i.e. "contacts-servlet.xml".
-
- A web app can contain any number of such servlets.
- Note that this web app does not have a shared root application context,
- therefore the DispatcherServlet contexts do not have a common parent.
-->
<servlet>
<servlet-name>contacts</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
- Maps the contacts dispatcher to /*.
-
-->
<servlet-mapping>
<servlet-name>contacts</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>
<security-constraint>
<display-name>Secured Area Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Secured Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/secure/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<!-- Anyone with one of the listed roles may access this area -->
<role-name>ROLE_TELLER</role-name>
<role-name>ROLE_SUPERVISOR</role-name>
</auth-constraint>
</security-constraint>
<!-- Default login configuration using BASIC authentication -->
<!--
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Spring Powered Realm</realm-name>
</login-config>
-->
<!-- Default login configuration using form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Spring Powered Realm</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp?login_error=1</form-error-page>
</form-login-config>
</login-config>
<!-- Security roles referenced by this web application -->
<security-role>
<role-name>ROLE_SUPERVISOR</role-name>
</security-role>
<security-role>
<role-name>ROLE_TELLER</role-name>
</security-role>
</web-app>
+4
View File
@@ -0,0 +1,4 @@
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<%-- Redirected because we can't set the welcome page to a virtual URL. --%>
<c:redirect url="/hello.htm"/>
+43
View File
@@ -0,0 +1,43 @@
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<P>If you've used the standard springsecurity.xml, try these users:
<P>
<P>username <b>marissa</b>, password <b>koala</b> (granted ROLE_SUPERVISOR)
<P>username <b>dianne</b>, password <b>emu</b> (not a supervisor)
<p>username <b>scott</b>, password <b>wombat</b> (not a supervisor)
<p>
<%-- this form-login-page form is also used as the
form-error-page to ask for a login again.
--%>
<c:if test="${not empty param.login_error}">
<font color="red">
Your login attempt was not successful, try again.
</font>
</c:if>
<form action="<c:url value='j_security_check'/>" method="POST">
<table>
<tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
<!--
- The j_uri is a Resin requirement (ignored by other containers)
-->
<input type='hidden' name='j_uri' value='/secure/index.htm'/>
</form>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
<%session.invalidate();
response.sendRedirect("index.jsp");
%>
+48
View File
@@ -0,0 +1,48 @@
<%@ page import="net.sf.acegisecurity.context.Context" %>
<%@ page import="net.sf.acegisecurity.context.ContextHolder" %>
<%@ page import="net.sf.acegisecurity.context.SecureContext" %>
<%@ page import="net.sf.acegisecurity.Authentication" %>
<%@ page import="net.sf.acegisecurity.GrantedAuthority" %>
<%@ page import="net.sf.acegisecurity.adapters.AuthByAdapter" %>
<% Context context = ContextHolder.getContext();
if (context != null) { %>
Context on ContextHolder is of type: <%= context.getClass().getName() %><BR><BR>
<% if (context instanceof SecureContext) { %>
The Context implements SecureContext.<BR><BR>
<% SecureContext sc = (SecureContext) context;
Authentication auth = sc.getAuthentication();
if (auth != null) { %>
Authentication object is of type: <%= auth.getClass().getName() %><BR><BR>
Authentication object as a String: <%= auth.toString() %><BR><BR>
Authentication object holds the following granted authorities:<BR><BR>
<% GrantedAuthority[] granted = auth.getAuthorities();
for (int i = 0; i < granted.length; i++) { %>
<%= granted[i].toString() %> (getAuthority(): <%= granted[i].getAuthority() %>)<BR>
<% }
if (auth instanceof AuthByAdapter) { %>
<BR><B>SUCCESS! Your container adapter appears to be properly configured!</B><BR><BR>
<% } else { %>
<BR><I>WARNING: Authentication object does not implement AuthByAdapter</I><BR>
This may point to an error with your adapter configuration, although can be ignored if intentional.<BR><BR>
<% }
} else { %>
Authentication object is null.<BR>
This is an error and your container adapter will not operate properly until corrected.<BR><BR>
<% }
} else { %>
<B>ContextHolder does not contain a SecureContext.</B><BR>
This is an error and your container adapter will not operate properly until corrected.<BR><BR>
<% }
} else { %>
<B>ContextHolder on ContextHolder is null.</B><BR>
This indicates improper setup of the container adapter. Refer to the reference documentation.<BR>
Also ensure the correct subclass of AbstractMvcIntegrationInterceptor is being used for your container.<BR>
<%}
%>