Documentation update to present state of CVS classes and interfaces.

This commit is contained in:
Ben Alex 2004-12-03 10:15:55 +00:00
parent 41b41ba316
commit 01165ea0e1
8 changed files with 434 additions and 119 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -26,7 +26,7 @@
<subtitle>Reference Documentation</subtitle> <subtitle>Reference Documentation</subtitle>
<releaseinfo>0.7-SNAPSHOT</releaseinfo> <releaseinfo>0.7.0-SNAPSHOT</releaseinfo>
<authorgroup> <authorgroup>
<author> <author>
@ -73,7 +73,7 @@
<title>Introduction</title> <title>Introduction</title>
<para>The Acegi Security System for Spring provides authentication and <para>The Acegi Security System for Spring provides authentication and
authorization capabilities for Spring-powered projects, with full authorization capabilities for Spring-powered projects, with optional
integration with popular web containers. The security architecture was integration with popular web containers. The security architecture was
designed from the ground up using "The Spring Way" of development, which designed from the ground up using "The Spring Way" of development, which
includes using bean contexts, interceptors and interface-driven includes using bean contexts, interceptors and interface-driven
@ -91,8 +91,9 @@
<para>Throughout the Acegi Security System for Spring, the user, system <para>Throughout the Acegi Security System for Spring, the user, system
or agent that needs to be authenticated is referred to as a "principal". or agent that needs to be authenticated is referred to as a "principal".
The security architecture does not have a notion of roles or groups, The security architecture does not have a notion of roles or groups,
which you may be familiar with from other security which you may be familiar with from other security implementations,
implementations.</para> although equivalent functionality is fully accommodated by Acegi
Security.</para>
<sect2 id="security-introduction-status"> <sect2 id="security-introduction-status">
<title>Current Status</title> <title>Current Status</title>
@ -156,7 +157,16 @@
<sect2 id="security-high-level-design-key-components"> <sect2 id="security-high-level-design-key-components">
<title>Key Components</title> <title>Key Components</title>
<para>The Acegi Security System for Spring essentially comprises seven <para>Most enterprise applications have four basic security
requirements. First, they need to be able to authenticate a principal.
Second, they need to be able to secure web requests. Third, enterprise
applications need to be able to secure services layer methods.
Finally, quite often an enterprise application will need to secure
domain object instances. Acegi Security provides a comprehensive
framework for achieving all of these four common enterprise
application security requirements.</para>
<para>The Acegi Security System for Spring essentially comprises eight
key functional parts:</para> key functional parts:</para>
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
@ -193,23 +203,51 @@
<listitem> <listitem>
<para>A "secure object" interceptor, which coordinates the <para>A "secure object" interceptor, which coordinates the
authentication, authorization, run-as replacement and execution of authentication, authorization, run-as replacement, after
a given operation.</para> invocation handling and execution of a given operation.</para>
</listitem>
<listitem>
<para>An <literal>AfterInvocationManager</literal> which can
modify an <literal>Object</literal> returned from a "secure
object" invocation, such as removing <literal>Collection</literal>
elements a principal does not have authority to access.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>An acess control list (ACL) management package, which can be <para>An acess control list (ACL) management package, which can be
used to obtain ACLs for domain object instances.</para> used to obtain the ACLs applicable for domain object
instances.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para>Secure objects refer to any type of object that can have <para>A "secure object" interceptor executes most of the Acegi
security applied to it. A secure object must provide some form of Security key classes and in doing so delivers the framework's major
callback, so that the security interceptor can transparently do its features. Given its importance, Figure 1 shows the key relationships
work as required, and callback the object when it is time for it to and concrete implementations of
proceed with the requested operation. If secure objects cannot provide <literal>AbstractSecurityInterceptor</literal>.</para>
a native callback approach, a wrapper needs to be written so this
becomes possible.</para> <para><mediaobject>
<imageobject role="html">
<imagedata align="center"
fileref="images/SecurityInterception.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 1: The key "secure object" model</para>
</caption>
</mediaobject></para>
<para>Each "secure object" interceptor (hereinafter called a "security
interceptor") works with a particular type of "secure object". So,
what is a secure object? Secure objects refer to any type of object
that can have security applied to it. A secure object must provide
some form of callback, so that the security interceptor can
transparently do its work as required, and callback the object when it
is time for it to proceed with the requested operation. If secure
objects cannot provide a native callback approach, a wrapper needs to
be written so this becomes possible.</para>
<para>Each secure object has its own package under <para>Each secure object has its own package under
<literal>net.sf.acegisecurity.intercept</literal>. Every other package <literal>net.sf.acegisecurity.intercept</literal>. Every other package
@ -221,20 +259,21 @@
directly. For example, it would be possible to build a new secure directly. For example, it would be possible to build a new secure
object to secure calls to a messaging system that does not use object to secure calls to a messaging system that does not use
<literal>MethodInvocation</literal>s. Most Spring applications will <literal>MethodInvocation</literal>s. Most Spring applications will
simply use the three currently supported secure object types simply use the three currently supported secure object types (AOP
(<literal>MethodInvocation</literal>, <literal>JoinPoint</literal> and Alliance <literal>MethodInvocation</literal>, AspectJ
<literal>JoinPoint</literal> and web request
<literal>FilterInterceptor</literal>) with complete <literal>FilterInterceptor</literal>) with complete
transparency.</para> transparency.</para>
<para>Each of the seven key parts is discussed in detail throughout <para>Each of the eight key parts of Acegi Security are discussed in
this document.</para> detail throughout this document.</para>
</sect2> </sect2>
<sect2 id="security-high-level-design-supported-secure-objects"> <sect2 id="security-high-level-design-supported-secure-objects">
<title>Supported Secure Objects</title> <title>Supported Secure Objects</title>
<para>The Acegi Security System for Spring currently supports three <para>As shown in the base of Figure 1, the Acegi Security System for
secure objects.</para> Spring currently supports three secure objects.</para>
<para>The first handles an AOP Alliance <para>The first handles an AOP Alliance
<literal>MethodInvocation</literal>. This is the secure object type <literal>MethodInvocation</literal>. This is the secure object type
@ -340,6 +379,17 @@
for Spring uses the request context to pass around the authentication for Spring uses the request context to pass around the authentication
request and response.</para> request and response.</para>
<para><mediaobject>
<imageobject role="html">
<imagedata align="center" fileref="images/Context.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 2: The ContextHolder</para>
</caption>
</mediaobject></para>
<para>A request context is a concrete implementation of the <para>A request context is a concrete implementation of the
<literal>Context</literal> interface, which exposes a single <literal>Context</literal> interface, which exposes a single
method:</para> method:</para>
@ -454,19 +504,28 @@
</listitem> </listitem>
<listitem> <listitem>
<para>Return any result received from the secure object <para>If an <literal>AfterInvocationManager</literal> is defined,
execution.</para> pass it the result of the secure object execution so that it may
throw an <literal>AccessDeniedException</literal> or mutate the
returned object if required.</para>
</listitem>
<listitem>
<para>Return any result received from the
<literal>AfterInvocationManager</literal>, or if no
<literal>AfterInvocationManager</literal> is defined, simply
return the result provided by the secure object execution.</para>
</listitem> </listitem>
</orderedlist> </orderedlist>
<para>Whilst this may seem quite involved, don't worry. Developers <para>Whilst this may seem quite involved, don't worry. Developers
interact with the security process by simply implementing basic interact with the security process by simply implementing basic
interfaces (such as <literal>AccessDecisionManager</literal>), which interfaces (such as <literal>AccessDecisionManager</literal>), which
are fully documented below.</para> are fully discussed below.</para>
<para>The <literal>AbstractSecurityInterceptor</literal> handles the <para>The <literal>AbstractSecurityInterceptor</literal> handles the
majority of the flow listed above. Each secure object has its own majority of the flow listed above. As shown in Figure 1, each secure
security interceptor which subclasses object has its own security interceptor which subclasses
<literal>AbstractSecurityInterceptor</literal>. Each of these secure <literal>AbstractSecurityInterceptor</literal>. Each of these secure
object-specific security interceptors are discussed below.</para> object-specific security interceptors are discussed below.</para>
</sect2> </sect2>
@ -495,6 +554,7 @@
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt; &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt; &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt; &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
&lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
&lt;property name="objectDefinitionSource"&gt; &lt;property name="objectDefinitionSource"&gt;
&lt;value&gt; &lt;value&gt;
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
@ -508,8 +568,10 @@
<literal>AuthenticationManager</literal>, <literal>AuthenticationManager</literal>,
<literal>AccessDecisionManager</literal> and <literal>AccessDecisionManager</literal> and
<literal>RunAsManager</literal>, which are each discussed in separate <literal>RunAsManager</literal>, which are each discussed in separate
sections below. The <literal>MethodSecurityInterceptor</literal> is sections below. In this case we've also defined an
also configured with configuration attributes that apply to different <literal>AfterInvocationManager</literal>, although this is entirely
optional. The <literal>MethodSecurityInterceptor</literal> is also
configured with configuration attributes that apply to different
method signatures. A full discussion of configuration attributes is method signatures. A full discussion of configuration attributes is
provided in the High Level Design section of this document.</para> provided in the High Level Design section of this document.</para>
@ -635,6 +697,7 @@
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt; &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt; &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt; &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
&lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
&lt;property name="objectDefinitionSource"&gt; &lt;property name="objectDefinitionSource"&gt;
&lt;value&gt; &lt;value&gt;
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
@ -784,7 +847,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal> Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
for commencing a form-based authentication, for commencing a form-based authentication,
<literal>BasicProcessingFilterEntryPoint</literal> for commencing a <literal>BasicProcessingFilterEntryPoint</literal> for commencing a
Http Basic authentication process, and HTTP Basic authentication process, and
<literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale <literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale
Central Authentication Service (CAS) login. The Central Authentication Service (CAS) login. The
<literal>AuthenticationProcessingFilterEntryPoint</literal> and <literal>AuthenticationProcessingFilterEntryPoint</literal> and
@ -919,8 +982,21 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
authorities that have been granted to the principal. The principal and authorities that have been granted to the principal. The principal and
its credentials are populated by the client code, whilst the granted its credentials are populated by the client code, whilst the granted
authorities are populated by the authorities are populated by the
<literal>AuthenticationManager</literal>. The Acegi Security System <literal>AuthenticationManager</literal>. </para>
for Spring includes several concrete <literal>Authentication</literal>
<para><mediaobject>
<imageobject role="html">
<imagedata align="center" fileref="images/Authentication.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 3: Key Authentication Architecture</para>
</caption>
</mediaobject></para>
<para>As shown in Figure 3, the Acegi Security System for Spring
includes several concrete <literal>Authentication</literal>
implementations:</para> implementations:</para>
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
@ -1177,7 +1253,10 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
<literal>User</literal> will be used directly or subclassed, although <literal>User</literal> will be used directly or subclassed, although
special circumstances (such as object relational mappers) may require special circumstances (such as object relational mappers) may require
users to write their own <literal>UserDetails</literal> implementation users to write their own <literal>UserDetails</literal> implementation
from scratch.</para> from scratch. <literal>UserDetails</literal> is often used to store
additional principal-related properties (such as their telephone
number and email address), so they can be easily used by web
views.</para>
<para>Given <literal>AuthenticationDao</literal> is so simple to <para>Given <literal>AuthenticationDao</literal> is so simple to
implement, it should be easy for users to retrieve authentication implement, it should be easy for users to retrieve authentication
@ -1626,7 +1705,21 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>AccessDecisionManager</literal> to control all aspects of <literal>AccessDecisionManager</literal> to control all aspects of
authorization, the Acegi Security System for Spring includes several authorization, the Acegi Security System for Spring includes several
<literal>AccessDecisionManager</literal> implementations that are <literal>AccessDecisionManager</literal> implementations that are
based on voting. Using this approach, a series of based on voting. Figure 4 illustrates the relevant classes.</para>
<para><mediaobject>
<imageobject role="html">
<imagedata align="center"
fileref="images/AccessDecisionVoting.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 4: Voting Decision Manager</para>
</caption>
</mediaobject></para>
<para>Using this approach, a series of
<literal>AccessDecisionVoter</literal> implementations are polled on <literal>AccessDecisionVoter</literal> implementations are polled on
an authorization decision. The an authorization decision. The
<literal>AccessDecisionManager</literal> then decides whether or not <literal>AccessDecisionManager</literal> then decides whether or not
@ -1676,12 +1769,12 @@ public boolean supports(Class clazz);</programlisting></para>
weighting, whilst a deny vote from a particular voter may have a veto weighting, whilst a deny vote from a particular voter may have a veto
effect.</para> effect.</para>
<para>There is one concrete <literal>AccessDecisionVoter</literal> <para>There are two concrete <literal>AccessDecisionVoter</literal>
implementation provided with the Acegi Security System for Spring. The implementations provided with the Acegi Security System for Spring.
<literal>RoleVoter</literal> class will vote if any ConfigAttribute The <literal>RoleVoter</literal> class will vote if any
begins with <literal>ROLE_</literal>. It will vote to grant access if ConfigAttribute begins with <literal>ROLE_</literal>. It will vote to
there is a <literal>GrantedAuthority</literal> which returns a grant access if there is a <literal>GrantedAuthority</literal> which
<literal>String</literal> representation (via the returns a <literal>String</literal> representation (via the
<literal>getAuthority()</literal> method) exactly equal to one or more <literal>getAuthority()</literal> method) exactly equal to one or more
<literal>ConfigAttributes</literal> starting with <literal>ConfigAttributes</literal> starting with
<literal>ROLE_</literal>. If there is no exact match of any <literal>ROLE_</literal>. If there is no exact match of any
@ -1692,7 +1785,61 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>RoleVoter</literal> is case sensitive on comparisons as well <literal>RoleVoter</literal> is case sensitive on comparisons as well
as the <literal>ROLE_</literal> prefix.</para> as the <literal>ROLE_</literal> prefix.</para>
<para>It is possible to implement a custom <para>BasicAclEntryVoter is the other concrete voter included with
Acegi Security. It integrates with Acegi Security's
<literal>AclManager</literal> (discussed later). This voter is
designed to have multiple instances in the same application context,
such as:</para>
<para><programlisting>&lt;bean id="aclContactReadVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter"&gt;
&lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_READ&lt;/value&gt;&lt;/property&gt;
&lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
&lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
&lt;property name="requirePermission"&gt;
&lt;list&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="aclContactDeleteVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter"&gt;
&lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_DELETE&lt;/value&gt;&lt;/property&gt;
&lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
&lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
&lt;property name="requirePermission"&gt;
&lt;list&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para>In the above example, you'd define
<literal>ACL_CONTACT_READ</literal> or
<literal>ACL_CONTACT_DELETE</literal> against some methods on a
<literal>MethodSecurityInterceptor</literal> or
<literal>AspectJSecurityInterceptor</literal>. When those methods are
invoked, the above applicable voter defined above would vote to grant
or deny access. The voter would look at the method invocation to
locate the first argument of type
<literal>sample.contact.Contact</literal>, and then pass that
<literal>Contact</literal> to the <literal>AclManager</literal>. The
<literal>AclManager</literal> will then return an access control list
(ACL) that applies to the current <literal>Authentication</literal>.
Assuming that ACL contains one of the listed
<literal>requirePermission</literal>s, the voter will vote to grant
access. If the ACL does not contain one of the permissions defined
against the voter, the voter will vote to deny access.
<literal>BasicAclEntryVoter</literal> is an important class as it
allows you to build truly complex applications with domain object
security entirely defined in the application context. If you're
interested in learning more about Acegi Security's ACL capabilities
and how best to apply them, please see the ACL and "After Invocation"
sections of this reference guide, and the Contacts sample
application.</para>
<para>It is also possible to implement a custom
<literal>AccessDecisionVoter</literal>. Several examples are provided <literal>AccessDecisionVoter</literal>. Several examples are provided
in the Acegi Security System for Spring unit tests, including in the Acegi Security System for Spring unit tests, including
<literal>ContactSecurityVoter</literal> and <literal>ContactSecurityVoter</literal> and
@ -1713,23 +1860,39 @@ public boolean supports(Class clazz);</programlisting></para>
</sect2> </sect2>
<sect2 id="security-authorization-taglib"> <sect2 id="security-authorization-taglib">
<title>Authorization Tag Library</title> <title>Authorization-Related Tag Libraries</title>
<para>The Acegi Security System for Spring comes bundled with a JSP <para>The Acegi Security System for Spring comes bundled with several
tag library that eases JSP writing. The tag library is known as JSP tag libraries that eases JSP writing. The tag libraries are known
<literal>authz</literal>.</para> as <literal>authz</literal> and provide a range of different
services.</para>
<para>This library allows you to easy develop JSP pages which <para>All taglib classes are included in the core
reference the security environment. For example, <literal>acegi-security-xx.jar</literal> file, with the
<literal>authz</literal> allows you to determine if a principal holds <literal>authz.tld</literal> located in the JAR's
a particular granted authority, holds a group of granted authorities, <literal>META-INF</literal> directory. This means for JSP 1.2+ web
or does not hold a given granted authority.</para> containers you can simply include the JAR in the WAR's
<literal>WEB-INF/lib</literal> directory and it will be available. If
you're using a JSP 1.1 container, you'll need to declare the JSP
taglib in your <literal>web.xml file</literal>, and include
<literal>authz.tld</literal> in the <literal>WEB-INF/lib</literal>
directory. The following fragment is added to
<literal>web.xml</literal>:</para>
<para><programlisting>&lt;taglib&gt;
&lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
&lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
&lt;/taglib&gt;</programlisting></para>
<sect3> <sect3>
<title>Usage</title> <title>AuthorizeTag</title>
<para><literal>AuthorizeTag</literal> is used to include content if
the current principal holds certain
<literal>GrantedAuthority</literal>s.</para>
<para>The following JSP fragment illustrates how to use the <para>The following JSP fragment illustrates how to use the
<literal>authz</literal> taglib:</para> <literal>AuthorizeTag</literal>:</para>
<para><programlisting>&lt;authz:authorize ifAllGranted="ROLE_SUPERVISOR"&gt; <para><programlisting>&lt;authz:authorize ifAllGranted="ROLE_SUPERVISOR"&gt;
&lt;td&gt; &lt;td&gt;
@ -1737,40 +1900,8 @@ public boolean supports(Class clazz);</programlisting></para>
&lt;/td&gt; &lt;/td&gt;
&lt;/authz:authorize&gt;</programlisting></para> &lt;/authz:authorize&gt;</programlisting></para>
<para>This code was copied from the Contacts sample <para>This tag would cause the tag's body to be output if the
application.</para> principal has been granted ROLE_SUPERVISOR.</para>
<para>What this code says is: if the principal has been granted
ROLE_SUPERVISOR, allow the tag's body to be output.</para>
</sect3>
<sect3>
<title>Installation</title>
<para>Installation is a simple matter. Simply copy the
<literal>acegi-security-taglib.jar</literal> file into your
application's <literal>WEB-INF/lib</literal> folder. The tag library
includes it's TLD, which makes it easier to work with JSP 1.2+
containers.</para>
<para>If you are using a JSP 1.1 container, you will need to declare
the JSP tag library in your application's <literal>web.xml</literal>
file, with code such as this:</para>
<para><programlisting>&lt;taglib&gt;
&lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
&lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
&lt;/taglib&gt;</programlisting></para>
<para>For JSP 1.1 containers you will also need to extract the
<literal>authz.tld</literal> file from the
<literal>acegi-security-taglib.jar</literal> file and put it into
your application's <literal>WEB-INF/lib</literal> folder. Use a
regular Zip tool, or Java's JAR utility.</para>
</sect3>
<sect3>
<title>Reference</title>
<para>The <literal>authz:authorize</literal> tag declares the <para>The <literal>authz:authorize</literal> tag declares the
following attributes:</para> following attributes:</para>
@ -1819,6 +1950,50 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>ifAllGranted</literal>, and finally, <literal>ifAllGranted</literal>, and finally,
<literal>ifAnyGranted</literal>.</para> <literal>ifAnyGranted</literal>.</para>
</sect3> </sect3>
<sect3>
<title>AuthenticationTag</title>
<para><literal>AuthenticationTag</literal> is used to simply output
the current principal to the web page.</para>
<para>The following JSP fragment illustrates how to use the
<literal>AuthenticationTag</literal>:</para>
<para><programlisting>&lt;authz:authentication operation="principal"/&gt;</programlisting></para>
<para>This tag would cause the principal's name to be output. The
taglib properly supports the various types of principals that can
exist in the <literal>Authentication</literal> object, such as a
<literal>String</literal> or <literal>UserDetails</literal>
instance.</para>
<para>The "operation" attribute must always be "principal". This may
be expanded in the future, such as obtaining other
<literal>Authentication</literal>-related properties such as email
address or telephone numbers.</para>
</sect3>
<sect3>
<title>AclTag</title>
<para><literal>AclTag</literal> is used to include content if the
current principal has a ACL to the indicated domain object.</para>
<para>The following JSP fragment illustrates how to use the
<literal>AclTag</literal>:</para>
<para><programlisting>&lt;authz:acl domainObject="${contact}" hasPermission="16,1"&gt;
&lt;td&gt;&lt;A HREF="&lt;c:url value="del.htm"&gt;&lt;c:param name="contactId" value="${contact.id}"/&gt;&lt;/c:url&gt;"&gt;Del&lt;/A&gt;&lt;/td&gt;
&lt;/authz:acl&gt;</programlisting></para>
<para>This tag would cause the tag's body to be output if the
principal holds either permission 16 or permission 1 for the
"contact" domain object. The numbers are actually integers that are
used with <literal>AbstractBasicAclEntry</literal> bit masking.
Please refer tro the ACL section of this reference guide to
understand more about the ACL capabilities of Acegi Security.</para>
</sect3>
</sect2> </sect2>
<sect2 id="security-authorization-recommendations"> <sect2 id="security-authorization-recommendations">
@ -1852,6 +2027,115 @@ public boolean supports(Class clazz);</programlisting></para>
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="afterinvocation">
<title>After Invocation Handling</title>
<sect2 id="afterinvocation-overview">
<title>Overview</title>
<para>Whilst the <literal>AccessDecisionManager</literal> is called by
the <literal>AbstractSecurityInterceptor</literal> before proceeding
with the secure object invocation, some applications need a way of
modifying the object actually returned by the secure object
invocation. Whilst you could easily implement your own AOP concern to
achieve this, Acegi Security provides a convenient hook that has
several concrete implementations that integrate with its ACL
capabilities.</para>
<para>Figure 4 illustrates Acegi Security's
<literal>AfterInvocationManager</literal> and its concrete
implementations.</para>
<para><mediaobject>
<imageobject role="html">
<imagedata align="center" fileref="images/AfterInvocation.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 4: After Invocation Implementation</para>
</caption>
</mediaobject></para>
<para>Like many other parts of Acegi Security,
<literal>AfterInvocationManager</literal> has a single concrete
implementation, <literal>AfterInvocationProvider</literal>, which
polls a list of <literal>AfterInvocationProvider</literal>s. Each
<literal>AfterInvocationProvider</literal> is allowed to modify the
return object or throw an <literal>AccessDeniedException</literal>.
Indeed multiple providers can modify the object, as the result of the
previous provider is passed to the next in the list. Let's now
consider our ACL-aware implementations of
<literal>AfterInvocationProvider</literal>.</para>
</sect2>
<sect2 id="afterinvocation-acl-aware">
<title>ACL-Aware AfterInvocationProviders</title>
<para>A common services layer method we've all written at one stage or
another looks like this:</para>
<para><programlisting>public Contact getById(Integer id);</programlisting></para>
<para>Quite often, only principals with permission to read the
<literal>Contact</literal> should be allowed to obtain it. In this
situation the <literal>AccessDecisionManager</literal> approach
provided by the <literal>AbstractSecurityInterceptor</literal> will
not suffice. This is because the identity of the
<literal>Contact</literal> is all that is available before the secure
object is invoked. The
<literal>BasicAclAfterInvocationProvider</literal> delivers a
solution, and is configured as follows:</para>
<para><programlisting>&lt;bean id="afterAclRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider"&gt;
&lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
&lt;property name="requirePermission"&gt;
&lt;list&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para>In the above example, the <literal>Contact</literal> will be
retrieved and passed to the
<literal>BasicAclEntryAfterInvocationProvider</literal>. The provider
will thrown an <literal>AccessDeniedException</literal> if one of the
listed <literal>requirePermission</literal>s is not held by the
<literal>Authentication</literal>. The
<literal>BasicAclEntryAfterInvocationProvider</literal> queries the
<literal>AclManager</literal> to determine the ACL that applies for
this domain object to this <literal>Authentication</literal>.</para>
<para>Similar to the
<literal>BasicAclEntryAfterInvocationProvider</literal> is
<literal>BasicAclEntryAfterInvocationCollectionFilteringProvider</literal>.
It is designed to remove <literal>Collection</literal> elements for
which a principal does not have access. It never thrown an
<literal>AccessDeniedException</literal> - simply silently removes the
offending elements. The provider is configured as follows:</para>
<para><programlisting>&lt;bean id="afterAclCollectionRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider"&gt;
&lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
&lt;property name="requirePermission"&gt;
&lt;list&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
&lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para>As you can imagine, the returned <literal>Object</literal> must
be a <literal>Collection</literal> for this provider to operate. It
will remove any element if the <literal>AclManager</literal> indicates
the <literal>Authentication</literal> does not hold one of the listed
<literal>requirePermission</literal>s.</para>
<para>The Contacts sample application demonstrates these two
<literal>AfterInvocationProvider</literal>s.</para>
</sect2>
</sect1>
<sect1 id="security-run-as"> <sect1 id="security-run-as">
<title>Run-As Authentication Replacement</title> <title>Run-As Authentication Replacement</title>
@ -1875,7 +2159,11 @@ public boolean supports(Class clazz);</programlisting></para>
secured invocation will be able to call other objects which require secured invocation will be able to call other objects which require
different authentication and authorization credentials. It will also different authentication and authorization credentials. It will also
be able to perform any internal security checks for specific be able to perform any internal security checks for specific
<literal>GrantedAuthority</literal> objects.</para> <literal>GrantedAuthority</literal> objects. Because Acegi Security
provides a number of helper classes that automatically configure
remoting protocols based on the contents of the
<literal>ContextHolder</literal>, these run-as replacements are
particularly useful when calling remote web services.</para>
</sect2> </sect2>
<sect2 id="security-run-as-usage"> <sect2 id="security-run-as-usage">
@ -1962,12 +2250,12 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>Authentication</literal> object. Developers are free to do <literal>Authentication</literal> object. Developers are free to do
this in whichever way they like, such as directly calling the relevant this in whichever way they like, such as directly calling the relevant
objects at runtime. However, several classes have been provided to objects at runtime. However, several classes have been provided to
make this process transparent in many situations.</para> make this process transparent in many situations. We call these
classes "authentication mechanisms".</para>
<para>The <literal>net.sf.acegisecurity.ui</literal> package is <para>The <literal>net.sf.acegisecurity.ui</literal> package provides
designed to make interfacing web application user interfaces with the authentication mechanisms for web applications. There are two major
<literal>ContextHolder</literal> as simple as possible. There are two steps in doing this:</para>
major steps in doing this:</para>
<para><itemizedlist spacing="compact"> <para><itemizedlist spacing="compact">
<listitem> <listitem>
@ -1985,18 +2273,19 @@ public boolean supports(Class clazz);</programlisting></para>
</itemizedlist></para> </itemizedlist></para>
<para>There are several alternatives are available for the first step, <para>There are several alternatives are available for the first step,
which will be briefly discussed in this chapter. The most popular which will be briefly discussed in this chapter. The most popular (and
approach is HTTP Session Authentication, which uses the almost always recommended) approach is HTTP Session Authentication,
<literal>HttpSession</literal> object and filters to authenticate the which uses the <literal>HttpSession</literal> object and filters to
user. Another approach is HTTP Basic Authentication, which allows authenticate the user. Another approach (commonly use with web
clients to use HTTP headers to present authentication information to services) is HTTP Basic Authentication, which allows clients to use
the Acegi Security System for Spring. Alternatively, you can also use HTTP headers to present authentication information to the Acegi
Yale Central Authentication Service (CAS) for enterprise-wide single Security System for Spring. Alternatively, you can also use Yale
sign on. The final approach is via Container Adapters, which allow Central Authentication Service (CAS) for enterprise-wide single sign
supported web containers to perform the authentication themselves. on. The final (generally unrecommended) approach is via Container
HTTP Session and Basic Authentication is discussed below, whilst CAS Adapters, which allow supported web containers to perform the
and Container Adapters are discussed in separate sections of this authentication themselves. HTTP Session and Basic Authentication is
document.</para> discussed below, whilst CAS and Container Adapters are discussed in
separate sections of this document.</para>
</sect2> </sect2>
<sect2 id="security-ui-http-session"> <sect2 id="security-ui-http-session">
@ -2485,7 +2774,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
installation.</para> installation.</para>
<para>There are two different ways of making spring context available <para>There are two different ways of making spring context available
to the Jboss integration classes. </para> to the Jboss integration classes.</para>
<para>The first approach is by editing your <para>The first approach is by editing your
<literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal> <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
@ -3412,9 +3701,6 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<sect2 id="acls-overview"> <sect2 id="acls-overview">
<title>Overview</title> <title>Overview</title>
<para>THIS FEATURE WAS ADDED IN VERSION 0.6. WE WELCOME YOUR COMMENTS
AND IMPROVEMENTS.</para>
<para>Complex applications often will find the need to define access <para>Complex applications often will find the need to define access
permissions not simply at a web request or method invocation level. permissions not simply at a web request or method invocation level.
Instead, security decisions need to comprise both who Instead, security decisions need to comprise both who
@ -3497,9 +3783,22 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<title>The net.sf.acegisecurity.acl Package</title> <title>The net.sf.acegisecurity.acl Package</title>
<para>The <literal>net.sf.acegisecurity.acl</literal> package is very <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
simple, comprising only a handful of interfaces and a single class. It simple, comprising only a handful of interfaces and a single class, as
provides the basic foundation for access control list (ACL) lookups. shown in Figure 5. It provides the basic foundation for access control
The central interface is <literal>AclManager</literal>, which is list (ACL) lookups. </para>
<para><mediaobject>
<imageobject role="html">
<imagedata align="center" fileref="images/ACLSecurity.gif"
format="GIF" />
</imageobject>
<caption>
<para>Figure 5: Access Control List Manager</para>
</caption>
</mediaobject></para>
<para>The central interface is <literal>AclManager</literal>, which is
defined by two methods:</para> defined by two methods:</para>
<para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance); <para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance);
@ -3548,12 +3847,25 @@ public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authen
<title>Integer Masked ACLs</title> <title>Integer Masked ACLs</title>
<para>Acegi Security System for Spring includes a production-quality <para>Acegi Security System for Spring includes a production-quality
ACL provider implementation. The implementation is based on integer ACL provider implementation, which is shown in Figure 6. </para>
masking, which is commonly used for ACL permissions given its
flexibility and speed. Anyone who has used Unix's <para><mediaobject>
<literal>chmod</literal> command will know all about this type of <imageobject role="html">
permission masking (eg <literal>chmod 777</literal>). You'll find the <imagedata align="center" fileref="images/BasicAclProvider.gif"
classes and interfaces for the integer masking ACL package under format="GIF" />
</imageobject>
<caption>
<para>Figure 6: Basic ACL Manager</para>
</caption>
</mediaobject></para>
<para>The implementation is based on integer masking, which is
commonly used for ACL permissions given its flexibility and speed.
Anyone who has used Unix's <literal>chmod</literal> command will know
all about this type of permission masking (eg <literal>chmod
777</literal>). You'll find the classes and interfaces for the integer
masking ACL package under
<literal>net.sf.acegisecurity.acl.basic</literal>.</para> <literal>net.sf.acegisecurity.acl.basic</literal>.</para>
<para>Extending the <literal>AclEntry</literal> interface is a <para>Extending the <literal>AclEntry</literal> interface is a
@ -3620,9 +3932,12 @@ public java.lang.Object getRecipient();</programlisting></para>
<para>Acegi Security includes a single <literal>BasicAclDao</literal> <para>Acegi Security includes a single <literal>BasicAclDao</literal>
implementation called <literal>JdbcDaoImpl</literal>. As implied by implementation called <literal>JdbcDaoImpl</literal>. As implied by
the name, it accesses ACL information from a JDBC database. The the name, <literal>JdbcDaoImpl</literal> accesses ACL information from
default database schema and some sample data will aid in understanding a JDBC database. There is also an extended version of this DAO,
its function:</para> <literal>JdbcExtendedDaoImpl</literal>, which provides CRUD operations
on the JDBC database, although we won't discuss these features here.
The default database schema and some sample data will aid in
understanding its function:</para>
<para><programlisting>CREATE TABLE acl_object_identity ( <para><programlisting>CREATE TABLE acl_object_identity (
id IDENTITY NOT NULL, id IDENTITY NOT NULL,