Documentation update to present state of CVS classes and interfaces.
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 5.7 KiB |
|
@ -26,7 +26,7 @@
|
|||
|
||||
<subtitle>Reference Documentation</subtitle>
|
||||
|
||||
<releaseinfo>0.7-SNAPSHOT</releaseinfo>
|
||||
<releaseinfo>0.7.0-SNAPSHOT</releaseinfo>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<title>Introduction</title>
|
||||
|
||||
<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
|
||||
designed from the ground up using "The Spring Way" of development, which
|
||||
includes using bean contexts, interceptors and interface-driven
|
||||
|
@ -91,8 +91,9 @@
|
|||
<para>Throughout the Acegi Security System for Spring, the user, system
|
||||
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,
|
||||
which you may be familiar with from other security
|
||||
implementations.</para>
|
||||
which you may be familiar with from other security implementations,
|
||||
although equivalent functionality is fully accommodated by Acegi
|
||||
Security.</para>
|
||||
|
||||
<sect2 id="security-introduction-status">
|
||||
<title>Current Status</title>
|
||||
|
@ -156,7 +157,16 @@
|
|||
<sect2 id="security-high-level-design-key-components">
|
||||
<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>
|
||||
|
||||
<itemizedlist spacing="compact">
|
||||
|
@ -193,23 +203,51 @@
|
|||
|
||||
<listitem>
|
||||
<para>A "secure object" interceptor, which coordinates the
|
||||
authentication, authorization, run-as replacement and execution of
|
||||
a given operation.</para>
|
||||
authentication, authorization, run-as replacement, after
|
||||
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>
|
||||
<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>
|
||||
</itemizedlist>
|
||||
|
||||
<para>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>A "secure object" interceptor executes most of the Acegi
|
||||
Security key classes and in doing so delivers the framework's major
|
||||
features. Given its importance, Figure 1 shows the key relationships
|
||||
and concrete implementations of
|
||||
<literal>AbstractSecurityInterceptor</literal>.</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
|
||||
<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
|
||||
object to secure calls to a messaging system that does not use
|
||||
<literal>MethodInvocation</literal>s. Most Spring applications will
|
||||
simply use the three currently supported secure object types
|
||||
(<literal>MethodInvocation</literal>, <literal>JoinPoint</literal> and
|
||||
simply use the three currently supported secure object types (AOP
|
||||
Alliance <literal>MethodInvocation</literal>, AspectJ
|
||||
<literal>JoinPoint</literal> and web request
|
||||
<literal>FilterInterceptor</literal>) with complete
|
||||
transparency.</para>
|
||||
|
||||
<para>Each of the seven key parts is discussed in detail throughout
|
||||
this document.</para>
|
||||
<para>Each of the eight key parts of Acegi Security are discussed in
|
||||
detail throughout this document.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="security-high-level-design-supported-secure-objects">
|
||||
<title>Supported Secure Objects</title>
|
||||
|
||||
<para>The Acegi Security System for Spring currently supports three
|
||||
secure objects.</para>
|
||||
<para>As shown in the base of Figure 1, the Acegi Security System for
|
||||
Spring currently supports three secure objects.</para>
|
||||
|
||||
<para>The first handles an AOP Alliance
|
||||
<literal>MethodInvocation</literal>. This is the secure object type
|
||||
|
@ -340,6 +379,17 @@
|
|||
for Spring uses the request context to pass around the authentication
|
||||
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
|
||||
<literal>Context</literal> interface, which exposes a single
|
||||
method:</para>
|
||||
|
@ -454,19 +504,28 @@
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Return any result received from the secure object
|
||||
execution.</para>
|
||||
<para>If an <literal>AfterInvocationManager</literal> is defined,
|
||||
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>
|
||||
</orderedlist>
|
||||
|
||||
<para>Whilst this may seem quite involved, don't worry. Developers
|
||||
interact with the security process by simply implementing basic
|
||||
interfaces (such as <literal>AccessDecisionManager</literal>), which
|
||||
are fully documented below.</para>
|
||||
are fully discussed below.</para>
|
||||
|
||||
<para>The <literal>AbstractSecurityInterceptor</literal> handles the
|
||||
majority of the flow listed above. Each secure object has its own
|
||||
security interceptor which subclasses
|
||||
majority of the flow listed above. As shown in Figure 1, each secure
|
||||
object has its own security interceptor which subclasses
|
||||
<literal>AbstractSecurityInterceptor</literal>. Each of these secure
|
||||
object-specific security interceptors are discussed below.</para>
|
||||
</sect2>
|
||||
|
@ -495,6 +554,7 @@
|
|||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref bean="runAsManager"/></property>
|
||||
<property name="afterInvocationManager"><ref bean="afterInvocationManager"/></property>
|
||||
<property name="objectDefinitionSource">
|
||||
<value>
|
||||
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
|
||||
|
@ -508,8 +568,10 @@
|
|||
<literal>AuthenticationManager</literal>,
|
||||
<literal>AccessDecisionManager</literal> and
|
||||
<literal>RunAsManager</literal>, which are each discussed in separate
|
||||
sections below. The <literal>MethodSecurityInterceptor</literal> is
|
||||
also configured with configuration attributes that apply to different
|
||||
sections below. In this case we've also defined an
|
||||
<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
|
||||
provided in the High Level Design section of this document.</para>
|
||||
|
||||
|
@ -635,6 +697,7 @@
|
|||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref bean="runAsManager"/></property>
|
||||
<property name="afterInvocationManager"><ref bean="afterInvocationManager"/></property>
|
||||
<property name="objectDefinitionSource">
|
||||
<value>
|
||||
net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
|
||||
|
@ -784,7 +847,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
|
|||
Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
|
||||
for commencing a form-based authentication,
|
||||
<literal>BasicProcessingFilterEntryPoint</literal> for commencing a
|
||||
Http Basic authentication process, and
|
||||
HTTP Basic authentication process, and
|
||||
<literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale
|
||||
Central Authentication Service (CAS) login. The
|
||||
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
|
||||
|
@ -919,8 +982,21 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
|
|||
authorities that have been granted to the principal. The principal and
|
||||
its credentials are populated by the client code, whilst the granted
|
||||
authorities are populated by the
|
||||
<literal>AuthenticationManager</literal>. The Acegi Security System
|
||||
for Spring includes several concrete <literal>Authentication</literal>
|
||||
<literal>AuthenticationManager</literal>. </para>
|
||||
|
||||
<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>
|
||||
|
||||
<itemizedlist spacing="compact">
|
||||
|
@ -1177,7 +1253,10 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
|
|||
<literal>User</literal> will be used directly or subclassed, although
|
||||
special circumstances (such as object relational mappers) may require
|
||||
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
|
||||
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
|
||||
authorization, the Acegi Security System for Spring includes several
|
||||
<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
|
||||
an authorization decision. The
|
||||
<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
|
||||
effect.</para>
|
||||
|
||||
<para>There is one concrete <literal>AccessDecisionVoter</literal>
|
||||
implementation provided with the Acegi Security System for Spring. The
|
||||
<literal>RoleVoter</literal> class will vote if any ConfigAttribute
|
||||
begins with <literal>ROLE_</literal>. It will vote to grant access if
|
||||
there is a <literal>GrantedAuthority</literal> which returns a
|
||||
<literal>String</literal> representation (via the
|
||||
<para>There are two concrete <literal>AccessDecisionVoter</literal>
|
||||
implementations provided with the Acegi Security System for Spring.
|
||||
The <literal>RoleVoter</literal> class will vote if any
|
||||
ConfigAttribute begins with <literal>ROLE_</literal>. It will vote to
|
||||
grant access if there is a <literal>GrantedAuthority</literal> which
|
||||
returns a <literal>String</literal> representation (via the
|
||||
<literal>getAuthority()</literal> method) exactly equal to one or more
|
||||
<literal>ConfigAttributes</literal> starting with
|
||||
<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
|
||||
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><bean id="aclContactReadVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_READ</value></property>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="aclContactDeleteVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_DELETE</value></property>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean></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
|
||||
in the Acegi Security System for Spring unit tests, including
|
||||
<literal>ContactSecurityVoter</literal> and
|
||||
|
@ -1713,23 +1860,39 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
</sect2>
|
||||
|
||||
<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
|
||||
tag library that eases JSP writing. The tag library is known as
|
||||
<literal>authz</literal>.</para>
|
||||
<para>The Acegi Security System for Spring comes bundled with several
|
||||
JSP tag libraries that eases JSP writing. The tag libraries are known
|
||||
as <literal>authz</literal> and provide a range of different
|
||||
services.</para>
|
||||
|
||||
<para>This library allows you to easy develop JSP pages which
|
||||
reference the security environment. For example,
|
||||
<literal>authz</literal> allows you to determine if a principal holds
|
||||
a particular granted authority, holds a group of granted authorities,
|
||||
or does not hold a given granted authority.</para>
|
||||
<para>All taglib classes are included in the core
|
||||
<literal>acegi-security-xx.jar</literal> file, with the
|
||||
<literal>authz.tld</literal> located in the JAR's
|
||||
<literal>META-INF</literal> directory. This means for JSP 1.2+ web
|
||||
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><taglib>
|
||||
<taglib-uri>http://acegisecurity.sf.net/authz</taglib-uri>
|
||||
<taglib-location>/WEB-INF/authz.tld</taglib-location>
|
||||
</taglib></programlisting></para>
|
||||
|
||||
<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
|
||||
<literal>authz</literal> taglib:</para>
|
||||
<literal>AuthorizeTag</literal>:</para>
|
||||
|
||||
<para><programlisting><authz:authorize ifAllGranted="ROLE_SUPERVISOR">
|
||||
<td>
|
||||
|
@ -1737,40 +1900,8 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
</td>
|
||||
</authz:authorize></programlisting></para>
|
||||
|
||||
<para>This code was copied from the Contacts sample
|
||||
application.</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><taglib>
|
||||
<taglib-uri>http://acegisecurity.sf.net/authz</taglib-uri>
|
||||
<taglib-location>/WEB-INF/authz.tld</taglib-location>
|
||||
</taglib></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>This tag would cause the tag's body to be output if the
|
||||
principal has been granted ROLE_SUPERVISOR.</para>
|
||||
|
||||
<para>The <literal>authz:authorize</literal> tag declares the
|
||||
following attributes:</para>
|
||||
|
@ -1819,6 +1950,50 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
<literal>ifAllGranted</literal>, and finally,
|
||||
<literal>ifAnyGranted</literal>.</para>
|
||||
</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><authz:authentication operation="principal"/></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><authz:acl domainObject="${contact}" hasPermission="16,1">
|
||||
<td><A HREF="<c:url value="del.htm"><c:param name="contactId" value="${contact.id}"/></c:url>">Del</A></td>
|
||||
</authz:acl></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 id="security-authorization-recommendations">
|
||||
|
@ -1852,6 +2027,115 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
</sect2>
|
||||
</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><bean id="afterAclRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean></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><bean id="afterAclCollectionRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean></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">
|
||||
<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
|
||||
different authentication and authorization credentials. It will also
|
||||
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 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
|
||||
this in whichever way they like, such as directly calling the relevant
|
||||
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
|
||||
designed to make interfacing web application user interfaces with the
|
||||
<literal>ContextHolder</literal> as simple as possible. There are two
|
||||
major steps in doing this:</para>
|
||||
<para>The <literal>net.sf.acegisecurity.ui</literal> package provides
|
||||
authentication mechanisms for web applications. There are two major
|
||||
steps in doing this:</para>
|
||||
|
||||
<para><itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
|
@ -1985,18 +2273,19 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
</itemizedlist></para>
|
||||
|
||||
<para>There are several alternatives are available for the first step,
|
||||
which will be briefly discussed in this chapter. The most popular
|
||||
approach is HTTP Session Authentication, which uses the
|
||||
<literal>HttpSession</literal> object and filters to authenticate the
|
||||
user. Another approach is HTTP Basic Authentication, which allows
|
||||
clients to use HTTP headers to present authentication information to
|
||||
the Acegi Security System for Spring. Alternatively, you can also use
|
||||
Yale Central Authentication Service (CAS) for enterprise-wide single
|
||||
sign on. The final approach is via Container Adapters, which allow
|
||||
supported web containers to perform the authentication themselves.
|
||||
HTTP Session and Basic Authentication is discussed below, whilst CAS
|
||||
and Container Adapters are discussed in separate sections of this
|
||||
document.</para>
|
||||
which will be briefly discussed in this chapter. The most popular (and
|
||||
almost always recommended) approach is HTTP Session Authentication,
|
||||
which uses the <literal>HttpSession</literal> object and filters to
|
||||
authenticate the user. Another approach (commonly use with web
|
||||
services) is HTTP Basic Authentication, which allows clients to use
|
||||
HTTP headers to present authentication information to the Acegi
|
||||
Security System for Spring. Alternatively, you can also use Yale
|
||||
Central Authentication Service (CAS) for enterprise-wide single sign
|
||||
on. The final (generally unrecommended) approach is via Container
|
||||
Adapters, which allow supported web containers to perform the
|
||||
authentication themselves. HTTP Session and Basic Authentication is
|
||||
discussed below, whilst CAS and Container Adapters are discussed in
|
||||
separate sections of this document.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="security-ui-http-session">
|
||||
|
@ -2485,7 +2774,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
|||
installation.</para>
|
||||
|
||||
<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
|
||||
<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">
|
||||
<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
|
||||
permissions not simply at a web request or method invocation level.
|
||||
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>
|
||||
|
||||
<para>The <literal>net.sf.acegisecurity.acl</literal> package is very
|
||||
simple, comprising only a handful of interfaces and a single class. It
|
||||
provides the basic foundation for access control list (ACL) lookups.
|
||||
The central interface is <literal>AclManager</literal>, which is
|
||||
simple, comprising only a handful of interfaces and a single class, as
|
||||
shown in Figure 5. It provides the basic foundation for access control
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
||||
<para>Acegi Security System for Spring includes a production-quality
|
||||
ACL provider implementation. 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
|
||||
ACL provider implementation, which is shown in Figure 6. </para>
|
||||
|
||||
<para><mediaobject>
|
||||
<imageobject role="html">
|
||||
<imagedata align="center" fileref="images/BasicAclProvider.gif"
|
||||
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>
|
||||
|
||||
<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>
|
||||
implementation called <literal>JdbcDaoImpl</literal>. As implied by
|
||||
the name, it accesses ACL information from a JDBC database. The
|
||||
default database schema and some sample data will aid in understanding
|
||||
its function:</para>
|
||||
the name, <literal>JdbcDaoImpl</literal> accesses ACL information from
|
||||
a JDBC database. There is also an extended version of this DAO,
|
||||
<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 (
|
||||
id IDENTITY NOT NULL,
|
||||
|
|