1
0
mirror of synced 2026-07-14 23:25:10 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Sanchez 1bc1196baa [maven-scm] copy for tag release_1_0_1 2006-06-22 17:28:18 +00:00
643 changed files with 12134 additions and 30694 deletions
+28 -28
View File
@@ -1,30 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="core/src/main/java"/>
<classpathentry kind="src" path="core/src/main/resources"/>
<classpathentry kind="src" path="core/src/test/java"/>
<classpathentry kind="src" path="core/src/test/resources"/>
<classpathentry kind="src" path="samples/dms/src/test/java"/>
<classpathentry kind="src" path="samples/dms/src/main/resources"/>
<classpathentry kind="src" path="samples/dms/src/main/java"/>
<classpathentry kind="src" path="samples/dms/src/test/resources"/>
<classpathentry kind="src" path="samples/contacts/src/main/java"/>
<classpathentry kind="src" path="samples/contacts/src/main/resources"/>
<classpathentry kind="src" path="samples/contacts/src/test/java"/>
<classpathentry kind="src" path="samples/contacts/src/test/resources"/>
<classpathentry kind="src" path="samples/acegifier/src/main/java"/>
<classpathentry kind="src" path="samples/acegifier/src/main/resources"/>
<classpathentry kind="src" path="samples/acegifier/src/test/java"/>
<classpathentry kind="src" path="samples/acegifier/src/test/resources"/>
<classpathentry kind="src" path="samples/attributes/src/main/java"/>
<classpathentry kind="src" path="samples/acegifier/src/test/resources"/>
<classpathentry kind="src" path="samples/acegifier/src/main/resources"/>
<classpathentry kind="src" path="samples/acegifier/src/main/java"/>
<classpathentry kind="src" path="samples/acegifier/src/test/java"/>
<classpathentry kind="src" path="domain/src/main/java"/>
<classpathentry kind="src" path="domain/src/main/resource"/>
<classpathentry kind="src" path="domain/src/test/java"/>
<classpathentry kind="src" path="domain/src/test/resources"/>
<classpathentry kind="src" path="adapters/catalina/src/main/resources"/>
<classpathentry kind="src" path="samples/attributes/src/main/resources"/>
<classpathentry kind="src" path="samples/attributes/src/test/java"/>
<classpathentry kind="src" path="adapters/cas/src/test/resources"/>
<classpathentry kind="src" path="adapters/cas/src/main/resources"/>
<classpathentry kind="src" path="core/src/main/resources"/>
<classpathentry kind="src" path="core/src/test/resources"/>
<classpathentry kind="src" path="samples/contacts/src/main/java"/>
<classpathentry kind="src" path="sandbox/src/main/java"/>
<classpathentry kind="src" path="sandbox/src/test/java"/>
<classpathentry kind="src" path="adapters/cas/src/main/java"/>
<classpathentry kind="src" path="adapters/cas/src/test/java"/>
<classpathentry kind="src" path="adapters/catalina/src/main/java"/>
<classpathentry kind="src" path="adapters/catalina/src/main/resources"/>
<classpathentry kind="src" path="adapters/catalina/src/test/java"/>
<classpathentry kind="src" path="adapters/jboss/src/main/java"/>
<classpathentry kind="src" path="adapters/jboss/src/test/java"/>
@@ -32,10 +29,12 @@
<classpathentry kind="src" path="adapters/jetty/src/test/java"/>
<classpathentry kind="src" path="adapters/resin/src/main/java"/>
<classpathentry kind="src" path="adapters/resin/src/test/java"/>
<classpathentry kind="src" path="core/src/main/java"/>
<classpathentry kind="src" path="core/src/test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="MAVEN_REPO/com.caucho/jars/resin-3.0.9.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.springframework/jars/spring-1.2.9.jar" sourcepath="/MAVEN_REPO/org.springframework/src/spring-1.2.9-sources.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.springframework/jars/spring-mock-1.2.9.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.springframework/jars/spring-2.0-m2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.springframework/jars/spring-mock-2.0-m2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/aopalliance/jars/aopalliance-1.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/aspectj/jars/aspectjrt-1.2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/cas/jars/casclient-2.0.11.jar"/>
@@ -43,7 +42,7 @@
<classpathentry kind="var" path="MAVEN_REPO/commons-codec/jars/commons-codec-1.3.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/commons-collections/jars/commons-collections-3.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/commons-logging/jars/commons-logging-1.0.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/hsqldb/jars/hsqldb-1.8.0.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/hsqldb/jars/hsqldb-1.7.3.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/oro/jars/oro-2.0.8.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/javax.servlet/jars/servlet-api-2.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/tomcat/jars/catalina-4.1.9.jar"/>
@@ -51,36 +50,37 @@
<classpathentry kind="var" path="MAVEN_REPO/jboss/jars/jboss-common-3.2.3.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/jboss/jars/jbosssx-3.2.3.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/junit/jars/junit-3.8.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/net.sf.ehcache/jars/ehcache-1.2.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/ehcache/jars/ehcache-1.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/javax.servlet/jars/jsp-api-2.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/hibernate/jars/hibernate-3.0.3.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/commons-beanutils/jars/commons-beanutils-1.6.1.jar" sourcepath="DIST_BASE/commons-beanutils-1.6.1-src/src/java"/>
<classpathentry kind="src" path="samples/contacts-tiger/src/main/java"/>
<classpathentry kind="var" path="MAVEN_REPO/commons-lang/jars/commons-lang-2.0.jar"/>
<classpathentry sourcepath="DIST_BASE/commons-beanutils-1.6.1-src/src/java" kind="var" path="MAVEN_REPO/commons-beanutils/jars/commons-beanutils-1.6.1.jar"/>
<classpathentry kind="src" path="core-tiger/src/main/java"/>
<classpathentry kind="src" path="core-tiger/src/main/resources"/>
<classpathentry kind="src" path="core-tiger/src/test/java"/>
<classpathentry kind="src" path="core-tiger/src/main/resources"/>
<classpathentry kind="src" path="core-tiger/src/test/resources"/>
<classpathentry kind="src" path="samples/annotations/src/main/java"/>
<classpathentry kind="src" path="samples/annotations/src/main/resources"/>
<classpathentry kind="src" path="samples/annotations/src/test/java"/>
<classpathentry kind="src" path="samples/contacts-tiger/src/main/java"/>
<classpathentry kind="var" path="MAVEN_REPO/org.samba.jcifs/jars/jcifs-1.2.6.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/dom4j/jars/dom4j-1.6.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/xerces/jars/xercesImpl-2.6.2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/jmock/jars/jmock-1.0.1.jar" sourcepath="MAVEN_REPO/jmock/distributions/jmock-1.0.1-src.jar"/>
<classpathentry sourcepath="MAVEN_REPO/jmock/distributions/jmock-1.0.1-src.jar" kind="var" path="MAVEN_REPO/jmock/jars/jmock-1.0.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/jdbm/jars/jdbm-1.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/regexp/jars/regexp-1.2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.slf4j/jars/slf4j-log4j12-1.0-rc5.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.server/jars/apacheds-core-1.0.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.server/jars/apacheds-core-shared-1.0.0.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.server/jars/apacheds-core-1.0-RC1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.server/jars/apacheds-core-shared-1.0-RC1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.shared/jars/shared-asn1-0.9.5.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.apache.directory.shared/jars/shared-ldap-0.9.5.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/antlr/jars/antlr-2.7.2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/ldapsdk/jars/ldapsdk-4.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/org.springframework/jars/spring-hibernate3-2.0-m2.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/cas/jars/cas-server-3.0.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/net.sourceforge.retroweaver/jars/retroweaver-1.0fcs.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/taglibs/jars/standard-1.0.6.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/commons-attributes/jars/commons-attributes-api-2.1.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/log4j/jars/log4j-1.2.9.jar"/>
<classpathentry kind="var" path="M2_REPO/postgresql/postgresql/8.1-407.jdbc3/postgresql-8.1-407.jdbc3.jar"/>
<classpathentry kind="output" path="target/eclipseclasses"/>
</classpath>
-205
View File
@@ -1,205 +0,0 @@
<?xml version="1.0"?>
<!--
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* 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.
*/
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<!--
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
Finally, it is worth reading the documentation.
-->
<module name="Checker">
<!-- Checks that a package.html file exists for each package. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
<!-- module name="PackageHtml"/ -->
<!-- Checks whether files end with a new line. -->
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- Checks that property files contain the same keys. -->
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
<module name="Translation"/>
<module name="TreeWalker">
<property name="cacheFile" value="${checkstyle.cache.file}"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<!--
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocVariable"/>
<module name="JavadocStyle"/>
-->
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName">
<!-- logger variables break normal constant syntax. We need to allow lower case too -->
<property name="format" value="^[a-zA-Z][a-zA-Z0-9]*(_[A-Z0-9]+)*$"/>
</module>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<!-- <module name="Header"> -->
<!-- The follow property value demonstrates the ability -->
<!-- to have access to ANT properties. In this case it uses -->
<!-- the ${basedir} property to allow Checkstyle to be run -->
<!-- from any directory within a project. See property -->
<!-- expansion, -->
<!-- http://checkstyle.sf.net/config.html#properties -->
<!-- <property -->
<!-- name="headerFile" -->
<!-- value="${basedir}/java.header"/> -->
<!-- </module> -->
<!-- Following interprets the header file as regular expressions. -->
<!-- <module name="RegexpHeader"/> -->
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_imports.html -->
<module name="AvoidStarImport">
<property name="excludes" value="javax.servlet,java.util"/>
</module>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<!--module name="UnusedImports"/ -->
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="FileLength"/>
<module name="LineLength">
<property name="max" value="125"/>
</module>
<module name="MethodLength"/>
<module name="ParameterNumber"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="TabCharacter"/>
<module name="WhitespaceAfter"/>
<!--
<module name="WhitespaceAround">
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyConstructors" value="true"/>
</module>
-->
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<!-- module name="EmptyBlock"/ -->
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<!-- module name="AvoidInlineConditionals"/ -->
<module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE -->
<module name="EmptyStatement"/>
<!-- module name="EqualsHashCode"/ -->
<!--
<module name="HiddenField">
<property name="ignoreConstructorParameter" value="true"/>
<property name="ignoreSetter" value="true"/>
</module>
-->
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<!-- module name="MagicNumber"/ -->
<module name="MissingSwitchDefault"/>
<!--
<module name="RedundantThrows">
<property name="allowUnchecked" value="true"/>
</module>
-->
<!--
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
-->
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!-- module name="DesignForExtension"/ -->
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier">
<!-- logger variables are often protected -->
<property name="protectedAllowed" value="true"/>
</module>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<!-- module name="FinalParameters"/ -->
<!--
<module name="GenericIllegalRegexp">
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
-->
<!-- module name="TrailingComment"/ -->
<!-- module name="TodoComment"/ -->
<module name="UpperEll"/>
</module>
</module>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-adapters</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-cas</artifactId>
<name>Acegi Security System for Spring - CAS adapter</name>
+3 -3
View File
@@ -6,9 +6,9 @@
<name>Acegi Security System for Spring - CAS adapter</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-cas</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/cas/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/cas/</url>
</repository>
<dependencies>
<dependency>
@@ -67,7 +67,7 @@ public final class CasAuthenticationHandler extends AbstractUsernamePasswordAuth
this.authenticationManager.authenticate(authenticationRequest);
} catch (final org.acegisecurity.AuthenticationException e) {
if (log.isDebugEnabled()) {
log.debug("Authentication request for " + credentials.getUsername() + " failed: " + e.toString(), e);
log.debug("Authentication request for " + credentials.getUsername() + "failed: " + e.toString());
}
return false;
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-adapters</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-catalina</artifactId>
<name>Acegi Security System for Spring - Catalina adapter</name>
+3 -3
View File
@@ -6,9 +6,9 @@
<name>Acegi Security System for Spring - Catalina adapter</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-catalina</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/catalina/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/catalina/</url>
</repository>
<dependencies>
<dependency>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-adapters</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-jboss</artifactId>
<name>Acegi Security System for Spring - JBoss adapter</name>
+3 -3
View File
@@ -6,9 +6,9 @@
<name>Acegi Security System for Spring - JBoss adapter</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-jboss</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/jboss/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/jboss/</url>
</repository>
<dependencies>
<dependency>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-adapters</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-jetty</artifactId>
<name>Acegi Security System for Spring - Jetty adapter</name>
+3 -3
View File
@@ -6,9 +6,9 @@
<name>Acegi Security System for Spring - Jetty adapter</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-jetty</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/jetty/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/jetty/</url>
</repository>
<dependencies>
<dependency>
@@ -31,7 +31,6 @@ import org.mortbay.http.UserPrincipal;
public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken implements UserPrincipal {
//~ Instance fields ================================================================================================
private static final long serialVersionUID = 1L;
private String password;
private String username;
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-parent</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-adapters</artifactId>
<name>Acegi Security System for Spring - Adapters</name>
+4 -4
View File
@@ -5,15 +5,15 @@
<artifactId>acegi-security-adapters</artifactId>
<name>Acegi Security System for Spring - Adapters</name>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/</url>
</repository>
<dependencies>
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security</artifactId>
<version>1.0.4</version>
<version>1.0.0</version>
<type>jar</type>
<url>http://acegisecurity.org</url>
<properties>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-adapters</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-resin</artifactId>
<name>Acegi Security System for Spring - Resin adapter</name>
+3 -3
View File
@@ -6,9 +6,9 @@
<name>Acegi Security System for Spring - Resin adapter</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-resin</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/resin/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/adapters/resin/</url>
</repository>
<dependencies>
<dependency>
+3 -11
View File
@@ -3,17 +3,10 @@
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-parent</artifactId>
<version>1.0.4-SNAPSHOT</version>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security-tiger</artifactId>
<name>Acegi Security System for Spring - Java 5 (Tiger)</name>
<scm>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core-tiger</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core-tiger</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core-tiger/</url>
</scm>
<dependencies>
<dependency>
<groupId>org.acegisecurity</groupId>
@@ -23,10 +16,9 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>2.0.4</version>
<version>1.2.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@@ -50,4 +42,4 @@
</plugin>
</plugins>
</reporting>
</project>
</project>
+4 -4
View File
@@ -6,15 +6,15 @@
<name>Acegi Security System for Spring - Java 5 (Tiger)</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security-tiger</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core-tiger/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core-tiger/</url>
</repository>
<dependencies>
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security</artifactId>
<version>1.0.4</version>
<version>1.0.0</version>
<type>jar</type>
</dependency>
</dependencies>
@@ -12,14 +12,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.acegisecurity.annotation;
import org.acegisecurity.SecurityConfig;
import org.springframework.metadata.Attributes;
import org.springframework.util.ClassUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -44,8 +43,6 @@ import java.util.Set;
* &lt;/bean></pre></p>
* <p>These security annotations are similiar to the Commons Attributes approach, however they are using Java 5
* language-level metadata support.</p>
* <p>This class should be used with Spring 2.0 or above, as it relies upon utility classes in Spring 2.0 for
* correct introspection of annotations on bridge methods.</p>
*
* @author Mark St.Godard
* @version $Id$
@@ -99,19 +96,7 @@ public class SecurityAnnotationAttributes implements Attributes {
public Collection getAttributes(Method method) {
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
Annotation[] annotations = null;
// Use AnnotationUtils if in classpath (ie Spring 1.2.9+ deployment)
try {
Class clazz = ClassUtils.forName("org.springframework.core.annotation.AnnotationUtils");
Method m = clazz.getMethod("getAnnotations", new Class[] {Method.class});
annotations = (Annotation[]) m.invoke(null, new Object[] {method});
} catch (Exception ex) {
// Fallback to manual retrieval if no AnnotationUtils available
annotations = method.getAnnotations();
}
for (Annotation annotation : annotations) {
for (Annotation annotation : method.getAnnotations()) {
// check for Secured annotations
if (annotation instanceof Secured) {
Secured attr = (Secured) annotation;
@@ -1,28 +0,0 @@
package org.acegisecurity.annotation;
/**
*
* @author Joe Scalise
*/
public class BusinessServiceImpl<E extends Entity> implements BusinessService {
@Secured({"ROLE_USER"})
public void someUserMethod1() {
}
@Secured({"ROLE_USER"})
public void someUserMethod2() {
}
@Secured({"ROLE_USER", "ROLE_ADMIN"})
public void someUserAndAdminMethod() {
}
@Secured({"ROLE_ADMIN"})
public void someAdminMethod() {
}
public E someUserMethod3(final E entity) {
return entity;
}
}
@@ -1,28 +0,0 @@
package org.acegisecurity.annotation;
/**
*
* @author Joe Scalise
*/
public class Department extends Entity {
//~ Instance fields ========================================================
private boolean active = true;
//~ Constructors ===========================================================
public Department(String name) {
super(name);
}
//~ Methods ================================================================
public boolean isActive() {
return this.active;
}
void deactive() {
this.active = true;
}
}
@@ -1,11 +0,0 @@
package org.acegisecurity.annotation;
/**
*
* @author Joe Scalise
*/
public interface DepartmentService extends BusinessService {
@Secured({"ROLE_USER"})
Department someUserMethod3(Department dept);
}
@@ -1,12 +0,0 @@
package org.acegisecurity.annotation;
/**
* @author Joe Scalise
*/
public class DepartmentServiceImpl extends BusinessServiceImpl <Department> implements DepartmentService {
@Secured({"ROLE_ADMIN"})
public Department someUserMethod3(final Department dept) {
return super.someUserMethod3(dept);
}
}
@@ -1,11 +0,0 @@
package org.acegisecurity.annotation;
/**
* Class to act as a superclass for annotations testing.
*
* @author Ben Alex
*
*/
public class Entity {
public Entity(String someParameter) {}
}
@@ -12,15 +12,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.acegisecurity.annotation;
import junit.framework.TestCase;
import org.acegisecurity.SecurityConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.metadata.Attributes;
import java.lang.reflect.Field;
@@ -33,14 +31,12 @@ import java.util.Collection;
* Tests for {@link org.acegisecurity.annotation.SecurityAnnotationAttributes}
*
* @author Mark St.Godard
* @author Joe Scalise
* @version $Id$
* @version $Revision$
*/
public class SecurityAnnotationAttributesTests extends TestCase {
//~ Instance fields ================================================================================================
private Attributes attributes;
private Log logger = LogFactory.getLog(SecurityAnnotationAttributesTests.class);
//~ Methods ========================================================================================================
@@ -49,67 +45,6 @@ public class SecurityAnnotationAttributesTests extends TestCase {
this.attributes = new SecurityAnnotationAttributes();
}
public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() {
Method method = null;
try {
method = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Department.class});
} catch (NoSuchMethodException unexpected) {
fail("Should be a superMethod called 'someUserMethod3' on class!");
}
Collection attrs = this.attributes.getAttributes(method);
if (logger.isDebugEnabled()) {
logger.debug("attrs: ");
logger.debug(attrs);
}
assertNotNull(attrs);
// expect 1 attribute
assertTrue("Did not find 1 attribute", attrs.size() == 1);
// should have 1 SecurityConfig
for (Object obj : attrs) {
assertTrue(obj instanceof SecurityConfig);
SecurityConfig sc = (SecurityConfig) obj;
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
}
Method superMethod = null;
try {
superMethod = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Entity.class});
} catch (NoSuchMethodException unexpected) {
fail("Should be a superMethod called 'someUserMethod3' on class!");
}
System.out.println(superMethod);
Collection superAttrs = this.attributes.getAttributes(superMethod);
if (logger.isDebugEnabled()) {
logger.debug("superAttrs: ");
logger.debug(superAttrs);
}
assertNotNull(superAttrs);
// TODO: Enable this part of the test once we can build against Spring 2.0+ and above only (SEC-274)
/*
// expect 1 attribute
assertTrue("Did not find 1 attribute", superAttrs.size() == 1);
// should have 1 SecurityConfig
for (Object obj : superAttrs) {
assertTrue(obj instanceof SecurityConfig);
SecurityConfig sc = (SecurityConfig) obj;
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
}
*/
}
public void testGetAttributesClass() {
Collection attrs = this.attributes.getAttributes(BusinessService.class);
+127 -165
View File
@@ -1,167 +1,129 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-parent</artifactId>
<version>1.0.4-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<artifactId>acegi-security</artifactId>
<name>Acegi Security System for Spring</name>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-parent</artifactId>
<version>1.0.1</version>
</parent>
<artifactId>acegi-security</artifactId>
<name>Acegi Security System for Spring</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-remoting</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
<version>1.2.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cas</groupId>
<artifactId>casclient</artifactId>
<version>2.0.11</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.0.6</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.7.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core</artifactId>
<version>1.0-RC1</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>nlog4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.0-rc5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<scm>
<connection>
scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core
</connection>
<developerConnection>
scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core
</developerConnection>
<url>
http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/
</url>
</scm>
</dependencies>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-remoting</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.2.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cas</groupId>
<artifactId>casclient</artifactId>
<version>2.0.11</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.0.6</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/../</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>notice.txt</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>
${basedir}/src/main/resources/org/acegisecurity/taglibs
</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<targetPath>/</targetPath>
<includes>
<include>**/*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
</project>
+3 -3
View File
@@ -7,9 +7,9 @@
<name>Acegi Security System for Spring</name>
<siteDirectory>/home/groups/a/ac/acegisecurity/htdocs/multiproject/acegi-security</siteDirectory>
<repository>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/</url>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity</developerConnection>
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/</url>
</repository>
<build>
<resources>
@@ -36,7 +36,7 @@ public interface AccessDecisionManager {
* @throws InsufficientAuthenticationException if access is denied as the authentication does not provide a
* sufficient level of trust
*/
void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
throws AccessDeniedException, InsufficientAuthenticationException;
/**
@@ -51,7 +51,7 @@ public interface AccessDecisionManager {
*
* @return true if this <code>AccessDecisionManager</code> can support the passed configuration attribute
*/
boolean supports(ConfigAttribute attribute);
public boolean supports(ConfigAttribute attribute);
/**
* Indicates whether the <code>AccessDecisionManager</code> implementation is able to provide access
@@ -61,5 +61,5 @@ public interface AccessDecisionManager {
*
* @return <code>true</code> if the implementation can process the indicated class
*/
boolean supports(Class clazz);
public boolean supports(Class clazz);
}
@@ -19,7 +19,7 @@ package org.acegisecurity;
* Reviews the <code>Object</code> returned from a secure object invocation,
* being able to modify the <code>Object</code> or throw an {@link
* AccessDeniedException}.
*
*
* <p>
* Typically used to ensure the principal is permitted to access the domain
* object instance returned by a service layer bean. Can also be used to
@@ -28,7 +28,7 @@ package org.acegisecurity;
* in conjunction with an {@link org.acegisecurity.acl.AclManager} to
* obtain the access control list applicable for the domain object instance.
* </p>
*
*
* <p>
* Special consideration should be given to using an
* <code>AfterInvocationManager</code> on bean methods that modify a database.
@@ -60,7 +60,7 @@ public interface AfterInvocationManager {
*
* @throws AccessDeniedException if access is denied
*/
Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object returnedObject) throws AccessDeniedException;
/**
@@ -75,7 +75,7 @@ public interface AfterInvocationManager {
*
* @return true if this <code>AfterInvocationManager</code> can support the passed configuration attribute
*/
boolean supports(ConfigAttribute attribute);
public boolean supports(ConfigAttribute attribute);
/**
* Indicates whether the <code>AfterInvocationManager</code> implementation is able to provide access
@@ -85,5 +85,5 @@ public interface AfterInvocationManager {
*
* @return <code>true</code> if the implementation can process the indicated class
*/
boolean supports(Class clazz);
public boolean supports(Class clazz);
}
@@ -22,12 +22,12 @@ import java.security.Principal;
/**
* Represents an authentication request.
*
*
* <p>
* An <code>Authentication</code> object is not considered authenticated until
* it is processed by an {@link AuthenticationManager}.
* </p>
*
*
* <p>
* Stored in a request {@link org.acegisecurity.context.SecurityContext}.
* </p>
@@ -46,7 +46,7 @@ public interface Authentication extends Principal, Serializable {
*
* @return the authorities granted to the principal, or <code>null</code> if authentication has not been completed
*/
GrantedAuthority[] getAuthorities();
public GrantedAuthority[] getAuthorities();
/**
* The credentials that prove the principal is correct. This is usually a password, but could be anything
@@ -54,7 +54,7 @@ public interface Authentication extends Principal, Serializable {
*
* @return the credentials that prove the identity of the <code>Principal</code>
*/
Object getCredentials();
public Object getCredentials();
/**
* Stores additional details about the authentication request. These might be an IP address, certificate
@@ -62,7 +62,7 @@ public interface Authentication extends Principal, Serializable {
*
* @return additional details about the authentication request, or <code>null</code> if not used
*/
Object getDetails();
public Object getDetails();
/**
* The identity of the principal being authenticated. This is usually a username. Callers are expected to
@@ -70,7 +70,7 @@ public interface Authentication extends Principal, Serializable {
*
* @return the <code>Principal</code> being authenticated
*/
Object getPrincipal();
public Object getPrincipal();
/**
* Used to indicate to <code>AbstractSecurityInterceptor</code> whether it should present the
@@ -85,7 +85,7 @@ public interface Authentication extends Principal, Serializable {
* @return true if the token has been authenticated and the <code>AbstractSecurityInterceptor</code> does not need
* to represent the token for re-authentication to the <code>AuthenticationManager</code>
*/
boolean isAuthenticated();
public boolean isAuthenticated();
/**
* See {@link #isAuthenticated()} for a full description.<p>Implementations should <b>always</b> allow this
@@ -101,6 +101,6 @@ public interface Authentication extends Principal, Serializable {
* <code>true</code> as the argument) is rejected due to the implementation being immutable or
* implementing its own alternative approach to {@link #isAuthenticated()}
*/
void setAuthenticated(boolean isAuthenticated)
public void setAuthenticated(boolean isAuthenticated)
throws IllegalArgumentException;
}
@@ -44,6 +44,6 @@ public interface AuthenticationManager {
*
* @throws AuthenticationException if authentication fails
*/
Authentication authenticate(Authentication authentication)
public Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
@@ -37,7 +37,7 @@ public interface AuthenticationTrustResolver {
* @return <code>true</code> the passed authentication token represented an anonymous principal, <code>false</code>
* otherwise
*/
boolean isAnonymous(Authentication authentication);
public boolean isAnonymous(Authentication authentication);
/**
* Indicates whether the passed <code>Authentication</code> token represents user that has been remembered
@@ -52,5 +52,5 @@ public interface AuthenticationTrustResolver {
* @return <code>true</code> the passed authentication token represented a principal authenticated using a
* remember-me token, <code>false</code> otherwise
*/
boolean isRememberMe(Authentication authentication);
public boolean isRememberMe(Authentication authentication);
}
@@ -29,7 +29,7 @@ public class BadCredentialsException extends AuthenticationException {
//~ Constructors ===================================================================================================
/**
/**
* Constructs a <code>BadCredentialsException</code> with the specified
* message.
*
@@ -44,7 +44,7 @@ public class BadCredentialsException extends AuthenticationException {
this.extraInformation = extraInformation;
}
/**
/**
* Constructs a <code>BadCredentialsException</code> with the specified
* message and root cause.
*
@@ -20,7 +20,7 @@ import java.io.Serializable;
/**
* Stores a security system related configuration attribute.
*
*
* <p>
* When an {@link org.acegisecurity.intercept.AbstractSecurityInterceptor}
* is setup, a list of configuration attributes is defined for secure object
@@ -28,7 +28,7 @@ import java.io.Serializable;
* RunAsManager}, {@link AccessDecisionManager} or
* <code>AccessDecisionManager</code> delegate.
* </p>
*
*
* <P>
* Stored at runtime with other <code>ConfigAttribute</code>s for the same
* secure object target within a {@link ConfigAttributeDefinition}.
@@ -52,5 +52,5 @@ public interface ConfigAttribute extends Serializable {
* @return a representation of the configuration attribute (or <code>null</code> if the configuration attribute
* cannot be expressed as a <code>String</code> with sufficient precision).
*/
String getAttribute();
public String getAttribute();
}
@@ -15,11 +15,9 @@
package org.acegisecurity;
import java.io.Serializable;
/**
* Represents an authority granted to an {@link Authentication} object.
*
*
* <p>
* A <code>GrantedAuthority</code> must either represent itself as a
* <code>String</code> or be specifically supported by an {@link
@@ -29,7 +27,7 @@ import java.io.Serializable;
* @author Ben Alex
* @version $Id$
*/
public interface GrantedAuthority extends Serializable {
public interface GrantedAuthority {
//~ Methods ========================================================================================================
/**
@@ -44,5 +42,5 @@ public interface GrantedAuthority extends Serializable {
* @return a representation of the granted authority (or <code>null</code> if the granted authority cannot be
* expressed as a <code>String</code> with sufficient precision).
*/
String getAuthority();
public String getAuthority();
}
@@ -28,7 +28,6 @@ import java.io.Serializable;
public class GrantedAuthorityImpl implements GrantedAuthority, Serializable {
//~ Instance fields ================================================================================================
private static final long serialVersionUID = 1L;
private String role;
//~ Constructors ===================================================================================================
@@ -18,7 +18,7 @@ package org.acegisecurity;
/**
* Creates a new temporary {@link Authentication} object for the current secure
* object invocation only.
*
*
* <p>
* This interface permits implementations to replace the
* <code>Authentication</code> object that applies to the current secure
@@ -29,7 +29,7 @@ package org.acegisecurity;
* for the duration of the secure object callback only, returning it to
* the original <code>Authentication</code> object when the callback ends.
* </p>
*
*
* <p>
* This is provided so that systems with two layers of objects can be
* established. One layer is public facing and has normal secure methods with
@@ -43,7 +43,7 @@ package org.acegisecurity;
* <code>RunAsManager</code> interface provides a mechanism to elevate
* security in this manner.
* </p>
*
*
* <p>
* It is expected implementations will provide a corresponding concrete
* <code>Authentication</code> and <code>AuthenticationProvider</code> so that
@@ -71,7 +71,7 @@ public interface RunAsManager {
* @return a replacement object to be used for duration of the secure object invocation, or <code>null</code> if
* the <code>Authentication</code> should be left as is
*/
Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
/**
* Indicates whether this <code>RunAsManager</code> is able to process the passed
@@ -84,7 +84,7 @@ public interface RunAsManager {
*
* @return <code>true</code> if this <code>RunAsManager</code> can support the passed configuration attribute
*/
boolean supports(ConfigAttribute attribute);
public boolean supports(ConfigAttribute attribute);
/**
* Indicates whether the <code>RunAsManager</code> implementation is able to provide run-as replacement for
@@ -94,5 +94,5 @@ public interface RunAsManager {
*
* @return true if the implementation can process the indicated class
*/
boolean supports(Class clazz);
public boolean supports(Class clazz);
}
@@ -35,6 +35,10 @@ public class SecurityConfig implements ConfigAttribute {
//~ Methods ========================================================================================================
public boolean equals(Object obj) {
if (obj instanceof String) {
return obj.equals(this.attrib);
}
if (obj instanceof ConfigAttribute) {
ConfigAttribute attr = (ConfigAttribute) obj;
@@ -21,7 +21,7 @@ import java.io.Serializable;
/**
* Marker interface representing an access control list entry associated with a
* specific domain object instance.
*
*
* @author Ben Alex
* @version $Id$
*/
@@ -35,7 +35,7 @@ public interface AclManager {
*
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
*/
AclEntry[] getAcls(Object domainInstance);
public AclEntry[] getAcls(Object domainInstance);
/**
* Obtains the ACLs that apply to the specified domain instance, but only including those ACLs which have
@@ -47,5 +47,5 @@ public interface AclManager {
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
* <code>null</code>) if no such ACLs are found
*/
AclEntry[] getAcls(Object domainInstance, Authentication authentication);
public AclEntry[] getAcls(Object domainInstance, Authentication authentication);
}
@@ -21,7 +21,7 @@ import org.acegisecurity.Authentication;
/**
* Indicates a class can process a given domain object instance and
* authoritatively return the ACLs that apply.
*
*
* <P>
* Implementations are typically called from the {@link AclProviderManager}.
* </p>
@@ -40,7 +40,7 @@ public interface AclProvider {
*
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
*/
AclEntry[] getAcls(Object domainInstance);
public AclEntry[] getAcls(Object domainInstance);
/**
* Obtains the ACLs that apply to the specified domain instance and presented <code>Authentication</code>
@@ -52,7 +52,7 @@ public interface AclProvider {
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
* <code>null</code>) if no such ACLs are found
*/
AclEntry[] getAcls(Object domainInstance, Authentication authentication);
public AclEntry[] getAcls(Object domainInstance, Authentication authentication);
/**
* Indicates whether this <code>AclProvider</code> can authoritatively return ACL information for the
@@ -63,5 +63,5 @@ public interface AclProvider {
* @return <code>true</code> if this provider is authoritative for the specified domain object instance,
* <code>false</code> otherwise
*/
boolean supports(Object domainInstance);
public boolean supports(Object domainInstance);
}
@@ -20,7 +20,7 @@ import java.io.Serializable;
/**
* Interface representing the identity of an individual domain object instance.
*
*
* <P>
* It should be noted that <code>AclObjectIdentity</code> instances are created
* in various locations throughout the package. As
@@ -31,7 +31,7 @@ import java.io.Serializable;
* <code>identity1.equals(identity2)</code>, rather than reference-equality of
* <code>identity1==identity2</code>.
* </p>
*
*
* <P>
* In practical terms this means you must implement the standard
* <code>java.lang.Object</code> methods shown below. Depending on your
@@ -53,12 +53,12 @@ public interface AclObjectIdentity extends Serializable {
*
* @return <code>true</code> if the objects are equal, <code>false</code> otherwise
*/
boolean equals(Object obj);
public boolean equals(Object obj);
/**
* Refer to the <code>java.lang.Object</code> documentation for the interface contract.
*
* @return a hash code representation of this object
*/
int hashCode();
public int hashCode();
}
@@ -18,7 +18,7 @@ package org.acegisecurity.acl.basic;
/**
* Indicates a domain object instance is able to provide {@link
* AclObjectIdentity} information.
*
*
* <P>
* Domain objects must implement this interface if they wish to provide an
* <code>AclObjectIdentity</code> rather than it being determined by relying
@@ -37,5 +37,5 @@ public interface AclObjectIdentityAware {
*
* @return the ACL object identity for this instance (can never be <code>null</code>)
*/
AclObjectIdentity getAclObjectIdentity();
public AclObjectIdentity getAclObjectIdentity();
}
@@ -18,13 +18,13 @@ package org.acegisecurity.acl.basic;
/**
* Represents a data access object that can return the {@link BasicAclEntry}s
* applying to a given ACL object identity.
*
*
* <P>
* <code>BasicAclDao</code> implementations are responsible for interpreting a
* given {@link AclObjectIdentity} and being able to lookup and return the
* corresponding {@link BasicAclEntry}[]s.
* </p>
*
*
* <P>
* <code>BasicAclDao</code>s many, but are not required to, allow the backend
* ACL repository to specify the class of <code>BasicAclEntry</code>
@@ -48,5 +48,5 @@ public interface BasicAclDao {
* @return the ACLs that apply (no <code>null</code>s are permitted in the array), or <code>null</code> if no ACLs
* could be found for the specified ACL object identity
*/
BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);
}
@@ -35,7 +35,7 @@ public interface BasicAclEntry extends AclEntry {
*
* @return the ACL object identity that is subject of this ACL entry (never <code>null</code>)
*/
AclObjectIdentity getAclObjectIdentity();
public AclObjectIdentity getAclObjectIdentity();
/**
* Indicates any ACL parent of the domain object instance. This is used by <code>BasicAclProvider</code> to
@@ -44,7 +44,7 @@ public interface BasicAclEntry extends AclEntry {
* @return the ACL object identity that is the parent of this ACL entry (may be <code>null</code> if no parent
* should be consulted)
*/
AclObjectIdentity getAclObjectParentIdentity();
public AclObjectIdentity getAclObjectParentIdentity();
/**
* Access control lists in this package are based on bit masking. The integer value of the bit mask can be
@@ -53,7 +53,7 @@ public interface BasicAclEntry extends AclEntry {
* @return the bit mask applicable to this ACL entry (zero indicates a bit mask where no permissions have been
* granted)
*/
int getMask();
public int getMask();
/**
* A domain object instance will usually have multiple <code>BasicAclEntry</code>s. Each separate
@@ -65,12 +65,12 @@ public interface BasicAclEntry extends AclEntry {
* object type will vary depending on the type of recipient. For instance, it might be a <code>String</code>
* containing a username, or a <code>GrantedAuthorityImpl</code> containing a complex granted authority that is
* being granted the permissions contained in this access control entry. The {@link EffectiveAclsResolver} and
* {@link BasicAclProvider#getAcls(Object,org.acegisecurity.Authentication)} can process the different recipient
* types and return only those that apply to a specified <code>Authentication</code> object.</p>
* {@link BasicAclProvider#getAcls(Object, Authentication)} can process the different recipient types and return
* only those that apply to a specified <code>Authentication</code> object.</p>
*
* @return the recipient of this access control list entry (never <code>null</code>)
*/
Object getRecipient();
public Object getRecipient();
/**
* Determine if the mask of this entry includes this permission or not
@@ -79,7 +79,7 @@ public interface BasicAclEntry extends AclEntry {
*
* @return if the entry's mask includes this permission
*/
boolean isPermitted(int permissionToCheck);
public boolean isPermitted(int permissionToCheck);
/**
* This setter should <B>only</B> be used by DAO implementations.
@@ -87,7 +87,7 @@ public interface BasicAclEntry extends AclEntry {
* @param aclObjectIdentity an object which can be used to uniquely identify the domain object instance subject of
* this ACL entry
*/
void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity);
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity);
/**
* This setter should <B>only</B> be used by DAO implementations.
@@ -96,14 +96,14 @@ public interface BasicAclEntry extends AclEntry {
* this ACL entry, or <code>null</code> if either the domain object instance has no parent or its parent
* should be not used to compute an inheritance hierarchy
*/
void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity);
public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity);
/**
* This setter should <B>only</B> be used by DAO implementations.
*
* @param mask the integer representing the permissions bit mask
*/
void setMask(int mask);
public void setMask(int mask);
/**
* This setter should <B>only</B> be used by DAO implementations.
@@ -111,5 +111,5 @@ public interface BasicAclEntry extends AclEntry {
* @param recipient a representation of the recipient of this ACL entry that makes sense to an
* <code>EffectiveAclsResolver</code> implementation
*/
void setRecipient(Object recipient);
public void setRecipient(Object recipient);
}
@@ -17,7 +17,7 @@ package org.acegisecurity.acl.basic;
/**
* Provides a cache of {@link BasicAclEntry} objects.
*
*
* <P>
* Implementations should provide appropriate methods to set their cache
* parameters (eg time-to-live) and/or force removal of entities before their
@@ -41,7 +41,7 @@ public interface BasicAclEntryCache {
* @return any applicable <code>BasicAclEntry</code>s (no <code>null</code>s are permitted in the returned array)
* or <code>null</code> if the object identity could not be found or if the cache entry has expired
*/
BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity);
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity);
/**
* Places an array of {@link BasicAclEntry}s in the cache.<P>No <code>null</code>s are allowed in the
@@ -50,12 +50,12 @@ public interface BasicAclEntryCache {
* @param basicAclEntry the ACL entries to cache (the key will be extracted from the {@link
* BasicAclEntry#getAclObjectIdentity()} method
*/
void putEntriesInCache(BasicAclEntry[] basicAclEntry);
public void putEntriesInCache(BasicAclEntry[] basicAclEntry);
/**
* Removes all ACL entries related to an {@link AclObjectIdentity} from the cache.
*
* @param aclObjectIdentity which should be removed from the cache
*/
void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity);
public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity);
}
@@ -21,12 +21,12 @@ import org.springframework.dao.DataAccessException;
/**
* Represents a more extensive data access object
* for {@link BasicAclEntry}s.
*
* <p>
*
* <P>
* <code>BasicAclExtendedDao</code> implementations are responsible for interpreting a
* a given {@link AclObjectIdentity}.
* </p>
*
*
* @author Ben Alex
* @version $Id$
*/
@@ -43,10 +43,10 @@ public interface BasicAclExtendedDao extends BasicAclDao {
*
* @throws DataAccessException DOCUMENT ME!
*/
void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
throws DataAccessException;
void create(BasicAclEntry basicAclEntry) throws DataAccessException;
public void create(BasicAclEntry basicAclEntry) throws DataAccessException;
/**
* Deletes <b>all</b> entries associated with the specified <code>AclObjectIdentity</code>.
@@ -55,7 +55,7 @@ public interface BasicAclExtendedDao extends BasicAclDao {
*
* @throws DataAccessException DOCUMENT ME!
*/
void delete(AclObjectIdentity aclObjectIdentity)
public void delete(AclObjectIdentity aclObjectIdentity)
throws DataAccessException;
/**
@@ -67,6 +67,6 @@ public interface BasicAclExtendedDao extends BasicAclDao {
*
* @throws DataAccessException DOCUMENT ME!
*/
void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
throws DataAccessException;
}
@@ -36,24 +36,18 @@ import java.util.Map;
/**
* Retrieves access control lists (ACL) entries for domain object instances from a data access object (DAO).
* <p>
* This implementation will provide ACL lookup services for any object that it can determine the {@link
* <P>Retrieves access control lists (ACL) entries for domain object instances from a data access object (DAO).</p>
* <P>This implementation will provide ACL lookup services for any object that it can determine the {@link
* AclObjectIdentity} for by calling the {@link #obtainIdentity(Object)} method. Subclasses can override this method
* if they only want the <code>BasicAclProvider</code> responding to particular domain object instances.
* </p>
* <p>
* <code>BasicAclProvider</code> will walk an inheritance hierarchy if a <code>BasicAclEntry</code> returned by
* the DAO indicates it has a parent. NB: inheritance occurs at a <i>domain instance object</i> level. It does not
* occur at an ACL recipient level. This means <b>all</b><code>BasicAclEntry</code>s for a given domain instance
* object <b>must</b> have the <b>same</b> parent identity, or <b>all</b><code>BasicAclEntry</code>s must have
* <code>null</code> as their parent identity.
* </p>
* <p>
* A cache should be used. This is provided by the {@link BasicAclEntryCache}. <code>BasicAclProvider</code> by
* default is setup to use the {@link NullAclEntryCache}, which performs no caching.
* </p>
* <p>To implement the {@link #getAcls(Object, Authentication)} method, <code>BasicAclProvider</code> requires a
* if they only want the <code>BasicAclProvider</code> responding to particular domain object instances.</p>
* <P><code>BasicAclProvider</code> will walk an inheritance hierarchy if a <code>BasicAclEntry</code> returned by
* the DAO indicates it has a parent. NB: inheritance occurs at a <I>domain instance object</I> level. It does not
* occur at an ACL recipient level. This means <B>all</B><code>BasicAclEntry</code>s for a given domain instance
* object <B>must</B> have the <B>same</B> parent identity, or <B>all</B><code>BasicAclEntry</code>s must have
* <code>null</code> as their parent identity.</p>
* <P>A cache should be used. This is provided by the {@link BasicAclEntryCache}. <code>BasicAclProvider</code> by
* default is setup to use the {@link NullAclEntryCache}, which performs no caching.</p>
* <P>To implement the {@link #getAcls(Object, Authentication)} method, <code>BasicAclProvider</code> requires a
* {@link EffectiveAclsResolver} to be configured against it. By default the {@link
* GrantedAuthorityEffectiveAclsResolver} is used.</p>
*
@@ -66,7 +60,7 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
private static final Log logger = LogFactory.getLog(BasicAclProvider.class);
/** Marker added to the cache to indicate an AclObjectIdentity has no corresponding BasicAclEntry[]s */
private static final String RECIPIENT_FOR_CACHE_EMPTY = "RESERVED_RECIPIENT_NOBODY";
private static String RECIPIENT_FOR_CACHE_EMPTY = "RESERVED_RECIPIENT_NOBODY";
//~ Instance fields ================================================================================================
@@ -243,8 +237,7 @@ public class BasicAclProvider implements AclProvider, InitializingBean {
Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class});
if (logger.isDebugEnabled()) {
logger.debug("domainInstance: " + domainInstance
+ " attempting to pass to constructor: " + constructor);
logger.debug("domainInstance: " + domainInstance + " attempting to pass to constructor: " + constructor);
}
return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance});
@@ -23,14 +23,14 @@ import org.acegisecurity.acl.AclEntry;
/**
* Determines the ACLs that are effective for a given
* <code>Authentication</code> object.
*
*
* <P>
* Implementations will vary depending on their ability to interpret the
* "recipient" object types contained in {@link BasicAclEntry} instances, and
* how those recipient object types correspond to
* <code>Authentication</code>-presented principals and granted authorities.
* </p>
*
*
* <P>
* Implementations should not filter the resulting ACL list from lower-order
* permissions. So if a resulting ACL list grants a "read" permission, an
@@ -57,5 +57,5 @@ public interface EffectiveAclsResolver {
*
* @return the ACLs that apply to the presented principal, or <code>null</code> if there are none after filtering
*/
AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy);
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy);
}
@@ -96,8 +96,9 @@ public class GrantedAuthorityEffectiveAclsResolver implements EffectiveAclsResol
if ((authorities == null) || (authorities.length == 0)) {
if (logger.isDebugEnabled()) {
logger.debug("Did not match principal and there are no granted authorities, "
+ "so cannot compare with recipient: " + recipient);
logger.debug(
"Did not match principal and there are no granted authorities, so cannot compare with recipient: "
+ recipient);
}
continue;
@@ -18,6 +18,7 @@ package org.acegisecurity.acl.basic;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Stores some privileges typical of a domain object.
*
@@ -44,21 +45,17 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
public static final int READ_WRITE_DELETE = READ | WRITE | DELETE;
// Array required by the abstract superclass via getValidPermissions()
private static final int[] VALID_PERMISSIONS = {
private static final int[] validPermissions = {
NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE,
READ_WRITE, READ_WRITE_DELETE
};
private static final String[] VALID_PERMISSIONS_AS_STRING = {
"NOTHING", "ADMINISTRATION", "READ", "WRITE", "CREATE", "DELETE", "READ_WRITE_CREATE_DELETE",
"READ_WRITE_CREATE", "READ_WRITE", "READ_WRITE_DELETE" };
//~ Constructors ===================================================================================================
/**
/**
* Allows {@link BasicAclDao} implementations to construct this object
* using <code>newInstance()</code>.
*
*
* <P>
* Normal classes should <B>not</B> use this default constructor.
* </p>
@@ -74,11 +71,8 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
//~ Methods ========================================================================================================
/**
* @return a copy of the permissions array, changes to the values won't affect this class.
*/
public int[] getValidPermissions() {
return (int[]) VALID_PERMISSIONS.clone();
return validPermissions;
}
public String printPermissionsBlock(int i) {
@@ -116,35 +110,4 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
return sb.toString();
}
/**
* Parse a permission {@link String} literal and return associated value.
*
* @param permission one of the field names that represent a permission: <code>ADMINISTRATION</code>,
* <code>READ</code>, <code>WRITE</code>,...
* @return the value associated to that permission
* @throws IllegalArgumentException if argument is not a valid permission
*/
public static int parsePermission(String permission) {
for (int i = 0; i < VALID_PERMISSIONS_AS_STRING.length; i++) {
if (VALID_PERMISSIONS_AS_STRING[i].equalsIgnoreCase(permission)) {
return VALID_PERMISSIONS[i];
}
}
throw new IllegalArgumentException("Permission provided does not exist: " + permission);
}
/**
* Parse a list of permission {@link String} literals and return associated values.
*
* @param permissions array with permissions as {@link String}
* @see #parsePermission(String) for valid values
*/
public static int[] parsePermissions(String[] permissions) {
int[] requirepermissionAsIntArray = new int[permissions.length];
for (int i = 0; i < requirepermissionAsIntArray.length; i++) {
requirepermissionAsIntArray[i] = parsePermission(permissions[i]);
}
return requirepermissionAsIntArray;
}
}
@@ -42,27 +42,17 @@ import javax.sql.DataSource;
/**
* Retrieves ACL details from a JDBC location.
* <p>
* A default database structure is assumed. This may be overridden by setting the default query strings to use.
* <p>Retrieves ACL details from a JDBC location.</p>
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.
* If this does not provide enough flexibility, another strategy would be to subclass this class and override the
* {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.
* </p>
* {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.</p>
*/
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
//~ Static fields/initializers =====================================================================================
public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___";
public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY =
"SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
public static final String DEF_OBJECT_PROPERTIES_QUERY =
"SELECT CHILD.ID, "
+ "CHILD.OBJECT_IDENTITY, "
+ "CHILD.ACL_CLASS, "
+ "PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY "
+ "FROM acl_object_identity as CHILD "
+ "LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id "
+ "WHERE CHILD.object_identity = ?";
public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY = "SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?";
private static final Log logger = LogFactory.getLog(JdbcDaoImpl.class);
//~ Instance fields ================================================================================================
@@ -392,8 +382,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
throw new IllegalArgumentException(cnf.getMessage());
}
return new AclDetailsHolder(id,
buildIdentity(objectIdentity), buildIdentity(parentObjectIdentity), aclClazz);
return new AclDetailsHolder(id, buildIdentity(objectIdentity), buildIdentity(parentObjectIdentity), aclClazz);
}
}
}
@@ -48,8 +48,8 @@ import javax.sql.DataSource;
/**
* <p>Extension of the base {@link JdbcDaoImpl}, which implements {@link BasicAclExtendedDao}.</p>
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.</p>
* <p>If you are using a cache with <code>BasicAclProvider</code>, you should specify that cache via {@link
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.</p>
* <p>If you are using a cache with <code>BasicAclProvider</code>, you should specify that cache via {@link
* #setBasicAclEntryCache(BasicAclEntryCache)}. This will cause cache evictions (removals) to take place whenever a
* DAO mutator method is called.</p>
* <p>This implementation works with <code>String</code> based recipients and {@link
@@ -63,18 +63,12 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl implements BasicAclExtended
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class);
public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT =
"DELETE FROM acl_object_identity WHERE id = ?";
public static final String DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT =
"INSERT INTO acl_object_identity (object_identity, parent_object, acl_class) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_DELETE_STATEMENT =
"DELETE FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
public static final String DEF_ACL_PERMISSION_INSERT_STATEMENT =
"INSERT INTO acl_permission (acl_object_identity, recipient, mask) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT =
"UPDATE acl_permission SET mask = ? WHERE id = ?";
public static final String DEF_LOOKUP_PERMISSION_ID_QUERY =
"SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT = "DELETE FROM acl_object_identity WHERE id = ?";
public static final String DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT = "INSERT INTO acl_object_identity (object_identity, parent_object, acl_class) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_DELETE_STATEMENT = "DELETE FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
public static final String DEF_ACL_PERMISSION_INSERT_STATEMENT = "INSERT INTO acl_permission (acl_object_identity, recipient, mask) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT = "UPDATE acl_permission SET mask = ? WHERE id = ?";
public static final String DEF_LOOKUP_PERMISSION_ID_QUERY = "SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
//~ Instance fields ================================================================================================
@@ -1,126 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.domain;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.acls.Acl;
import org.acegisecurity.acls.Permission;
import org.acegisecurity.acls.sid.PrincipalSid;
import org.acegisecurity.acls.sid.Sid;
import org.acegisecurity.acls.sid.SidRetrievalStrategy;
import org.acegisecurity.acls.sid.SidRetrievalStrategyImpl;
import org.acegisecurity.context.SecurityContextHolder;
import org.springframework.util.Assert;
/**
* Default implementation of {@link AclAuthorizationStrategy}.<p>Permission will be granted provided the current
* principal is either the owner (as defined by the ACL), has {@link BasePermission#ADMINISTRATION} (as defined by the
* ACL and via a {@link Sid} retrieved for the current principal via {@link #sidRetrievalStrategy}), or if the current
* principal holds the relevant system-wide {@link GrantedAuthority} and injected into the constructor.</p>
*
* @author Ben Alex
* @version $Id$
*/
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
//~ Instance fields ================================================================================================
private GrantedAuthority gaGeneralChanges;
private GrantedAuthority gaModifyAuditing;
private GrantedAuthority gaTakeOwnership;
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
//~ Constructors ===================================================================================================
/**
* Constructor. The only mandatory parameter relates to the system-wide {@link GrantedAuthority} instances that
* can be held to always permit ACL changes.
*
* @param auths an array of <code>GrantedAuthority</code>s that have
* special permissions (index 0 is the authority needed to change
* ownership, index 1 is the authority needed to modify auditing details,
* index 2 is the authority needed to change other ACL and ACE details) (required)
*/
public AclAuthorizationStrategyImpl(GrantedAuthority[] auths) {
Assert.notEmpty(auths, "GrantedAuthority[] with three elements required");
Assert.isTrue(auths.length == 3, "GrantedAuthority[] with three elements required");
this.gaTakeOwnership = auths[0];
this.gaModifyAuditing = auths[1];
this.gaGeneralChanges = auths[2];
}
//~ Methods ========================================================================================================
public void securityCheck(Acl acl, int changeType) {
if ((SecurityContextHolder.getContext() == null)
|| (SecurityContextHolder.getContext().getAuthentication() == null)
|| !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// Check if authorized by virtue of ACL ownership
Sid currentUser = new PrincipalSid(authentication);
if (currentUser.equals(acl.getOwner())
&& ((changeType == CHANGE_GENERAL) || (changeType == CHANGE_OWNERSHIP))) {
return;
}
// Not authorized by ACL ownership; try via adminstrative permissions
GrantedAuthority requiredAuthority = null;
if (changeType == CHANGE_AUDITING) {
requiredAuthority = this.gaModifyAuditing;
} else if (changeType == CHANGE_GENERAL) {
requiredAuthority = this.gaGeneralChanges;
} else if (changeType == CHANGE_OWNERSHIP) {
requiredAuthority = this.gaTakeOwnership;
} else {
throw new IllegalArgumentException("Unknown change type");
}
// Iterate this principal's authorities to determine right
GrantedAuthority[] auths = authentication.getAuthorities();
for (int i = 0; i < auths.length; i++) {
if (requiredAuthority.equals(auths[i])) {
return;
}
}
// Try to get permission via ACEs within the ACL
Sid[] sids = sidRetrievalStrategy.getSids(authentication);
if (acl.isGranted(new Permission[] {BasePermission.ADMINISTRATION}, sids, false)) {
return;
}
throw new AccessDeniedException(
"Principal does not have required ACL permissions to perform requested operation");
}
public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
Assert.notNull(sidRetrievalStrategy, "SidRetrievalStrategy required");
this.sidRetrievalStrategy = sidRetrievalStrategy;
}
}
@@ -1,168 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.domain;
import org.acegisecurity.acls.AclFormattingUtils;
import org.acegisecurity.acls.Permission;
import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
/**
* A set of standard permissions.
*
* @author Ben Alex
* @version $Id$
*/
public final class BasePermission implements Permission {
//~ Static fields/initializers =====================================================================================
public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
public static final Permission WRITE = new BasePermission(1 << 1, 'W'); // 2
public static final Permission CREATE = new BasePermission(1 << 2, 'C'); // 4
public static final Permission DELETE = new BasePermission(1 << 3, 'D'); // 8
public static final Permission ADMINISTRATION = new BasePermission(1 << 4, 'A'); // 16
private static Map locallyDeclaredPermissionsByInteger = new HashMap();
private static Map locallyDeclaredPermissionsByName = new HashMap();
static {
Field[] fields = BasePermission.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
try {
Object fieldValue = fields[i].get(null);
if (BasePermission.class.isAssignableFrom(fieldValue.getClass())) {
// Found a BasePermission static field
BasePermission perm = (BasePermission) fieldValue;
locallyDeclaredPermissionsByInteger.put(new Integer(perm.getMask()), perm);
locallyDeclaredPermissionsByName.put(fields[i].getName(), perm);
}
} catch (Exception ignore) {}
}
}
//~ Instance fields ================================================================================================
private char code;
private int mask;
//~ Constructors ===================================================================================================
private BasePermission(int mask, char code) {
this.mask = mask;
this.code = code;
}
//~ Methods ========================================================================================================
/**
* Dynamically creates a <code>CumulativePermission</code> or <code>BasePermission</code> representing the
* active bits in the passed mask.
*
* @param mask to build
*
* @return a Permission representing the requested object
*/
public static Permission buildFromMask(int mask) {
if (locallyDeclaredPermissionsByInteger.containsKey(new Integer(mask))) {
// The requested mask has an exactly match against a statically-defined BasePermission, so return it
return (Permission) locallyDeclaredPermissionsByInteger.get(new Integer(mask));
}
// To get this far, we have to use a CumulativePermission
CumulativePermission permission = new CumulativePermission();
for (int i = 0; i < 32; i++) {
int permissionToCheck = 1 << i;
if ((mask & permissionToCheck) == permissionToCheck) {
Permission p = (Permission) locallyDeclaredPermissionsByInteger.get(new Integer(permissionToCheck));
Assert.state(p != null,
"Mask " + permissionToCheck + " does not have a corresponding static BasePermission");
permission.set(p);
}
}
return permission;
}
public static Permission[] buildFromMask(int[] masks) {
if ((masks == null) || (masks.length == 0)) {
return new Permission[] {};
}
List list = new Vector();
for (int i = 0; i < masks.length; i++) {
list.add(BasePermission.buildFromMask(masks[i]));
}
return (Permission[]) list.toArray(new Permission[] {});
}
public static Permission buildFromName(String name) {
Assert.isTrue(locallyDeclaredPermissionsByName.containsKey(name), "Unknown permission '" + name + "'");
return (Permission) locallyDeclaredPermissionsByName.get(name);
}
public static Permission[] buildFromName(String[] names) {
if ((names == null) || (names.length == 0)) {
return new Permission[] {};
}
List list = new Vector();
for (int i = 0; i < names.length; i++) {
list.add(BasePermission.buildFromName(names[i]));
}
return (Permission[]) list.toArray(new Permission[] {});
}
public boolean equals(Object arg0) {
if (!(arg0 instanceof BasePermission)) {
return false;
}
BasePermission rhs = (BasePermission) arg0;
return (this.mask == rhs.getMask());
}
public int getMask() {
return mask;
}
public String getPattern() {
return AclFormattingUtils.printBinary(mask, code);
}
public String toString() {
return "BasePermission[" + getPattern() + "=" + mask + "]";
}
public int hashCode() {
return this.mask;
}
}
@@ -1,5 +0,0 @@
<html>
<body>
Basic implementation of access control lists (ACLs) interfaces.
</body>
</html>
@@ -1,114 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.jdbc;
import org.acegisecurity.acls.Acl;
import org.acegisecurity.acls.AclService;
import org.acegisecurity.acls.NotFoundException;
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
import org.acegisecurity.acls.sid.Sid;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.Assert;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
/**
* Simple JDBC-based implementation of <code>AclService</code>.<p>Requires the "dirty" flags in {@link
* org.acegisecurity.acls.domain.AclImpl} and {@link org.acegisecurity.acls.domain.AccessControlEntryImpl} to be set,
* so that the implementation can detect changed parameters easily.</p>
*
* @author Ben Alex
* @version $Id$
*/
public class JdbcAclService implements AclService {
//~ Static fields/initializers =====================================================================================
protected static final Log log = LogFactory.getLog(JdbcAclService.class);
private static final String selectAclObjectWithParent = "SELECT obj.object_id_identity obj_id, class.class class "
+ "FROM acl_object_identity obj, acl_object_identity parent, acl_class class "
+ "WHERE obj.parent_object = parent.id AND obj.object_id_class = class.id "
+ "AND parent.object_id_identity = ? AND parent.object_id_class = ("
+ "SELECT id FROM acl_class WHERE acl_class.class = ?)";
//~ Instance fields ================================================================================================
protected JdbcTemplate jdbcTemplate;
private LookupStrategy lookupStrategy;
//~ Constructors ===================================================================================================
public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
Assert.notNull(dataSource, "DataSource required");
Assert.notNull(lookupStrategy, "LookupStrategy required");
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.lookupStrategy = lookupStrategy;
}
//~ Methods ========================================================================================================
public ObjectIdentity[] findChildren(ObjectIdentity parentIdentity) {
Object[] args = {parentIdentity.getIdentifier(), parentIdentity.getJavaType().getName()};
List objects = jdbcTemplate.query(selectAclObjectWithParent, args,
new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
String javaType = rs.getString("class");
String identifier = rs.getString("obj_id");
return new ObjectIdentityImpl(javaType, identifier);
}
});
return (ObjectIdentityImpl[]) objects.toArray(new ObjectIdentityImpl[] {});
}
public Acl readAclById(ObjectIdentity object, Sid[] sids)
throws NotFoundException {
Map map = readAclsById(new ObjectIdentity[] {object}, sids);
if (map.size() == 0) {
throw new NotFoundException("Could not find ACL");
} else {
return (Acl) map.get(object);
}
}
public Acl readAclById(ObjectIdentity object) throws NotFoundException {
return readAclById(object, null);
}
public Map readAclsById(ObjectIdentity[] objects) {
return readAclsById(objects, null);
}
public Map readAclsById(ObjectIdentity[] objects, Sid[] sids)
throws NotFoundException {
return lookupStrategy.readAclsById(objects, sids);
}
}
@@ -1,371 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.jdbc;
import org.acegisecurity.Authentication;
import org.acegisecurity.acls.AccessControlEntry;
import org.acegisecurity.acls.Acl;
import org.acegisecurity.acls.AlreadyExistsException;
import org.acegisecurity.acls.ChildrenExistException;
import org.acegisecurity.acls.MutableAcl;
import org.acegisecurity.acls.MutableAclService;
import org.acegisecurity.acls.NotFoundException;
import org.acegisecurity.acls.domain.AccessControlEntryImpl;
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
import org.acegisecurity.acls.sid.GrantedAuthoritySid;
import org.acegisecurity.acls.sid.PrincipalSid;
import org.acegisecurity.acls.sid.Sid;
import org.acegisecurity.context.SecurityContextHolder;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import java.lang.reflect.Array;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
/**
* Provides a base implementation of {@link MutableAclService}.
*
* @author Ben Alex
* @author Johannes Zlattinger
* @version $Id$
*/
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
//~ Instance fields ================================================================================================
private AclCache aclCache;
private String deleteClassByClassNameString = "DELETE FROM acl_class WHERE class=?";
private String deleteEntryByObjectIdentityForeignKey = "DELETE FROM acl_entry WHERE acl_object_identity=?";
private String deleteObjectIdentityByPrimaryKey = "DELETE FROM acl_object_identity WHERE id=?";
private String identityQuery = "call identity()";
private String insertClass = "INSERT INTO acl_class (id, class) VALUES (null, ?)";
private String insertEntry = "INSERT INTO acl_entry "
+ "(id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
+ "VALUES (null, ?, ?, ?, ?, ?, ?, ?)";
private String insertObjectIdentity = "INSERT INTO acl_object_identity "
+ "(id, object_id_class, object_id_identity, owner_sid, entries_inheriting) " + "VALUES (null, ?, ?, ?, ?)";
private String insertSid = "INSERT INTO acl_sid (id, principal, sid) VALUES (null, ?, ?)";
private String selectClassPrimaryKey = "SELECT id FROM acl_class WHERE class=?";
private String selectCountObjectIdentityRowsForParticularClassNameString = "SELECT COUNT(acl_object_identity.id) "
+ "FROM acl_object_identity, acl_class WHERE acl_class.id = acl_object_identity.object_id_class and class=?";
private String selectObjectIdentityPrimaryKey = "SELECT acl_object_identity.id FROM acl_object_identity, acl_class "
+ "WHERE acl_object_identity.object_id_class = acl_class.id and acl_class.class=? "
+ "and acl_object_identity.object_id_identity = ?";
private String selectSidPrimaryKey = "SELECT id FROM acl_sid WHERE principal=? AND sid=?";
private String updateObjectIdentity = "UPDATE acl_object_identity SET "
+ "parent_object = ?, owner_sid = ?, entries_inheriting = ?" + "where id = ?";
//~ Constructors ===================================================================================================
public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {
super(dataSource, lookupStrategy);
Assert.notNull(aclCache, "AclCache required");
this.aclCache = aclCache;
}
//~ Methods ========================================================================================================
public MutableAcl createAcl(ObjectIdentity objectIdentity)
throws AlreadyExistsException {
Assert.notNull(objectIdentity, "Object Identity required");
// Check this object identity hasn't already been persisted
if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {
throw new AlreadyExistsException("Object identity '" + objectIdentity + "' already exists");
}
// Need to retrieve the current principal, in order to know who "owns" this ACL (can be changed later on)
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
PrincipalSid sid = new PrincipalSid(auth);
// Create the acl_object_identity row
createObjectIdentity(objectIdentity, sid);
// Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
Acl acl = readAclById(objectIdentity);
Assert.isInstanceOf(MutableAcl.class, acl, "MutableAcl should be been returned");
return (MutableAcl) acl;
}
/**
* Creates a new row in acl_entry for every ACE defined in the passed MutableAcl object.
*
* @param acl containing the ACEs to insert
*/
protected void createEntries(final MutableAcl acl) {
jdbcTemplate.batchUpdate(insertEntry,
new BatchPreparedStatementSetter() {
public int getBatchSize() {
return acl.getEntries().length;
}
public void setValues(PreparedStatement stmt, int i)
throws SQLException {
AccessControlEntry entry_ = (AccessControlEntry) Array.get(acl.getEntries(), i);
Assert.isTrue(entry_ instanceof AccessControlEntryImpl, "Unknown ACE class");
AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
stmt.setLong(1, ((Long) acl.getId()).longValue());
stmt.setInt(2, i);
stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true).longValue());
stmt.setInt(4, entry.getPermission().getMask());
stmt.setBoolean(5, entry.isGranting());
stmt.setBoolean(6, entry.isAuditSuccess());
stmt.setBoolean(7, entry.isAuditFailure());
}
});
}
/**
* Creates an entry in the acl_object_identity table for the passed ObjectIdentity. The Sid is also
* necessary, as acl_object_identity has defined the sid column as non-null.
*
* @param object to represent an acl_object_identity for
* @param owner for the SID column (will be created if there is no acl_sid entry for this particular Sid already)
*/
protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
Long classId = createOrRetrieveClassPrimaryKey(object.getJavaType(), true);
jdbcTemplate.update(insertObjectIdentity,
new Object[] {classId, object.getIdentifier().toString(), sidId, new Boolean(true)});
}
/**
* Retrieves the primary key from acl_class, creating a new row if needed and the allowCreate property is
* true.
*
* @param clazz to find or create an entry for (this implementation uses the fully-qualified class name String)
* @param allowCreate true if creation is permitted if not found
*
* @return the primary key or null if not found
*/
protected Long createOrRetrieveClassPrimaryKey(Class clazz, boolean allowCreate) {
List classIds = jdbcTemplate.queryForList(selectClassPrimaryKey, new Object[] {clazz.getName()}, Long.class);
Long classId = null;
if (classIds.isEmpty()) {
if (allowCreate) {
classId = null;
jdbcTemplate.update(insertClass, new Object[] {clazz.getName()});
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
classId = new Long(jdbcTemplate.queryForLong(identityQuery));
}
} else {
classId = (Long) classIds.iterator().next();
}
return classId;
}
/**
* Retrieves the primary key from acl_sid, creating a new row if needed and the allowCreate property is
* true.
*
* @param sid to find or create
* @param allowCreate true if creation is permitted if not found
*
* @return the primary key or null if not found
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
protected Long createOrRetrieveSidPrimaryKey(Sid sid, boolean allowCreate) {
Assert.notNull(sid, "Sid required");
String sidName = null;
boolean principal = true;
if (sid instanceof PrincipalSid) {
sidName = ((PrincipalSid) sid).getPrincipal();
} else if (sid instanceof GrantedAuthoritySid) {
sidName = ((GrantedAuthoritySid) sid).getGrantedAuthority();
principal = false;
} else {
throw new IllegalArgumentException("Unsupported implementation of Sid");
}
List sidIds = jdbcTemplate.queryForList(selectSidPrimaryKey, new Object[] {new Boolean(principal), sidName},
Long.class);
Long sidId = null;
if (sidIds.isEmpty()) {
if (allowCreate) {
sidId = null;
jdbcTemplate.update(insertSid, new Object[] {new Boolean(principal), sidName});
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
sidId = new Long(jdbcTemplate.queryForLong(identityQuery));
}
} else {
sidId = (Long) sidIds.iterator().next();
}
return sidId;
}
public void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren)
throws ChildrenExistException {
Assert.notNull(objectIdentity, "Object Identity required");
Assert.notNull(objectIdentity.getIdentifier(), "Object Identity doesn't provide an identifier");
// Recursively call this method for children, or handle children if they don't want automatic recursion
ObjectIdentity[] children = findChildren(objectIdentity);
if (deleteChildren) {
for (int i = 0; i < children.length; i++) {
deleteAcl(children[i], true);
}
} else if (children.length > 0) {
throw new ChildrenExistException("Cannot delete '" + objectIdentity + "' (has " + children.length
+ " children)");
}
// Delete this ACL's ACEs in the acl_entry table
deleteEntries(objectIdentity);
// Delete this ACL's acl_object_identity row
deleteObjectIdentityAndOptionallyClass(objectIdentity);
// Clear the cache
aclCache.evictFromCache(objectIdentity);
}
/**
* Deletes all ACEs defined in the acl_entry table belonging to the presented ObjectIdentity
*
* @param oid the rows in acl_entry to delete
*/
protected void deleteEntries(ObjectIdentity oid) {
jdbcTemplate.update(deleteEntryByObjectIdentityForeignKey,
new Object[] {retrieveObjectIdentityPrimaryKey(oid)});
}
/**
* Deletes a single row from acl_object_identity that is associated with the presented ObjectIdentity. In
* addition, deletes the corresponding row from acl_class if there are no more entries in acl_object_identity that
* use that particular acl_class. This keeps the acl_class table reasonably small.
*
* @param oid to delete the acl_object_identity (and clean up acl_class for that class name if appropriate)
*/
protected void deleteObjectIdentityAndOptionallyClass(ObjectIdentity oid) {
// Delete the acl_object_identity row
jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, new Object[] {retrieveObjectIdentityPrimaryKey(oid)});
// Delete the acl_class row, assuming there are no other references to it in acl_object_identity
Object[] className = {oid.getJavaType().getName()};
long numObjectIdentities = jdbcTemplate.queryForLong(selectCountObjectIdentityRowsForParticularClassNameString,
className);
if (numObjectIdentities == 0) {
// No more rows
jdbcTemplate.update(deleteClassByClassNameString, className);
}
}
/**
* Retrieves the primary key from the acl_object_identity table for the passed ObjectIdentity. Unlike some
* other methods in this implementation, this method will NOT create a row (use {@link
* #createObjectIdentity(ObjectIdentity, Sid)} instead).
*
* @param oid to find
*
* @return the object identity or null if not found
*/
protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
try {
return new Long(jdbcTemplate.queryForLong(selectObjectIdentityPrimaryKey,
new Object[] {oid.getJavaType().getName(), oid.getIdentifier()}));
} catch (DataAccessException notFound) {
return null;
}
}
/**
* This implementation will simply delete all ACEs in the database and recreate them on each invocation of
* this method. A more comprehensive implementation might use dirty state checking, or more likely use ORM
* capabilities for create, update and delete operations of {@link MutableAcl}.
*
* @param acl DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws NotFoundException DOCUMENT ME!
*/
public MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {
Assert.notNull(acl.getId(), "Object Identity doesn't provide an identifier");
// Delete this ACL's ACEs in the acl_entry table
deleteEntries(acl.getObjectIdentity());
// Create this ACL's ACEs in the acl_entry table
createEntries(acl);
// Change the mutable columns in acl_object_identity
updateObjectIdentity(acl);
// Clear the cache
aclCache.evictFromCache(acl.getObjectIdentity());
// Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
return (MutableAcl) super.readAclById(acl.getObjectIdentity());
}
/**
* Updates an existing acl_object_identity row, with new information presented in the passed MutableAcl
* object. Also will create an acl_sid entry if needed for the Sid that owns the MutableAcl.
*
* @param acl to modify (a row must already exist in acl_object_identity)
*
* @throws NotFoundException DOCUMENT ME!
*/
protected void updateObjectIdentity(MutableAcl acl) {
Long parentId = null;
if (acl.getParentAcl() != null) {
Assert.isInstanceOf(ObjectIdentityImpl.class, acl.getParentAcl().getObjectIdentity(),
"Implementation only supports ObjectIdentityImpl");
ObjectIdentityImpl oii = (ObjectIdentityImpl) acl.getParentAcl().getObjectIdentity();
parentId = retrieveObjectIdentityPrimaryKey(oii);
}
Assert.notNull(acl.getOwner(), "Owner is required in this implementation");
Long ownerSid = createOrRetrieveSidPrimaryKey(acl.getOwner(), true);
int count = jdbcTemplate.update(updateObjectIdentity,
new Object[] {parentId, ownerSid, new Boolean(acl.isEntriesInheriting()), acl.getId()});
if (count != 1) {
throw new NotFoundException("Unable to locate ACL to update");
}
}
}
@@ -1,5 +0,0 @@
<html>
<body>
JDBC-based persistence of ACL information.
</body>
</html>
@@ -1,31 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.objectidentity;
/**
* Basic implementation of {@link ObjectIdentityRetrievalStrategy} that uses the constructor of {@link
* ObjectIdentityImpl} to create the {@link ObjectIdentity}.
*
* @author Ben Alex
* @version $Id$
*/
public class ObjectIdentityRetrievalStrategyImpl implements ObjectIdentityRetrievalStrategy {
//~ Methods ========================================================================================================
public ObjectIdentity getObjectIdentity(Object domainObject) {
return new ObjectIdentityImpl(domainObject);
}
}
@@ -1,5 +0,0 @@
<html>
<body>
Provides indirection between ACL packages and domain objects.
</body>
</html>
@@ -1,5 +0,0 @@
<html>
<body>
Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
</body>
</html>
@@ -1,48 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.acls.sid;
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import java.util.List;
import java.util.Vector;
/**
* Basic implementation of {@link SidRetrievalStrategy} that creates a {@link Sid} for the principal, as well as
* every granted authority the principal holds.<p>The returned array will always contain the {@link PrincipalSid}
* before any {@link GrantedAuthoritySid} elements.</p>
*
* @author Ben Alex
* @version $Id$
*/
public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
//~ Methods ========================================================================================================
public Sid[] getSids(Authentication authentication) {
List list = new Vector();
list.add(new PrincipalSid(authentication));
GrantedAuthority[] authorities = authentication.getAuthorities();
for (int i = 0; i < authorities.length; i++) {
list.add(new GrantedAuthoritySid(authorities[i]));
}
return (Sid[]) list.toArray(new Sid[] {});
}
}
@@ -1,5 +0,0 @@
<html>
<body>
Provides indirection between ACL packages and security identities, such as principals and GrantedAuthority[]s.
</body>
</html>
@@ -21,7 +21,7 @@ import org.acegisecurity.Authentication;
/**
* Indicates a specialized, immutable, server-side only {@link Authentication}
* class.
*
*
* <P>
* Automatically considered valid by the {@link AuthByAdapterProvider},
* provided the hash code presented by the implementation objects matches that
@@ -41,5 +41,5 @@ public interface AuthByAdapter extends Authentication {
*
* @return the hash code of the key used when the object was created.
*/
int getKeyHash();
public int getKeyHash();
}
@@ -27,7 +27,6 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
@@ -39,24 +38,15 @@ import org.springframework.util.Assert;
* <code>AuthByAdapterProvider</code>-configured key.</p>
* <P>If the key does not match, a <code>BadCredentialsException</code> is thrown.</p>
*/
public class AuthByAdapterProvider implements InitializingBean, AuthenticationProvider, MessageSourceAware, Ordered {
public class AuthByAdapterProvider implements InitializingBean, AuthenticationProvider, MessageSourceAware {
//~ Instance fields ================================================================================================
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
private String key;
private int order = -1; // default: same as non-Ordered
//~ Methods ========================================================================================================
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public void afterPropertiesSet() throws Exception {
public void afterPropertiesSet() throws Exception {
Assert.notNull(key, "A Key is required and should match that configured for the adapters");
Assert.notNull(messages, "A message source must be set");
}
@@ -29,7 +29,6 @@ import java.security.Principal;
public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken implements Principal {
//~ Instance fields ================================================================================================
private static final long serialVersionUID = 1L;
private Object principal;
private String password;
private String username;
@@ -1,130 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.afterinvocation;
import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.acls.Acl;
import org.acegisecurity.acls.AclService;
import org.acegisecurity.acls.NotFoundException;
import org.acegisecurity.acls.Permission;
import org.acegisecurity.acls.domain.BasePermission;
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategy;
import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl;
import org.acegisecurity.acls.sid.Sid;
import org.acegisecurity.acls.sid.SidRetrievalStrategy;
import org.acegisecurity.acls.sid.SidRetrievalStrategyImpl;
import org.springframework.util.Assert;
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
public abstract class AbstractAclProvider implements AfterInvocationProvider {
//~ Instance fields ================================================================================================
private AclService aclService;
private Class processDomainObjectClass = Object.class;
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
private String processConfigAttribute;
private Permission[] requirePermission = {BasePermission.READ};
//~ Constructors ===================================================================================================
public AbstractAclProvider(AclService aclService, String processConfigAttribute, Permission[] requirePermission) {
Assert.hasText(processConfigAttribute, "A processConfigAttribute is mandatory");
Assert.notNull(aclService, "An AclService is mandatory");
if ((requirePermission == null) || (requirePermission.length == 0)) {
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
}
this.aclService = aclService;
this.processConfigAttribute = processConfigAttribute;
this.requirePermission = requirePermission;
}
//~ Methods ========================================================================================================
protected Class getProcessDomainObjectClass() {
return processDomainObjectClass;
}
protected boolean hasPermission(Authentication authentication, Object domainObject) {
// Obtain the OID applicable to the domain object
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy.getObjectIdentity(domainObject);
// Obtain the SIDs applicable to the principal
Sid[] sids = sidRetrievalStrategy.getSids(authentication);
Acl acl = null;
try {
// Lookup only ACLs for SIDs we're interested in
acl = aclService.readAclById(objectIdentity, sids);
return acl.isGranted(requirePermission, sids, false);
} catch (NotFoundException ignore) {
return false;
}
}
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
Assert.notNull(objectIdentityRetrievalStrategy, "ObjectIdentityRetrievalStrategy required");
this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
}
protected void setProcessConfigAttribute(String processConfigAttribute) {
Assert.hasText(processConfigAttribute, "A processConfigAttribute is mandatory");
this.processConfigAttribute = processConfigAttribute;
}
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
this.processDomainObjectClass = processDomainObjectClass;
}
public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
Assert.notNull(sidRetrievalStrategy, "SidRetrievalStrategy required");
this.sidRetrievalStrategy = sidRetrievalStrategy;
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(this.processConfigAttribute)) {
return true;
} else {
return false;
}
}
/**
* This implementation supports any type of class, because it does not query the presented secure object.
*
* @param clazz the secure object
*
* @return always <code>true</code>
*/
public boolean supports(Class clazz) {
return true;
}
}
@@ -1,133 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.afterinvocation;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthorizationServiceException;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.acls.AclService;
import org.acegisecurity.acls.Permission;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Collection;
import java.util.Iterator;
/**
* <p>Given a <code>Collection</code> of domain object instances returned from a secure object invocation, remove
* any <code>Collection</code> elements the principal does not have appropriate permission to access as defined by the
* {@link AclService}.</p>
* <p>The <code>AclService</code> is used to retrieve the access control list (ACL) permissions associated with
* each <code>Collection</code> domain object instance element for the current <code>Authentication</code> object.</p>
* <p>This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclService</code> and ensure the
* principal is
* {@link org.acegisecurity.acls.Acl#isGranted(org.acegisecurity.acls.Permission[],
* org.acegisecurity.acls.sid.Sid[], boolean) Acl.isGranted(Permission[], Sid[], boolean)}
* when presenting the {@link #requirePermission} array to that method.</p>
* <p>If the principal does not have permission, that element will not be included in the returned
* <code>Collection</code>.</p>
* <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
* #processConfigAttribute} of <code>AFTER_ACL_COLLECTION_READ</code> and a {@link #requirePermission} of
* <code>BasePermission.READ</code>. These are also the defaults.</p>
* <p>If the provided <code>returnObject</code> is <code>null</code>, a <code>null</code><code>Collection</code>
* will be returned. If the provided <code>returnObject</code> is not a <code>Collection</code>, an {@link
* AuthorizationServiceException} will be thrown.</p>
* <p>All comparisons and prefixes are case sensitive.</p>
*
* @author Ben Alex
* @author Paulo Neves
* @version $Id$
*/
public class AclEntryAfterInvocationCollectionFilteringProvider extends AbstractAclProvider {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(AclEntryAfterInvocationCollectionFilteringProvider.class);
//~ Constructors ===================================================================================================
public AclEntryAfterInvocationCollectionFilteringProvider(AclService aclService, Permission[] requirePermission) {
super(aclService, "AFTER_ACL_COLLECTION_READ", requirePermission);
}
//~ Methods ========================================================================================================
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object returnedObject) throws AccessDeniedException {
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr)) {
// Need to process the Collection for this invocation
if (returnedObject == null) {
if (logger.isDebugEnabled()) {
logger.debug("Return object is null, skipping");
}
return null;
}
Filterer filterer = null;
if (returnedObject instanceof Collection) {
Collection collection = (Collection) returnedObject;
filterer = new CollectionFilterer(collection);
} else if (returnedObject.getClass().isArray()) {
Object[] array = (Object[]) returnedObject;
filterer = new ArrayFilterer(array);
} else {
throw new AuthorizationServiceException("A Collection or an array (or null) was required as the "
+ "returnedObject, but the returnedObject was: " + returnedObject);
}
// Locate unauthorised Collection elements
Iterator collectionIter = filterer.iterator();
while (collectionIter.hasNext()) {
Object domainObject = collectionIter.next();
boolean hasPermission = false;
if (domainObject == null) {
hasPermission = true;
} else if (!getProcessDomainObjectClass().isAssignableFrom(domainObject.getClass())) {
hasPermission = true;
} else {
hasPermission = hasPermission(authentication, domainObject);
if (!hasPermission) {
filterer.remove(domainObject);
if (logger.isDebugEnabled()) {
logger.debug("Principal is NOT authorised for element: " + domainObject);
}
}
}
}
return filterer.getFilteredObject();
}
}
return returnedObject;
}
}
@@ -1,119 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.afterinvocation;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.acls.AclService;
import org.acegisecurity.acls.Permission;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import java.util.Iterator;
/**
* <p>Given a domain object instance returned from a secure object invocation, ensures the principal has
* appropriate permission as defined by the {@link AclService}.</p>
* <p>The <code>AclService</code> is used to retrieve the access control list (ACL) permissions associated with a
* domain object instance for the current <code>Authentication</code> object.</p>
* <p>This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclService</code> and ensure the
* principal is {@link org.acegisecurity.acls.Acl#isGranted(org.acegisecurity.acls.Permission[],
org.acegisecurity.acls.sid.Sid[], boolean) Acl.isGranted(Permission[], Sid[], boolean)}
* when presenting the {@link #requirePermission} array to that method.</p>
* <p>Often users will setup an <code>AclEntryAfterInvocationProvider</code> with a {@link
* #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a {@link #requirePermission} of
* <code>BasePermission.READ</code>. These are also the defaults.</p>
* <p>If the principal does not have sufficient permissions, an <code>AccessDeniedException</code> will be thrown.</p>
* <p>If the provided <code>returnObject</code> is <code>null</code>, permission will always be granted and
* <code>null</code> will be returned.</p>
* <p>All comparisons and prefixes are case sensitive.</p>
*/
public class AclEntryAfterInvocationProvider extends AbstractAclProvider implements MessageSourceAware {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(AclEntryAfterInvocationProvider.class);
//~ Instance fields ================================================================================================
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
//~ Constructors ===================================================================================================
public AclEntryAfterInvocationProvider(AclService aclService, Permission[] requirePermission) {
super(aclService, "AFTER_ACL_READ", requirePermission);
}
//~ Methods ========================================================================================================
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object returnedObject) throws AccessDeniedException {
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr)) {
// Need to make an access decision on this invocation
if (returnedObject == null) {
// AclManager interface contract prohibits nulls
// As they have permission to null/nothing, grant access
if (logger.isDebugEnabled()) {
logger.debug("Return object is null, skipping");
}
return null;
}
if (!getProcessDomainObjectClass().isAssignableFrom(returnedObject.getClass())) {
if (logger.isDebugEnabled()) {
logger.debug("Return object is not applicable for this provider, skipping");
}
return returnedObject;
}
if (hasPermission(authentication, returnedObject)) {
return returnedObject;
} else {
if (logger.isDebugEnabled()) {
logger.debug("Denying access");
}
throw new AccessDeniedException(messages.getMessage(
"BasicAclEntryAfterInvocationProvider.noPermission",
new Object[] {authentication.getName(), returnedObject},
"Authentication {0} has NO permissions to the domain object {1}"));
}
}
}
return returnedObject;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
}
@@ -31,7 +31,7 @@ import org.acegisecurity.ConfigAttributeDefinition;
public interface AfterInvocationProvider {
//~ Methods ========================================================================================================
Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object returnedObject) throws AccessDeniedException;
/**
@@ -46,7 +46,7 @@ public interface AfterInvocationProvider {
*
* @return true if this <code>AfterInvocationProvider</code> can support the passed configuration attribute
*/
boolean supports(ConfigAttribute attribute);
public boolean supports(ConfigAttribute attribute);
/**
* Indicates whether the <code>AfterInvocationProvider</code> is able to provide "after invocation"
@@ -56,5 +56,5 @@ public interface AfterInvocationProvider {
*
* @return true if the implementation can process the indicated class
*/
boolean supports(Class clazz);
public boolean supports(Class clazz);
}
@@ -1,102 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.afterinvocation;
import org.apache.commons.collections.iterators.ArrayIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.lang.reflect.Array;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* A filter used to filter arrays.
*
* @author Ben Alex
* @author Paulo Neves
* @version $Id$
*/
class ArrayFilterer implements Filterer {
//~ Static fields/initializers =====================================================================================
protected static final Log logger =
LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
//~ Instance fields ================================================================================================
private Set removeList;
private Object[] list;
//~ Constructors ===================================================================================================
ArrayFilterer(Object[] list) {
this.list = list;
// Collect the removed objects to a HashSet so that
// it is fast to lookup them when a filtered array
// is constructed.
removeList = new HashSet();
}
//~ Methods ========================================================================================================
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
*/
public Object getFilteredObject() {
// Recreate an array of same type and filter the removed objects.
int originalSize = list.length;
int sizeOfResultingList = originalSize - removeList.size();
Object[] filtered = (Object[]) Array.newInstance(list.getClass().getComponentType(), sizeOfResultingList);
for (int i = 0, j = 0; i < list.length; i++) {
Object object = list[i];
if (!removeList.contains(object)) {
filtered[j] = object;
j++;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Original array contained " + originalSize + " elements; now contains " + sizeOfResultingList
+ " elements");
}
return filtered;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
*/
public Iterator iterator() {
return new ArrayIterator(list);
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
*/
public void remove(Object object) {
removeList.add(object);
}
}
@@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.acegisecurity.afterinvocation;
import org.acegisecurity.AccessDeniedException;
@@ -25,6 +26,7 @@ import org.acegisecurity.acl.AclManager;
import org.acegisecurity.acl.basic.BasicAclEntry;
import org.acegisecurity.acl.basic.SimpleAclEntry;
import org.apache.commons.collections.iterators.ArrayIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -32,8 +34,12 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
@@ -116,8 +122,9 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements
Object[] array = (Object[]) returnedObject;
filterer = new ArrayFilterer(array);
} else {
throw new AuthorizationServiceException("A Collection or an array (or null) was required as the "
+ "returnedObject, but the returnedObject was: " + returnedObject);
throw new AuthorizationServiceException(
"A Collection or an array (or null) was required as the returnedObject, but the returnedObject was: "
+ returnedObject);
}
// Locate unauthorised Collection elements
@@ -128,40 +135,42 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements
boolean hasPermission = false;
AclEntry[] acls = null;
if (domainObject == null) {
hasPermission = true;
} else if (!processDomainObjectClass.isAssignableFrom(domainObject.getClass())) {
hasPermission = true;
} else {
AclEntry[] acls = aclManager.getAcls(domainObject, authentication);
acls = aclManager.getAcls(domainObject, authentication);
}
if ((acls != null) && (acls.length != 0)) {
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
if ((acls != null) && (acls.length != 0)) {
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
// See if principal has any of the required permissions
for (int y = 0; y < requirePermission.length; y++) {
if (processableAcl.isPermitted(requirePermission[y])) {
hasPermission = true;
// See if principal has any of the required permissions
for (int y = 0; y < requirePermission.length; y++) {
if (processableAcl.isPermitted(requirePermission[y])) {
hasPermission = true;
if (logger.isDebugEnabled()) {
logger.debug("Principal is authorised for element: " + domainObject
+ " due to ACL: " + processableAcl.toString());
}
if (logger.isDebugEnabled()) {
logger.debug("Principal is authorised for element: " + domainObject
+ " due to ACL: " + processableAcl.toString());
}
}
}
}
}
}
if (!hasPermission) {
filterer.remove(domainObject);
if (!hasPermission) {
filterer.remove(domainObject);
if (logger.isDebugEnabled()) {
logger.debug("Principal is NOT authorised for element: " + domainObject);
}
if (logger.isDebugEnabled()) {
logger.debug("Principal is NOT authorised for element: " + domainObject);
}
}
}
@@ -202,18 +211,6 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements
this.requirePermission = requirePermission;
}
/**
* Allow setting permissions with String literals instead of integers as {@link
* #setRequirePermission(int[])}
*
* @param requiredPermissions permission literals
*
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
*/
public void setRequirePermissionFromString(String[] requiredPermissions) {
setRequirePermission(SimpleAclEntry.parsePermissions(requiredPermissions));
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
return true;
@@ -233,3 +230,179 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements
return true;
}
}
/**
* Filter strategy interface.
*/
interface Filterer {
//~ Methods ========================================================================================================
/**
* Gets the filtered collection or array.
*
* @return the filtered collection or array
*/
public Object getFilteredObject();
/**
* Returns an iterator over the filtered collection or array.
*
* @return an Iterator
*/
public Iterator iterator();
/**
* Removes the the given object from the resulting list.
*
* @param object the object to be removed
*/
public void remove(Object object);
}
/**
* A filter used to filter Collections.
*/
class CollectionFilterer implements Filterer {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
//~ Instance fields ================================================================================================
private Collection collection;
// collectionIter offers significant performance optimisations (as
// per acegisecurity-developer mailing list conversation 19/5/05)
private Iterator collectionIter;
private Set removeList;
//~ Constructors ===================================================================================================
CollectionFilterer(Collection collection) {
this.collection = collection;
// We create a Set of objects to be removed from the Collection,
// as ConcurrentModificationException prevents removal during
// iteration, and making a new Collection to be returned is
// problematic as the original Collection implementation passed
// to the method may not necessarily be re-constructable (as
// the Collection(collection) constructor is not guaranteed and
// manually adding may lose sort order or other capabilities)
removeList = new HashSet();
}
//~ Methods ========================================================================================================
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
*/
public Object getFilteredObject() {
// Now the Iterator has ended, remove Objects from Collection
Iterator removeIter = removeList.iterator();
int originalSize = collection.size();
while (removeIter.hasNext()) {
collection.remove(removeIter.next());
}
if (logger.isDebugEnabled()) {
logger.debug("Original collection contained " + originalSize + " elements; now contains "
+ collection.size() + " elements");
}
return collection;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
*/
public Iterator iterator() {
collectionIter = collection.iterator();
return collectionIter;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
*/
public void remove(Object object) {
collectionIter.remove();
}
}
/**
* A filter used to filter arrays.
*/
class ArrayFilterer implements Filterer {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
//~ Instance fields ================================================================================================
private Set removeList;
private Object[] list;
//~ Constructors ===================================================================================================
ArrayFilterer(Object[] list) {
this.list = list;
// Collect the removed objects to a HashSet so that
// it is fast to lookup them when a filtered array
// is constructed.
removeList = new HashSet();
}
//~ Methods ========================================================================================================
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
*/
public Object getFilteredObject() {
// Recreate an array of same type and filter the removed objects.
int originalSize = list.length;
int sizeOfResultingList = originalSize - removeList.size();
Object[] filtered = (Object[]) Array.newInstance(list.getClass().getComponentType(), sizeOfResultingList);
for (int i = 0, j = 0; i < list.length; i++) {
Object object = list[i];
if (!removeList.contains(object)) {
filtered[j] = object;
j++;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Original array contained " + originalSize + " elements; now contains " + sizeOfResultingList
+ " elements");
}
return filtered;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
*/
public Iterator iterator() {
return new ArrayIterator(list);
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
*/
public void remove(Object object) {
removeList.add(object);
}
}
@@ -33,13 +33,13 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.util.Iterator;
/**
* <p>Given a domain object instance returned from a secure object invocation, ensures the principal has
* appropriate permission as defined by the {@link AclManager}.</p>
@@ -121,7 +121,7 @@ public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProv
throw new AccessDeniedException(messages.getMessage(
"BasicAclEntryAfterInvocationProvider.noPermission",
new Object[] {authentication.getName(), returnedObject},
"Authentication {0} has NO permissions at all to the domain object {1}", LocaleContextHolder.getLocale()));
"Authentication {0} has NO permissions at all to the domain object {1}"));
}
for (int i = 0; i < acls.length; i++) {
@@ -147,8 +147,7 @@ public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProv
throw new AccessDeniedException(messages.getMessage(
"BasicAclEntryAfterInvocationProvider.insufficientPermission",
new Object[] {authentication.getName(), returnedObject},
"Authentication {0} has ACL permissions to the domain object, "
+ "but not the required ACL permission to the domain object {1}", LocaleContextHolder.getLocale()));
"Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}"));
}
}
@@ -188,16 +187,6 @@ public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProv
this.requirePermission = requirePermission;
}
/**
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
*
* @param requiredPermissions Permission literals
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
*/
public void setRequirePermissionFromString(String[] requiredPermissions) {
setRequirePermission(SimpleAclEntry.parsePermissions(requiredPermissions));
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
return true;
@@ -1,104 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.afterinvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* A filter used to filter Collections.
*
* @author Ben Alex
* @author Paulo Neves
* @version $Id$
*/
class CollectionFilterer implements Filterer {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(CollectionFilterer.class);
//~ Instance fields ================================================================================================
private Collection collection;
// collectionIter offers significant performance optimisations (as
// per acegisecurity-developer mailing list conversation 19/5/05)
private Iterator collectionIter;
private Set removeList;
//~ Constructors ===================================================================================================
CollectionFilterer(Collection collection) {
this.collection = collection;
// We create a Set of objects to be removed from the Collection,
// as ConcurrentModificationException prevents removal during
// iteration, and making a new Collection to be returned is
// problematic as the original Collection implementation passed
// to the method may not necessarily be re-constructable (as
// the Collection(collection) constructor is not guaranteed and
// manually adding may lose sort order or other capabilities)
removeList = new HashSet();
}
//~ Methods ========================================================================================================
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject()
*/
public Object getFilteredObject() {
// Now the Iterator has ended, remove Objects from Collection
Iterator removeIter = removeList.iterator();
int originalSize = collection.size();
while (removeIter.hasNext()) {
collection.remove(removeIter.next());
}
if (logger.isDebugEnabled()) {
logger.debug("Original collection contained " + originalSize + " elements; now contains "
+ collection.size() + " elements");
}
return collection;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#iterator()
*/
public Iterator iterator() {
collectionIter = collection.iterator();
return collectionIter;
}
/**
*
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
*/
public void remove(Object object) {
removeList.add(object);
}
}
@@ -44,15 +44,11 @@ import javax.servlet.http.HttpServletResponse;
/**
* The captcha entry point : redirect to the captcha test page.
* <p>
* This entry point can force the use of SSL : see {@link #getForceHttps()}
* </p>
* <p>
* This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br />
* / Original request can be added to the redirect path using a custom translation : see
* {@link #setIncludeOriginalRequest(boolean)}<br />
* The original request is translated using URLEncoding and the following translation mapping in the redirect url :
* The captcha entry point : redirect to the captcha test page. <br><p>This entry point can force the use of SSL :
* see {@link #getForceHttps()}<br></p>
* This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}<br>
* / Original request can be added to the redirect path using a custom translation : see {@link #setIncludeOriginalRequest(boolean)}<br>
* Original request is translated using URLEncoding and the following translation mapping in the redirect url :
* <ul>
* <li>original url => {@link #getOriginalRequestUrlParameterName()}</li>
* <li>If {@link #isIncludeOriginalParameters()}</li>
@@ -67,20 +63,17 @@ import javax.servlet.http.HttpServletResponse;
* </li>
* </ul>
* <br><br>
* Default values :
* <pre>
* forceHttps = false
* includesOriginalRequest = true
* includesOriginalParameters = false
* isOutsideWebApp = false
* originalRequestUrlParameterName = original_requestUrl
* originalRequestParametersParameterName = original_request_parameters
* originalRequestParametersNameValueSeparator = __
* originalRequestParametersSeparator = ;;
* originalRequestMethodParameterName = original_request_method
* urlEncodingCharset = UTF-8
* </pre>
* </p>
* Default values :<br>
* forceHttps = false<br>
* includesOriginalRequest = true<br>
* includesOriginalParameters = false<br>
* isOutsideWebApp=false<br>
* originalRequestUrlParameterName =original_requestUrl <br>
* originalRequestParametersParameterName = original_request_parameters<br>
* originalRequestParametersNameValueSeparator = __ <br>
* originalRequestParametersSeparator = ;; <br>
* originalRequestMethodParameterName = original_request_method <br>
* urlEncodingCharset = UTF-8<br>
*
* @author marc antoine Garrigue
* @version $Id$
@@ -88,6 +81,8 @@ import javax.servlet.http.HttpServletResponse;
public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean {
//~ Static fields/initializers =====================================================================================
// ~ Static fields/initializers
// =============================================
private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class);
//~ Instance fields ================================================================================================
@@ -44,10 +44,14 @@ import javax.servlet.http.HttpSession;
public class CaptchaValidationProcessingFilter implements InitializingBean, Filter {
//~ Static fields/initializers =====================================================================================
// ~ Static fields/initializers
// =============================================
protected static final Log logger = LogFactory.getLog(CaptchaValidationProcessingFilter.class);
//~ Instance fields ================================================================================================
// ~ Instance fields
// ========================================================
private CaptchaServiceProxy captchaService;
private String captchaValidationParameter = "_captcha_parameter";
@@ -70,9 +74,9 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, Filt
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String captchaResponse = request.getParameter(captchaValidationParameter);
String captcha_reponse = request.getParameter(captchaValidationParameter);
if ((request != null) && request instanceof HttpServletRequest && (captchaResponse != null)) {
if ((request != null) && request instanceof HttpServletRequest && (captcha_reponse != null)) {
logger.debug("captcha validation parameter found");
// validate the request against CaptchaServiceProxy
@@ -85,7 +89,7 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, Filt
if (session != null) {
String id = session.getId();
valid = this.captchaService.validateReponseForId(id, captchaResponse);
valid = this.captchaService.validateReponseForId(id, captcha_reponse);
logger.debug("captchaServiceProxy says : request is valid = " + valid);
if (valid) {
@@ -110,6 +114,8 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, Filt
chain.doFilter(request, response);
}
// ~ Methods
// ================================================================
public CaptchaServiceProxy getCaptchaService() {
return captchaService;
}
@@ -41,7 +41,7 @@ public interface ConcurrentSessionController {
*
* @throws AuthenticationException if the user has exceeded their maximum allowed current sessions
*/
void checkAuthenticationAllowed(Authentication request)
public void checkAuthenticationAllowed(Authentication request)
throws AuthenticationException;
/**
@@ -51,5 +51,5 @@ public interface ConcurrentSessionController {
*
* @param authentication the successfully authenticated user (never <code>null</code>)
*/
void registerSuccessfulAuthentication(Authentication authentication);
public void registerSuccessfulAuthentication(Authentication authentication);
}
@@ -67,16 +67,14 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
SessionRegistry registry) {
if (exceptionIfMaximumExceeded || (sessions == null)) {
throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed",
new Object[] {new Integer(allowableSessions)},
"Maximum sessions of {0} for this principal exceeded"));
new Object[] {new Integer(allowableSessions)}, "Maximum sessions of {0} for this principal exceeded"));
}
// Determine least recently used session, and mark it for invalidation
SessionInformation leastRecentlyUsed = null;
for (int i = 0; i < sessions.length; i++) {
if ((leastRecentlyUsed == null)
|| sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
if ((leastRecentlyUsed == null) || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
leastRecentlyUsed = sessions[i];
}
}
@@ -100,8 +98,8 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
}
int allowableSessions = getMaximumSessionsForThisUser(request);
Assert.isTrue(allowableSessions != 0, "getMaximumSessionsForThisUser() must return either -1 to allow "
+ "unlimited logins, or a positive integer to specify a maximum");
Assert.isTrue(allowableSessions != 0,
"getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
if (sessionCount < allowableSessions) {
// They haven't got too many login sessions running at present
@@ -140,6 +138,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
Object principal = SessionRegistryUtils.obtainPrincipalFromAuthentication(authentication);
String sessionId = SessionRegistryUtils.obtainSessionIdFromAuthentication(authentication);
sessionRegistry.removeSessionInformation(sessionId);
sessionRegistry.registerNewSession(sessionId, principal);
}
@@ -18,7 +18,7 @@ package org.acegisecurity.concurrent;
/**
* Implemented by {@link org.acegisecurity.Authentication#getDetails()}
* implementations that are capable of returning a session ID.
*
*
* <p>
* This interface is used by {@link
* org.acegisecurity.concurrent.SessionRegistryUtils} to extract the session
@@ -40,5 +40,5 @@ public interface SessionIdentifierAware {
*
* @return the session ID, or <code>null</code> if not known.
*/
String getSessionId();
public String getSessionId();
}
@@ -29,7 +29,7 @@ public interface SessionRegistry {
*
* @return each of the unique principals, which can then be presented to {@link #getAllSessions(Object, boolean)}.
*/
Object[] getAllPrincipals();
public Object[] getAllPrincipals();
/**
* Obtains all the known sessions for the specified principal. Sessions that have been destroyed are not
@@ -41,7 +41,7 @@ public interface SessionRegistry {
*
* @return the matching sessions for this principal, or <code>null</code> if none were found
*/
SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions);
public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions);
/**
* Obtains the session information for the specified <code>sessionId</code>. Even expired sessions are
@@ -51,7 +51,7 @@ public interface SessionRegistry {
*
* @return the session information, or <code>null</code> if not found
*/
SessionInformation getSessionInformation(String sessionId);
public SessionInformation getSessionInformation(String sessionId);
/**
* Updates the given <code>sessionId</code> so its last request time is equal to the present date and time.
@@ -59,7 +59,7 @@ public interface SessionRegistry {
*
* @param sessionId for which to update the date and time of the last request (should never be <code>null</code>)
*/
void refreshLastRequest(String sessionId);
public void refreshLastRequest(String sessionId);
/**
* Registers a new session for the specified principal. The newly registered session will not be marked for
@@ -70,7 +70,7 @@ public interface SessionRegistry {
*
* @throws SessionAlreadyUsedException DOCUMENT ME!
*/
void registerNewSession(String sessionId, Object principal)
public void registerNewSession(String sessionId, Object principal)
throws SessionAlreadyUsedException;
/**
@@ -79,5 +79,5 @@ public interface SessionRegistry {
*
* @param sessionId to delete information for (should never be <code>null</code>)
*/
void removeSessionInformation(String sessionId);
public void removeSessionInformation(String sessionId);
}
@@ -112,12 +112,14 @@ public class SessionRegistryImpl implements SessionRegistry,
}
}
public synchronized void registerNewSession(String sessionId, Object principal) {
public void registerNewSession(String sessionId, Object principal)
throws SessionAlreadyUsedException {
Assert.hasText(sessionId, "SessionId required as per interface contract");
Assert.notNull(principal, "Principal required as per interface contract");
if (getSessionInformation(sessionId) != null) {
removeSessionInformation(sessionId);
throw new SessionAlreadyUsedException("Session " + sessionId
+ " is already is use");
}
sessionIds.put(sessionId,
@@ -28,12 +28,7 @@ import org.springframework.util.Assert;
* @author Ben Alex
* @version $Id$
*/
public final class SessionRegistryUtils {
//~ Constructors ===================================================================================================
private SessionRegistryUtils() {
}
public class SessionRegistryUtils {
//~ Methods ========================================================================================================
public static Object obtainPrincipalFromAuthentication(Authentication auth) {
@@ -15,8 +15,12 @@
package org.acegisecurity.context;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -27,389 +31,271 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Populates the {@link SecurityContextHolder} with information obtained from
* the <code>HttpSession</code>.
*
* <p>
* The <code>HttpSession</code> will be queried to retrieve the
* <code>SecurityContext</code> that should be stored against the
* <code>SecurityContextHolder</code> for the duration of the web request. At
* the end of the web request, any updates made to the
* <code>SecurityContextHolder</code> will be persisted back to the
* <code>HttpSession</code> by this filter.
* </p>
* <p>
* If a valid <code>SecurityContext</code> cannot be obtained from the
* <code>HttpSession</code> for whatever reason, a fresh
* <code>SecurityContext</code> will be created and used instead. The created
* object will be of the instance defined by the {@link #setContext(Class)}
* method (which defaults to {@link
* org.acegisecurity.context.SecurityContextImpl}.
* </p>
* <p>
* No <code>HttpSession</code> will be created by this filter if one does not
* already exist. If at the end of the web request the <code>HttpSession</code>
* does not exist, a <code>HttpSession</code> will <b>only</b> be created if
* the current contents of the <code>SecurityContextHolder</code> are not
* {@link java.lang.Object#equals(java.lang.Object)} to a <code>new</code>
* instance of {@link #setContext(Class)}. This avoids needless
* <code>HttpSession</code> creation, but automates the storage of changes
* made to the <code>SecurityContextHolder</code>. There is one exception to
* this rule, that is if the {@link #forceEagerSessionCreation} property is
* <code>true</code>, in which case sessions will always be created
* irrespective of normal session-minimisation logic (the default is
* <code>false</code>, as this is resource intensive and not recommended).
* </p>
* <p>
* This filter will only execute once per request, to resolve servlet container
* (specifically Weblogic) incompatibilities.
* </p>
* <p>
* If for whatever reason no <code>HttpSession</code> should <b>ever</b> be
* created (eg this filter is only being used with Basic authentication or
* similar clients that will never present the same <code>jsessionid</code>
* etc), the {@link #setAllowSessionCreation(boolean)} should be set to
* <code>false</code>. Only do this if you really need to conserve server
* memory and ensure all classes using the <code>SecurityContextHolder</code>
* are designed to have no persistence of the <code>SecurityContext</code>
* between web requests. Please note that if {@link #forceEagerSessionCreation}
* is <code>true</code>, the <code>allowSessionCreation</code> must also be
* <code>true</code> (setting it to <code>false</code> will cause a startup
* time error).
* </p>
* <p>
* This filter MUST be executed BEFORE any authentication processing mechanisms.
* Authentication processing mechanisms (eg BASIC, CAS processing filters etc)
* expect the <code>SecurityContextHolder</code> to contain a valid
* <code>SecurityContext</code> by the time they execute.
* </p>
*
* <p>Populates the {@link SecurityContextHolder} with information obtained from the <code>HttpSession</code>.</p>
* <p>The <code>HttpSession</code> will be queried to retrieve the <code>SecurityContext</code> that should be
* stored against the <code>SecurityContextHolder</code> for the duration of the web request. At the end of the web
* request, any updates made to the <code>SecurityContextHolder</code> will be persisted back to the
* <code>HttpSession</code> by this filter.</p>
* <p>If a valid <code>SecurityContext</code> cannot be obtained from the <code>HttpSession</code> for whatever
* reason, a fresh <code>SecurityContext</code> will be created and used instead. The created object will be of the
* instance defined by the {@link #setContext(Class)} method (which defaults to {@link
* org.acegisecurity.context.SecurityContextImpl}.</p>
* <p>No <code>HttpSession</code> will be created by this filter if one does not already exist. If at the end of
* the web request the <code>HttpSession</code> does not exist, a <code>HttpSession</code> will <b>only</b> be created
* if the current contents of the <code>SecurityContextHolder</code> are not {@link
* java.lang.Object#equals(java.lang.Object)} to a <code>new</code> instance of {@link #setContext(Class)}. This
* avoids needless <code>HttpSession</code> creation, but automates the storage of changes made to the
* <code>SecurityContextHolder</code>. There is one exception to this rule, that is if the {@link
* #forceEagerSessionCreation} property is <code>true</code>, in which case sessions will always be created
* irrespective of normal session-minimisation logic (the default is <code>false</code>, as this is resource intensive
* and not recommended).</p>
* <p>This filter will only execute once per request, to resolve servlet container (specifically Weblogic)
* incompatibilities.</p>
* <p>If for whatever reason no <code>HttpSession</code> should <b>ever</b> be created (eg this filter is only
* being used with Basic authentication or similar clients that will never present the same <code>jsessionid</code>
* etc), the {@link #setAllowSessionCreation(boolean)} should be set to <code>false</code>. Only do this if you really
* need to conserve server memory and ensure all classes using the <code>SecurityContextHolder</code> are designed to
* have no persistence of the <code>SecurityContext</code> between web requests. Please note that if {@link
* #forceEagerSessionCreation} is <code>true</code>, the <code>allowSessionCreation</code> must also be
* <code>true</code> (setting it to <code>false</code> will cause a startup time error).</p>
* <p>This filter MUST be executed BEFORE any authentication processing mechanisms. Authentication processing
* mechanisms (eg BASIC, CAS processing filters etc) expect the <code>SecurityContextHolder</code> to contain a valid
* <code>SecurityContext</code> by the time they execute.</p>
*
* @author Ben Alex
* @author Patrick Burleson
* @version $Id: HttpSessionContextIntegrationFilter.java 1784 2007-02-24
* 21:00:24Z luke_t $
* @version $Id$
*/
public class HttpSessionContextIntegrationFilter implements InitializingBean, Filter {
// ~ Static fields/initializers
// =====================================================================================
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(HttpSessionContextIntegrationFilter.class);
protected static final Log logger = LogFactory.getLog(HttpSessionContextIntegrationFilter.class);
private static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";
public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT";
static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";
//~ Instance fields ================================================================================================
public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT";
private Class context = SecurityContextImpl.class;
private Object contextObject;
// ~ Instance fields
// ================================================================================================
/**
* Indicates if this filter can create a <code>HttpSession</code> if needed (sessions are always created
* sparingly, but setting this value to <code>false</code> will prohibit sessions from ever being created).
* Defaults to <code>true</code>. Do not set to <code>false</code> if you are have set {@link
* #forceEagerSessionCreation} to <code>true</code>, as the properties would be in conflict.
*/
private boolean allowSessionCreation = true;
private Class context = SecurityContextImpl.class;
/**
* Indicates if this filter is required to create a <code>HttpSession</code> for every request before
* proceeding through the filter chain, even if the <code>HttpSession</code> would not ordinarily have been
* created. By default this is <code>false</code>, which is entirely appropriate for most circumstances as you do
* not want a <code>HttpSession</code> created unless the filter actually needs one. It is envisaged the main
* situation in which this property would be set to <code>true</code> is if using other filters that depend on a
* <code>HttpSession</code> already existing, such as those which need to obtain a session ID. This is only
* required in specialised cases, so leave it set to <code>false</code> unless you have an actual requirement and
* are conscious of the session creation overhead.
*/
private boolean forceEagerSessionCreation = false;
private Object contextObject;
//~ Methods ========================================================================================================
/**
* Indicates if this filter can create a <code>HttpSession</code> if
* needed (sessions are always created sparingly, but setting this value to
* <code>false</code> will prohibit sessions from ever being created).
* Defaults to <code>true</code>. Do not set to <code>false</code> if
* you are have set {@link #forceEagerSessionCreation} to <code>true</code>,
* as the properties would be in conflict.
*/
private boolean allowSessionCreation = true;
public void afterPropertiesSet() throws Exception {
if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) {
throw new IllegalArgumentException(
"context must be defined and implement SecurityContext (typically use org.acegisecurity.context.SecurityContextImpl; existing class is "
+ this.context + ")");
}
/**
* Indicates if this filter is required to create a <code>HttpSession</code>
* for every request before proceeding through the filter chain, even if the
* <code>HttpSession</code> would not ordinarily have been created. By
* default this is <code>false</code>, which is entirely appropriate for
* most circumstances as you do not want a <code>HttpSession</code>
* created unless the filter actually needs one. It is envisaged the main
* situation in which this property would be set to <code>true</code> is
* if using other filters that depend on a <code>HttpSession</code>
* already existing, such as those which need to obtain a session ID. This
* is only required in specialised cases, so leave it set to
* <code>false</code> unless you have an actual requirement and are
* conscious of the session creation overhead.
*/
private boolean forceEagerSessionCreation = false;
if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) {
throw new IllegalArgumentException(
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
}
/**
* Indicates whether the <code>SecurityContext</code> will be cloned from
* the <code>HttpSession</code>. The default is to simply reference (ie
* the default is <code>false</code>). The default may cause issues if
* concurrent threads need to have a different security identity from other
* threads being concurrently processed that share the same
* <code>HttpSession</code>. In most normal environments this does not
* represent an issue, as changes to the security identity in one thread is
* allowed to affect the security identitiy in other threads associated with
* the same <code>HttpSession</code>. For unusual cases where this is not
* permitted, change this value to <code>true</code> and ensure the
* {@link #context} is set to a <code>SecurityContext</code> that
* implements {@link Cloneable} and overrides the <code>clone()</code>
* method.
*/
private boolean cloneFromHttpSession = false;
this.contextObject = generateNewContext();
}
public boolean isCloneFromHttpSession() {
return cloneFromHttpSession;
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*/
public void destroy() {}
public void setCloneFromHttpSession(boolean cloneFromHttpSession) {
this.cloneFromHttpSession = cloneFromHttpSession;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
} else {
if (request != null) {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
public HttpSessionContextIntegrationFilter() throws ServletException {
this.contextObject = generateNewContext();
}
HttpSession httpSession = null;
boolean httpSessionExistedAtStartOfRequest = false;
// ~ Methods
// ========================================================================================================
try {
httpSession = ((HttpServletRequest) request).getSession(forceEagerSessionCreation);
} catch (IllegalStateException ignored) {}
public void afterPropertiesSet() throws Exception {
if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) {
throw new IllegalArgumentException("context must be defined and implement SecurityContext "
+ "(typically use org.acegisecurity.context.SecurityContextImpl; existing class is " + this.context
+ ")");
}
if (httpSession != null) {
httpSessionExistedAtStartOfRequest = true;
if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) {
throw new IllegalArgumentException(
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
}
}
Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);
/**
* Does nothing. We use IoC container lifecycle services instead.
*/
public void destroy() {
}
if (contextFromSessionObject != null) {
if (contextFromSessionObject instanceof SecurityContext) {
if (logger.isDebugEnabled()) {
logger.debug(
"Obtained from ACEGI_SECURITY_CONTEXT a valid SecurityContext and set to SecurityContextHolder: '"
+ contextFromSessionObject + "'");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
boolean filterApplied = false;
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
}
else {
if (request != null) {
filterApplied = true;
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
} else {
if (logger.isWarnEnabled()) {
logger.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
+ contextFromSessionObject
+ "'; are you improperly modifying the HttpSession directly (you should always use SecurityContextHolder) or using the HttpSession attribute reserved for this class? - new SecurityContext instance associated with SecurityContextHolder");
}
HttpSession httpSession = null;
boolean httpSessionExistedAtStartOfRequest = false;
SecurityContextHolder.setContext(generateNewContext());
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession returned null object for ACEGI_SECURITY_CONTEXT - new SecurityContext instance associated with SecurityContextHolder");
}
try {
httpSession = ((HttpServletRequest) request).getSession(forceEagerSessionCreation);
}
catch (IllegalStateException ignored) {
}
SecurityContextHolder.setContext(generateNewContext());
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"No HttpSession currently exists - new SecurityContext instance associated with SecurityContextHolder");
}
if (httpSession != null) {
httpSessionExistedAtStartOfRequest = true;
SecurityContextHolder.setContext(generateNewContext());
}
Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);
// Make the HttpSession null, as we want to ensure we don't keep
// a reference to the HttpSession laying around in case the
// chain.doFilter() invalidates it.
httpSession = null;
if (contextFromSessionObject != null) {
// Clone if required (see SEC-356)
if (cloneFromHttpSession) {
Assert.isInstanceOf(Cloneable.class, contextFromSessionObject,
"Context must implement Clonable and provide a Object.clone() method");
try {
Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {});
if (!m.isAccessible()) {
m.setAccessible(true);
}
contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {});
}
catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
}
}
// Proceed with chain
int contextWhenChainProceeded = SecurityContextHolder.getContext().hashCode();
if (contextFromSessionObject instanceof SecurityContext) {
if (logger.isDebugEnabled()) {
logger.debug("Obtained from ACEGI_SECURITY_CONTEXT a valid SecurityContext and "
+ "set to SecurityContextHolder: '" + contextFromSessionObject + "'");
}
try {
chain.doFilter(request, response);
} catch (IOException ioe) {
throw ioe;
} catch (ServletException se) {
throw se;
} finally {
// do clean up, even if there was an exception
// Store context back to HttpSession
try {
httpSession = ((HttpServletRequest) request).getSession(false);
} catch (IllegalStateException ignored) {}
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
}
else {
if (logger.isWarnEnabled()) {
logger
.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
+ contextFromSessionObject
+ "'; are you improperly modifying the HttpSession directly "
+ "(you should always use SecurityContextHolder) or using the HttpSession attribute "
+ "reserved for this class? - new SecurityContext instance associated with "
+ "SecurityContextHolder");
}
if ((httpSession == null) && httpSessionExistedAtStartOfRequest) {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession is now null, but was not null at start of request; session was invalidated, so do not create a new session");
}
}
SecurityContextHolder.setContext(generateNewContext());
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("HttpSession returned null object for ACEGI_SECURITY_CONTEXT - new "
+ "SecurityContext instance associated with SecurityContextHolder");
}
// Generate a HttpSession only if we need to
if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) {
if (!allowSessionCreation) {
if (logger.isDebugEnabled()) {
logger.debug(
"The HttpSession is currently null, and the HttpSessionContextIntegrationFilter is prohibited from creating a HttpSession (because the allowSessionCreation property is false) - SecurityContext thus not stored for next request");
}
} else if (!contextObject.equals(SecurityContextHolder.getContext())) {
if (logger.isDebugEnabled()) {
logger.debug("HttpSession being created as SecurityContextHolder contents are non-default");
}
SecurityContextHolder.setContext(generateNewContext());
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("No HttpSession currently exists - new SecurityContext instance "
+ "associated with SecurityContextHolder");
}
try {
httpSession = ((HttpServletRequest) request).getSession(true);
} catch (IllegalStateException ignored) {}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession is null, but SecurityContextHolder has not changed from default: ' "
+ SecurityContextHolder.getContext()
+ "'; not creating HttpSession or storing SecurityContextHolder contents");
}
}
}
SecurityContextHolder.setContext(generateNewContext());
}
// If HttpSession exists, store current SecurityContextHolder
// contents
// but only if SecurityContext has actually changed (see JIRA
// SEC-37)
if ((httpSession != null)
&& (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) {
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
// Make the HttpSession null, as we want to ensure we don't keep
// a reference to the HttpSession laying around in case the
// chain.doFilter() invalidates it.
httpSession = null;
if (logger.isDebugEnabled()) {
logger.debug("SecurityContext stored to HttpSession: '" + SecurityContextHolder.getContext()
+ "'");
}
}
// Proceed with chain
int contextWhenChainProceeded = SecurityContextHolder.getContext().hashCode();
// Remove SecurityContextHolder contents
SecurityContextHolder.clearContext();
try {
chain.doFilter(request, response);
}
catch (IOException ioe) {
throw ioe;
}
catch (ServletException se) {
throw se;
}
finally {
// do clean up, even if there was an exception
// Store context back to HttpSession
try {
httpSession = ((HttpServletRequest) request).getSession(false);
}
catch (IllegalStateException ignored) {
}
if (logger.isDebugEnabled()) {
logger.debug("SecurityContextHolder set to new context, as request processing completed");
}
}
}
}
if ((httpSession == null) && httpSessionExistedAtStartOfRequest) {
if (logger.isDebugEnabled()) {
logger.debug("HttpSession is now null, but was not null at start of request; "
+ "session was invalidated, so do not create a new session");
}
}
public SecurityContext generateNewContext() throws ServletException {
try {
return (SecurityContext) this.context.newInstance();
} catch (InstantiationException ie) {
throw new ServletException(ie);
} catch (IllegalAccessException iae) {
throw new ServletException(iae);
}
}
// Generate a HttpSession only if we need to
if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) {
if (!allowSessionCreation) {
if (logger.isDebugEnabled()) {
logger
.debug("The HttpSession is currently null, and the "
+ "HttpSessionContextIntegrationFilter is prohibited from creating an HttpSession "
+ "(because the allowSessionCreation property is false) - SecurityContext thus not "
+ "stored for next request");
}
}
else if (!contextObject.equals(SecurityContextHolder.getContext())) {
if (logger.isDebugEnabled()) {
logger.debug("HttpSession being created as SecurityContextHolder contents are non-default");
}
public Class getContext() {
return context;
}
try {
httpSession = ((HttpServletRequest) request).getSession(true);
}
catch (IllegalStateException ignored) {
}
}
else {
if (logger.isDebugEnabled()) {
logger
.debug("HttpSession is null, but SecurityContextHolder has not changed from default: ' "
+ SecurityContextHolder.getContext()
+ "'; not creating HttpSession or storing SecurityContextHolder contents");
}
}
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param filterConfig ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig filterConfig) throws ServletException {}
// If HttpSession exists, store current
// SecurityContextHolder contents but only if
// SecurityContext has
// actually changed (see JIRA SEC-37)
if ((httpSession != null)
&& (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) {
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
public boolean isAllowSessionCreation() {
return allowSessionCreation;
}
if (logger.isDebugEnabled()) {
logger.debug("SecurityContext stored to HttpSession: '" + SecurityContextHolder.getContext()
+ "'");
}
}
public boolean isForceEagerSessionCreation() {
return forceEagerSessionCreation;
}
if (filterApplied) {
request.removeAttribute(FILTER_APPLIED);
}
// Remove SecurityContextHolder contents
SecurityContextHolder.clearContext();
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
if (logger.isDebugEnabled()) {
logger.debug("SecurityContextHolder set to new context, as request processing completed");
}
}
}
}
public void setContext(Class secureContext) {
this.context = secureContext;
}
public SecurityContext generateNewContext() throws ServletException {
try {
return (SecurityContext) this.context.newInstance();
}
catch (InstantiationException ie) {
throw new ServletException(ie);
}
catch (IllegalAccessException iae) {
throw new ServletException(iae);
}
}
public Class getContext() {
return context;
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param filterConfig ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig filterConfig) throws ServletException {
}
public boolean isAllowSessionCreation() {
return allowSessionCreation;
}
public boolean isForceEagerSessionCreation() {
return forceEagerSessionCreation;
}
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
public void setContext(Class secureContext) {
this.context = secureContext;
}
public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
this.forceEagerSessionCreation = forceEagerSessionCreation;
}
public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
this.forceEagerSessionCreation = forceEagerSessionCreation;
}
}
@@ -23,7 +23,7 @@ import java.io.Serializable;
/**
* Interface defining the minimum security information associated with the
* current thread of execution.
*
*
* <p>
* The security context is stored in a {@link SecurityContextHolder}.
* </p>
@@ -39,7 +39,7 @@ public interface SecurityContext extends Serializable {
*
* @return the <code>Authentication</code> or <code>null</code> if no authentication information is available
*/
Authentication getAuthentication();
public Authentication getAuthentication();
/**
* Changes the currently authenticated principal, or removes the authentication information.
@@ -47,5 +47,5 @@ public interface SecurityContext extends Serializable {
* @param authentication the new <code>Authentication</code> token, or <code>null</code> if no further
* authentication information should be stored
*/
void setAuthentication(Authentication authentication);
public void setAuthentication(Authentication authentication);
}
@@ -17,7 +17,7 @@ package org.acegisecurity.context;
/**
* A strategy for storing security context information against a thread.
*
*
* <p>
* The preferred strategy is loaded by {@link
* org.acegisecurity.context.SecurityContextHolder}.
@@ -32,14 +32,14 @@ public interface SecurityContextHolderStrategy {
/**
* Clears the current context.
*/
void clearContext();
public void clearContext();
/**
* Obtains the current context.
*
* @return a context (never <code>null</code> - create a default implementation if necessary)
*/
SecurityContext getContext();
public SecurityContext getContext();
/**
* Sets the current context.
@@ -47,5 +47,5 @@ public interface SecurityContextHolderStrategy {
* @param context to the new argument (should never be <code>null</code>, although implementations must check if
* <code>null</code> has been passed and throw an <code>IllegalArgumentException</code> in such cases)
*/
void setContext(SecurityContext context);
public void setContext(SecurityContext context);
}
@@ -85,8 +85,9 @@ public class AuthenticationSimpleHttpInvokerRequestExecutor extends SimpleHttpIn
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Unable to set BASIC authentication header as SecurityContext did not provide "
+ "valid Authentication: " + auth);
logger.debug(
"Unable to set BASIC authentication header as SecurityContext did not provide valid Authentication: "
+ auth);
}
}
@@ -17,8 +17,10 @@ package org.acegisecurity.event.authentication;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.util.ClassUtils;
@@ -33,19 +35,12 @@ public class LoggerListener implements ApplicationListener {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(LoggerListener.class);
/** If set to true, {@link InteractiveAuthenticationSuccessEvent} will be logged (defaults to true) */
private boolean logInteractiveAuthenticationSuccessEvents = true;
//~ Methods ========================================================================================================
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof AbstractAuthenticationEvent) {
AbstractAuthenticationEvent authEvent = (AbstractAuthenticationEvent) event;
if (!logInteractiveAuthenticationSuccessEvents && authEvent instanceof InteractiveAuthenticationSuccessEvent) {
return;
}
if (logger.isWarnEnabled()) {
String message = "Authentication event " + ClassUtils.getShortName(authEvent.getClass()) + ": "
@@ -61,13 +56,4 @@ public class LoggerListener implements ApplicationListener {
}
}
}
public boolean isLogInteractiveAuthenticationSuccessEvents() {
return logInteractiveAuthenticationSuccessEvents;
}
public void setLogInteractiveAuthenticationSuccessEvents(
boolean logInteractiveAuthenticationSuccessEvents) {
this.logInteractiveAuthenticationSuccessEvents = logInteractiveAuthenticationSuccessEvents;
}
}
@@ -21,12 +21,7 @@ import org.acegisecurity.ConfigAttributeDefinition;
/**
* Indicates a secure object invocation failed because the principal could not
* be authorized for the request.
*
* <p>This event might be thrown as a result of either an
* {@link org.acegisecurity.AccessDecisionManager AccessDecisionManager} or an
* {@link org.acegisecurity.AfterInvocationManager AfterInvocationManager}.
* Indicates a secure object invocation failed because the principal could not be authorized for the request.
*
* @author Ben Alex
* @version $Id$
@@ -40,7 +35,7 @@ public class AuthorizationFailureEvent extends AbstractAuthorizationEvent {
//~ Constructors ===================================================================================================
/**
/**
* Construct the event.
*
* @param secureObject the secure object
@@ -23,11 +23,8 @@ import org.springframework.context.ApplicationListener;
/**
* Outputs interceptor-related application events to Commons Logging.
* <p>
* All failures are logged at the warning level, with success events logged at the information level,
* and public invocation events logged at the debug level.
* </p>
* Outputs interceptor-related application events to Commons Logging.<P>All failures are logged at the warning
* level, with success events logged at the information level, and public invocation events logged at the debug level.</p>
*
* @author Ben Alex
* @version $Id$
@@ -55,9 +52,8 @@ public class LoggerListener implements ApplicationListener {
if (logger.isWarnEnabled()) {
logger.warn("Security authorization failed due to: " + authEvent.getAccessDeniedException()
+ "; authenticated principal: " + authEvent.getAuthentication()
+ "; secure object: " + authEvent.getSource()
+ "; configuration attributes: " + authEvent.getConfigAttributeDefinition());
+ "; authenticated principal: " + authEvent.getAuthentication() + "; secure object: "
+ authEvent.getSource() + "; configuration attributes: " + authEvent.getConfigAttributeDefinition());
}
}
@@ -41,7 +41,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
@@ -148,17 +147,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
}
if (afterInvocationManager != null) {
// Attempt after invocation handling
try {
returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(),
token.getAttr(), returnedObject);
} catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(token.getSecureObject(),
token.getAttr(), token.getAuthentication(), accessDeniedException);
publishEvent(event);
throw accessDeniedException;
}
returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(),
token.getAttr(), returnedObject);
}
return returnedObject;
@@ -194,32 +184,35 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
Iterator iter = this.obtainObjectDefinitionSource().getConfigAttributeDefinitions();
if (iter == null) {
logger.warn("Could not validate configuration attributes as the MethodDefinitionSource did not return "
+ "a ConfigAttributeDefinition Iterator");
return;
}
if (logger.isWarnEnabled()) {
logger.warn(
"Could not validate configuration attributes as the MethodDefinitionSource did not return a ConfigAttributeDefinition Iterator");
}
} else {
Set set = new HashSet();
Set unsupportedAttrs = new HashSet();
while (iter.hasNext()) {
ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter.next();
Iterator attributes = def.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter.next();
Iterator attributes = def.getConfigAttributes();
while (attributes.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) attributes.next();
while (attributes.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) attributes.next();
if (!this.runAsManager.supports(attr) && !this.accessDecisionManager.supports(attr)
&& ((this.afterInvocationManager == null) || !this.afterInvocationManager.supports(attr))) {
unsupportedAttrs.add(attr);
if (!this.runAsManager.supports(attr) && !this.accessDecisionManager.supports(attr)
&& ((this.afterInvocationManager == null) || !this.afterInvocationManager.supports(attr))) {
set.add(attr);
}
}
}
}
if (unsupportedAttrs.size() != 0) {
throw new IllegalArgumentException("Unsupported configuration attributes: " + unsupportedAttrs);
if (set.size() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Validated configuration attributes");
}
} else {
throw new IllegalArgumentException("Unsupported configuration attributes: " + set.toString());
}
}
logger.info("Validated configuration attributes");
}
}
@@ -235,96 +228,93 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object);
if (attr == null) {
if(rejectPublicInvocations) {
throw new IllegalArgumentException(
"No public invocations are allowed via this AbstractSecurityInterceptor. "
+ "This indicates a configuration error because the "
+ "AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");
if ((attr == null) && rejectPublicInvocations) {
throw new IllegalArgumentException(
"No public invocations are allowed via this AbstractSecurityInterceptor. This indicates a configuration error because the AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");
}
if (attr != null) {
if (logger.isDebugEnabled()) {
logger.debug("Secure object: " + object.toString() + "; ConfigAttributes: " + attr.toString());
}
// We check for just the property we're interested in (we do
// not call Context.validate() like the ContextInterceptor)
if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"), object, attr);
}
// Attempt authentication if not already authenticated, or user always wants reauthentication
Authentication authenticated;
if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) {
try {
authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
.getAuthentication());
} catch (AuthenticationException authenticationException) {
throw authenticationException;
}
// We don't authenticated.setAuthentication(true), because each provider should do that
if (logger.isDebugEnabled()) {
logger.debug("Successfully Authenticated: " + authenticated.toString());
}
SecurityContextHolder.getContext().setAuthentication(authenticated);
} else {
authenticated = SecurityContextHolder.getContext().getAuthentication();
if (logger.isDebugEnabled()) {
logger.debug("Previously Authenticated: " + authenticated.toString());
}
}
// Attempt authorization
try {
this.accessDecisionManager.decide(authenticated, object, attr);
} catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,
accessDeniedException);
this.eventPublisher.publishEvent(event);
throw accessDeniedException;
}
if (logger.isDebugEnabled()) {
logger.debug("Authorization successful");
}
AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);
this.eventPublisher.publishEvent(event);
// Attempt to run as a different user
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);
if (runAs == null) {
if (logger.isDebugEnabled()) {
logger.debug("RunAsManager did not change Authentication object");
}
return new InterceptorStatusToken(authenticated, false, attr, object); // no further work post-invocation
} else {
if (logger.isDebugEnabled()) {
logger.debug("Switching to RunAs Authentication: " + runAs.toString());
}
SecurityContextHolder.getContext().setAuthentication(runAs);
return new InterceptorStatusToken(authenticated, true, attr, object); // revert to token.Authenticated post-invocation
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Public object - authentication not attempted");
}
publishEvent(new PublicInvocationEvent(object));
this.eventPublisher.publishEvent(new PublicInvocationEvent(object));
return null; // no further work post-invocation
}
if (logger.isDebugEnabled()) {
logger.debug("Secure object: " + object.toString() + "; ConfigAttributes: " + attr.toString());
}
if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"), object, attr);
}
// Attempt authentication if not already authenticated, or user always wants reauthentication
Authentication authenticated;
if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) {
try {
authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
.getAuthentication());
} catch (AuthenticationException authenticationException) {
throw authenticationException;
}
// We don't authenticated.setAuthentication(true), because each provider should do that
if (logger.isDebugEnabled()) {
logger.debug("Successfully Authenticated: " + authenticated.toString());
}
SecurityContextHolder.getContext().setAuthentication(authenticated);
} else {
authenticated = SecurityContextHolder.getContext().getAuthentication();
if (logger.isDebugEnabled()) {
logger.debug("Previously Authenticated: " + authenticated.toString());
}
}
// Attempt authorization
try {
this.accessDecisionManager.decide(authenticated, object, attr);
} catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,
accessDeniedException);
publishEvent(event);
throw accessDeniedException;
}
if (logger.isDebugEnabled()) {
logger.debug("Authorization successful");
}
AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);
publishEvent(event);
// Attempt to run as a different user
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);
if (runAs == null) {
if (logger.isDebugEnabled()) {
logger.debug("RunAsManager did not change Authentication object");
}
// no further work post-invocation
return new InterceptorStatusToken(authenticated, false, attr, object);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Switching to RunAs Authentication: " + runAs.toString());
}
SecurityContextHolder.getContext().setAuthentication(runAs);
// revert to token.Authenticated post-invocation
return new InterceptorStatusToken(authenticated, true, attr, object);
}
}
/**
@@ -340,7 +330,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject,
configAttribs, exception);
publishEvent(event);
this.eventPublisher.publishEvent(event);
throw exception;
}
@@ -406,8 +396,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
this.alwaysReauthenticate = alwaysReauthenticate;
}
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void setAuthenticationManager(AuthenticationManager newManager) {
@@ -427,7 +417,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
* attempt is made to invoke a secure object that has no configuration attributes.
*
* @param rejectPublicInvocations set to <code>true</code> to reject invocations of secure objects that have no
* configuration attributes (by default it is <code>false</code> which treats undeclared secure objects as
* configuration attributes (by default it is <code>true</code> which treats undeclared secure objects as
* "public" or unauthorized)
*/
public void setRejectPublicInvocations(boolean rejectPublicInvocations) {
@@ -441,10 +431,4 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
public void setValidateConfigAttributes(boolean validateConfigAttributes) {
this.validateConfigAttributes = validateConfigAttributes;
}
private void publishEvent(ApplicationEvent event) {
if (this.eventPublisher != null) {
this.eventPublisher.publishEvent(event);
}
}
}
@@ -42,7 +42,7 @@ public interface ObjectDefinitionSource {
* @throws IllegalArgumentException if the passed object is not of a type supported by the
* <code>ObjectDefinitionSource</code> implementation
*/
ConfigAttributeDefinition getAttributes(Object object)
public ConfigAttributeDefinition getAttributes(Object object)
throws IllegalArgumentException;
/**
@@ -52,7 +52,7 @@ public interface ObjectDefinitionSource {
*
* @return an iterator over all the <code>ConfigAttributeDefinition</code>s or <code>null</code> if unsupported
*/
Iterator getConfigAttributeDefinitions();
public Iterator getConfigAttributeDefinitions();
/**
* Indicates whether the <code>ObjectDefinitionSource</code> implementation is able to provide
@@ -62,5 +62,5 @@ public interface ObjectDefinitionSource {
*
* @return true if the implementation can process the indicated class
*/
boolean supports(Class clazz);
public boolean supports(Class clazz);
}
@@ -86,7 +86,7 @@ public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource {
Method m = clazz.getDeclaredMethod(method.getName(), (Class[]) method.getParameterTypes());
addMethodAttributes(definition, m);
} catch (Exception e) {
// this won't happen since we are getting a method from an interface that
// this won't happen since we are getting a method from an interface that
// the declaring class implements
}
}
@@ -17,7 +17,6 @@ package org.acegisecurity.intercept.method;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.SecurityConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -207,8 +206,7 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
try {
// Look for the method on the current interface
Method interfaceMethod = clazz.getDeclaredMethod(method.getName(), (Class[]) method.getParameterTypes());
ConfigAttributeDefinition interfaceAssigned =
(ConfigAttributeDefinition) this.methodMap.get(interfaceMethod);
ConfigAttributeDefinition interfaceAssigned = (ConfigAttributeDefinition) this.methodMap.get(interfaceMethod);
merge(definition, interfaceAssigned);
} catch (Exception e) {
// skip this interface
@@ -234,25 +232,4 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
definition.addConfigAttribute((ConfigAttribute) attribs.next());
}
}
/**
* Easier configuration of the instance, using {@link MethodDefinitionSourceMapping}.
*
* @param mappings {@link List} of {@link MethodDefinitionSourceMapping} objects.
*/
public void setMappings(List mappings) {
Iterator it = mappings.iterator();
while (it.hasNext()) {
MethodDefinitionSourceMapping mapping = (MethodDefinitionSourceMapping) it.next();
ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
Iterator configAttributesIt = mapping.getConfigAttributes().iterator();
while (configAttributesIt.hasNext()) {
String s = (String) configAttributesIt.next();
configDefinition.addConfigAttribute(new SecurityConfig(s));
}
addSecureMethod(mapping.getMethodName(), configDefinition);
}
}
}
@@ -15,23 +15,23 @@
package org.acegisecurity.intercept.method;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.ConfigAttributeEditor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* Property editor to assist with the setup of a {@link MethodDefinitionSource}.
* <p>The class creates and populates a {@link MethodDefinitionMap}.</p>
* Property editor to assist with the setup of a {@link MethodDefinitionSource}.<p>The class creates and populates
* a {@link MethodDefinitionMap}.</p>
*
* @author Ben Alex
* @version $Id$
@@ -56,24 +56,20 @@ public class MethodDefinitionSourceEditor extends PropertyEditorSupport {
Properties props = (Properties) propertiesEditor.getValue();
// Now we have properties, process each one individually
List mappings = new ArrayList();
ConfigAttributeEditor configAttribEd = new ConfigAttributeEditor();
for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = props.getProperty(name);
MethodDefinitionSourceMapping mapping = new MethodDefinitionSourceMapping();
mapping.setMethodName(name);
// Convert value to series of security configuration attributes
configAttribEd.setAsText(value);
String[] tokens = StringUtils.commaDelimitedListToStringArray(value);
ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd.getValue();
for (int i = 0; i < tokens.length; i++) {
mapping.addConfigAttribute(tokens[i].trim());
}
mappings.add(mapping);
// Register name and attribute
source.addSecureMethod(name, attr);
}
source.setMappings(mappings);
}
setValue(source);
@@ -1,82 +0,0 @@
/* Copyright 2006 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 org.acegisecurity.intercept.method;
import java.util.ArrayList;
import java.util.List;
import org.acegisecurity.ConfigAttribute;
/**
* Configuration entry for {@link MethodDefinitionSource}, that holds
* the method to be protected and the {@link ConfigAttribute}s as {@link String}
* that apply to that url.
*
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
* @version $Id$
* @since 1.1
*/
public class MethodDefinitionSourceMapping {
private String methodName;
private List configAttributes = new ArrayList();
/**
* Name of the method to be secured, including package and class name.
* eg. <code>org.mydomain.MyClass.myMethod</code>
*
* @param methodName
*/
public void setMethodName(String methodName) {
this.methodName = methodName;
}
/**
* Name of the method to be secured.
*
* @return the name of the method
*/
public String getMethodName() {
return methodName;
}
/**
*
* @param roles {@link List}&lt;{@link String}>
*/
public void setConfigAttributes(List roles) {
this.configAttributes = roles;
}
/**
*
* @return {@link List}&lt;{@link String}>
*/
public List getConfigAttributes() {
return configAttributes;
}
/**
* Add a {@link ConfigAttribute} as {@link String}
*
* @param configAttribute
*/
public void addConfigAttribute(String configAttribute) {
configAttributes.add(configAttribute);
}
}
@@ -68,12 +68,11 @@ public class MethodDefinitionSourceAdvisor extends StaticMethodMatcherPointcutAd
//~ Inner Classes ==================================================================================================
/**
* Represents a <code>MethodInvocation</code>.
* <p>Required as <code>MethodDefinitionSource</code> only supports lookup of configuration attributes for
* <code>MethodInvocation</code>s.</p>
* Represents a <code>MethodInvocation</code>.<p>Required as <code>MethodDefinitionSource</code> only
* supports lookup of configuration attributes for <code>MethodInvocation</code>s.</p>
*/
class InternalMethodInvocation implements MethodInvocation {
private Method method;
Method method;
public InternalMethodInvocation(Method method) {
this.method = method;
@@ -27,5 +27,5 @@ package org.acegisecurity.intercept.method.aspectj;
public interface AspectJCallback {
//~ Methods ========================================================================================================
Object proceedWithObject();
public Object proceedWithObject();
}
@@ -17,6 +17,9 @@ package org.acegisecurity.intercept.web;
import org.acegisecurity.ConfigAttributeDefinition;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Abstract implementation of <Code>FilterInvocationDefinitionSource</code>.
@@ -25,6 +28,9 @@ import org.acegisecurity.ConfigAttributeDefinition;
* @version $Id$
*/
public abstract class AbstractFilterInvocationDefinitionSource implements FilterInvocationDefinitionSource {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(AbstractFilterInvocationDefinitionSource.class);
//~ Methods ========================================================================================================
@@ -41,11 +47,9 @@ public abstract class AbstractFilterInvocationDefinitionSource implements Filter
/**
* Performs the actual lookup of the relevant <code>ConfigAttributeDefinition</code> for the specified
* <code>FilterInvocation</code>.
* <p>Provided so subclasses need only to provide one basic method to properly interface with the
* <code>FilterInvocationDefinitionSource</code>.
* </p>
* <p>Public visiblity so that tablibs or other view helper classes can access the
* <code>FilterInvocation</code>.<P>Provided so subclasses need only to provide one basic method to
* properly interface with the <code>FilterInvocationDefinitionSource</code>.</p>
* <P>Public visiblity so that tablibs or other view helper classes can access the
* <code>ConfigAttributeDefinition</code> applying to a given URI pattern without needing to construct a mock
* <code>FilterInvocation</code> and retrieving the attibutes via the {@link #getAttributes(Object)} method.</p>
*
@@ -56,6 +60,10 @@ public abstract class AbstractFilterInvocationDefinitionSource implements Filter
public abstract ConfigAttributeDefinition lookupAttributes(String url);
public boolean supports(Class clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
if (FilterInvocation.class.isAssignableFrom(clazz)) {
return true;
} else {
return false;
}
}
}
@@ -1,27 +0,0 @@
/* Copyright 2006 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 org.acegisecurity.intercept.web;
/**
* Interface to join {@link FilterInvocationDefinitionMap} and
* {@link FilterInvocationDefinitionSource}.
*
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
* @version $Id$
* @since 1.1
*/
public interface FilterInvocationDefinition extends FilterInvocationDefinitionMap, FilterInvocationDefinitionSource {
}

Some files were not shown because too many files have changed in this diff Show More