Converted literals to classname/interfacename docbook tags for easier indexing
This commit is contained in:
parent
09c70bb28e
commit
de379dc2ac
|
@ -14,11 +14,11 @@
|
|||
logout and home pages of an application. There are also other
|
||||
situations where anonymous authentication would be desired, such as
|
||||
when an auditing interceptor queries the
|
||||
<literal>SecurityContextHolder</literal> to identify which principal
|
||||
<classname>SecurityContextHolder</classname> to identify which principal
|
||||
was responsible for a given operation. Such classes can be authored
|
||||
with more robustness if they know the
|
||||
<literal>SecurityContextHolder</literal> always contains an
|
||||
<literal>Authentication</literal> object, and never
|
||||
<classname>SecurityContextHolder</classname> always contains an
|
||||
<interfacename>Authentication</interfacename> object, and never
|
||||
<literal>null</literal>.</para>
|
||||
</section>
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
|||
<para>Spring Security provides three classes that together provide an
|
||||
anonymous authentication feature.
|
||||
<literal>AnonymousAuthenticationToken</literal> is an implementation
|
||||
of <literal>Authentication</literal>, and stores the
|
||||
<literal>GrantedAuthority</literal>[]s which apply to the anonymous
|
||||
of <interfacename>Authentication</interfacename>, and stores the
|
||||
<interfacename>GrantedAuthority</interfacename>[]s which apply to the anonymous
|
||||
principal. There is a corresponding
|
||||
<literal>AnonymousAuthenticationProvider</literal>, which is chained
|
||||
into the <literal>ProviderManager</literal> so that
|
||||
|
@ -37,8 +37,8 @@
|
|||
Finally, there is an AnonymousProcessingFilter, which is chained after
|
||||
the normal authentication mechanisms and automatically add an
|
||||
<literal>AnonymousAuthenticationToken</literal> to the
|
||||
<literal>SecurityContextHolder</literal> if there is no existing
|
||||
<literal>Authentication</literal> held there. The definition of the
|
||||
<classname>SecurityContextHolder</classname> if there is no existing
|
||||
<interfacename>Authentication</interfacename> held there. The definition of the
|
||||
filter and authentication provider appears as follows:</para>
|
||||
|
||||
<para><programlisting>
|
||||
|
@ -91,12 +91,12 @@
|
|||
<literal>isAnonymous(Authentication)</literal> method, which allows
|
||||
interested classes to take into account this special type of
|
||||
authentication status. The
|
||||
<literal>ExceptionTranslationFilter</literal> uses this interface in
|
||||
<classname>ExceptionTranslationFilter</classname> uses this interface in
|
||||
processing <literal>AccessDeniedException</literal>s. If an
|
||||
<literal>AccessDeniedException</literal> is thrown, and the
|
||||
authentication is of an anonymous type, instead of throwing a 403
|
||||
(forbidden) response, the filter will instead commence the
|
||||
<literal>AuthenticationEntryPoint</literal> so the principal can
|
||||
<interfacename>AuthenticationEntryPoint</interfacename> so the principal can
|
||||
authenticate properly. This is a necessary distinction, otherwise
|
||||
principals would always be deemed "authenticated" and never be given
|
||||
an opportunity to login via form, basic, digest or some other normal
|
||||
|
|
|
@ -5,50 +5,50 @@
|
|||
<info><title>Authorities</title></info>
|
||||
|
||||
<para>As briefly mentioned in the Authentication section, all
|
||||
<literal>Authentication</literal> implementations are required to
|
||||
store an array of <literal>GrantedAuthority</literal> objects. These
|
||||
<interfacename>Authentication</interfacename> implementations are required to
|
||||
store an array of <interfacename>GrantedAuthority</interfacename> objects. These
|
||||
represent the authorities that have been granted to the principal. The
|
||||
<literal>GrantedAuthority</literal> objects are inserted into the
|
||||
<literal>Authentication</literal> object by the
|
||||
<literal>AuthenticationManager</literal> and are later read by
|
||||
<literal>AccessDecisionManager</literal>s when making authorization
|
||||
<interfacename>GrantedAuthority</interfacename> objects are inserted into the
|
||||
<interfacename>Authentication</interfacename> object by the
|
||||
<interfacename>AuthenticationManager</interfacename> and are later read by
|
||||
<interfacename>AccessDecisionManager</interfacename>s when making authorization
|
||||
decisions.</para>
|
||||
|
||||
<para><literal>GrantedAuthority</literal> is an interface with only
|
||||
<para><interfacename>GrantedAuthority</interfacename> is an interface with only
|
||||
one method:
|
||||
<programlisting>
|
||||
String getAuthority();
|
||||
</programlisting>
|
||||
This method allows <literal>AccessDecisionManager</literal>s to
|
||||
This method allows <interfacename>AccessDecisionManager</interfacename>s to
|
||||
obtain a precise <literal>String</literal> representation of the
|
||||
<literal>GrantedAuthority</literal>. By returning a representation as
|
||||
a <literal>String</literal>, a <literal>GrantedAuthority</literal> can
|
||||
be easily "read" by most <literal>AccessDecisionManager</literal>s. If
|
||||
a <literal>GrantedAuthority</literal> cannot be precisely represented
|
||||
<interfacename>GrantedAuthority</interfacename>. By returning a representation as
|
||||
a <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can
|
||||
be easily "read" by most <interfacename>AccessDecisionManager</interfacename>s. If
|
||||
a <interfacename>GrantedAuthority</interfacename> cannot be precisely represented
|
||||
as a <literal>String</literal>, the
|
||||
<literal>GrantedAuthority</literal> is considered "complex" and
|
||||
<interfacename>GrantedAuthority</interfacename> is considered "complex" and
|
||||
<literal>getAuthority()</literal> must return
|
||||
<literal>null</literal>.</para>
|
||||
|
||||
<para>An example of a "complex" <literal>GrantedAuthority</literal>
|
||||
<para>An example of a "complex" <interfacename>GrantedAuthority</interfacename>
|
||||
would be an implementation that stores a list of operations and
|
||||
authority thresholds that apply to different customer account numbers.
|
||||
Representing this complex <literal>GrantedAuthority</literal> as a
|
||||
Representing this complex <interfacename>GrantedAuthority</interfacename> as a
|
||||
<literal>String</literal> would be quite complex, and as a result the
|
||||
<literal>getAuthority()</literal> method should return
|
||||
<literal>null</literal>. This will indicate to any
|
||||
<literal>AccessDecisionManager</literal> that it will need to
|
||||
specifically support the <literal>GrantedAuthority</literal>
|
||||
<interfacename>AccessDecisionManager</interfacename> that it will need to
|
||||
specifically support the <interfacename>GrantedAuthority</interfacename>
|
||||
implementation in order to understand its contents.</para>
|
||||
|
||||
<para>Spring Security includes one concrete
|
||||
<literal>GrantedAuthority</literal> implementation,
|
||||
<interfacename>GrantedAuthority</interfacename> implementation,
|
||||
<literal>GrantedAuthorityImpl</literal>. This allows any
|
||||
user-specified <literal>String</literal> to be converted into a
|
||||
<literal>GrantedAuthority</literal>. All
|
||||
<literal>AuthenticationProvider</literal>s included with the security
|
||||
<interfacename>GrantedAuthority</interfacename>. All
|
||||
<classname>AuthenticationProvider</classname>s included with the security
|
||||
architecture use <literal>GrantedAuthorityImpl</literal> to populate
|
||||
the <literal>Authentication</literal> object.</para>
|
||||
the <interfacename>Authentication</interfacename> object.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="pre-invocation">
|
||||
|
@ -64,10 +64,10 @@
|
|||
|
||||
<section>
|
||||
<title>The AccessDecisionManager</title>
|
||||
<para>The <literal>AccessDecisionManager</literal> is called by the
|
||||
<literal>AbstractSecurityInterceptor</literal> and is responsible for
|
||||
<para>The <interfacename>AccessDecisionManager</interfacename> is called by the
|
||||
<classname>AbstractSecurityInterceptor</classname> and is responsible for
|
||||
making final access control decisions. The
|
||||
<literal>AccessDecisionManager</literal> interface contains three
|
||||
<interfacename>AccessDecisionManager</interfacename> interface contains three
|
||||
methods:
|
||||
<programlisting>
|
||||
void decide(Authentication authentication, Object secureObject, ConfigAttributeDefinition config) throws AccessDeniedException;
|
||||
|
@ -75,33 +75,33 @@
|
|||
boolean supports(Class clazz);
|
||||
</programlisting>
|
||||
As can be seen from the first method, the
|
||||
<literal>AccessDecisionManager</literal> is passed via method
|
||||
<interfacename>AccessDecisionManager</interfacename> is passed via method
|
||||
parameters all information that is likely to be of value in assessing
|
||||
an authorization decision. In particular, passing the secure
|
||||
<literal>Object</literal> enables those arguments contained in the
|
||||
actual secure object invocation to be inspected. For example, let's
|
||||
assume the secure object was a <literal>MethodInvocation</literal>. It
|
||||
would be easy to query the <literal>MethodInvocation</literal> for any
|
||||
assume the secure object was a <classname>MethodInvocation</classname>. It
|
||||
would be easy to query the <classname>MethodInvocation</classname> for any
|
||||
<literal>Customer</literal> argument, and then implement some sort of
|
||||
security logic in the <literal>AccessDecisionManager</literal> to
|
||||
security logic in the <interfacename>AccessDecisionManager</interfacename> to
|
||||
ensure the principal is permitted to operate on that customer.
|
||||
Implementations are expected to throw an
|
||||
<literal>AccessDeniedException</literal> if access is denied.</para>
|
||||
|
||||
<para>The <literal>supports(ConfigAttribute)</literal> method is
|
||||
called by the <literal>AbstractSecurityInterceptor</literal> at
|
||||
called by the <classname>AbstractSecurityInterceptor</classname> at
|
||||
startup time to determine if the
|
||||
<literal>AccessDecisionManager</literal> can process the passed
|
||||
<interfacename>AccessDecisionManager</interfacename> can process the passed
|
||||
<literal>ConfigAttribute</literal>. The
|
||||
<literal>supports(Class)</literal> method is called by a security
|
||||
interceptor implementation to ensure the configured
|
||||
<literal>AccessDecisionManager</literal> supports the type of secure
|
||||
<interfacename>AccessDecisionManager</interfacename> supports the type of secure
|
||||
object that the security interceptor will present.</para>
|
||||
|
||||
<section>
|
||||
<title>Voting-Based AccessDecisionManager Implementations</title>
|
||||
<para>Whilst users can implement their own <literal>AccessDecisionManager</literal> to control all aspects of
|
||||
authorization, Spring Security includes several <literal>AccessDecisionManager</literal> implementations that are
|
||||
<para>Whilst users can implement their own <interfacename>AccessDecisionManager</interfacename> to control all aspects of
|
||||
authorization, Spring Security includes several <interfacename>AccessDecisionManager</interfacename> implementations that are
|
||||
based on voting. <xref linkend="authz-access-voting"/> illustrates the relevant classes.</para>
|
||||
<figure xml:id="authz-access-voting">
|
||||
<title>Voting Decision Manager</title>
|
||||
|
@ -115,13 +115,13 @@
|
|||
</mediaobject>
|
||||
</figure>
|
||||
<para>Using this approach, a series of
|
||||
<literal>AccessDecisionVoter</literal> implementations are polled on
|
||||
<interfacename>AccessDecisionVoter</interfacename> implementations are polled on
|
||||
an authorization decision. The
|
||||
<literal>AccessDecisionManager</literal> then decides whether or not
|
||||
<interfacename>AccessDecisionManager</interfacename> then decides whether or not
|
||||
to throw an <literal>AccessDeniedException</literal> based on its
|
||||
assessment of the votes.</para>
|
||||
|
||||
<para>The <literal>AccessDecisionVoter</literal> interface has three
|
||||
<para>The <interfacename>AccessDecisionVoter</interfacename> interface has three
|
||||
methods:
|
||||
<programlisting>
|
||||
int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
|
||||
|
@ -130,7 +130,7 @@ boolean supports(Class clazz);
|
|||
</programlisting>
|
||||
Concrete implementations return an <literal>int</literal>, with
|
||||
possible values being reflected in the
|
||||
<literal>AccessDecisionVoter</literal> static fields
|
||||
<interfacename>AccessDecisionVoter</interfacename> static fields
|
||||
<literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal>
|
||||
and <literal>ACCESS_GRANTED</literal>. A voting implementation will
|
||||
return <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an
|
||||
|
@ -139,7 +139,7 @@ boolean supports(Class clazz);
|
|||
<literal>ACCESS_GRANTED</literal>.</para>
|
||||
|
||||
<para>There are three concrete
|
||||
<literal>AccessDecisionManager</literal>s provided with Spring
|
||||
<interfacename>AccessDecisionManager</interfacename>s provided with Spring
|
||||
Security that tally the votes. The <literal>ConsensusBased</literal>
|
||||
implementation will grant or deny access based on the consensus of
|
||||
non-abstain votes. Properties are provided to control behavior in the
|
||||
|
@ -157,21 +157,21 @@ boolean supports(Class clazz);
|
|||
abstain.</para>
|
||||
|
||||
<para>It is possible to implement a custom
|
||||
<literal>AccessDecisionManager</literal> that tallies votes
|
||||
<interfacename>AccessDecisionManager</interfacename> that tallies votes
|
||||
differently. For example, votes from a particular
|
||||
<literal>AccessDecisionVoter</literal> might receive additional
|
||||
<interfacename>AccessDecisionVoter</interfacename> might receive additional
|
||||
weighting, whilst a deny vote from a particular voter may have a veto
|
||||
effect.</para>
|
||||
|
||||
<section>
|
||||
<title><classname>RoleVoter</classname></title>
|
||||
<para>
|
||||
The most commonly used <literal>AccessDecisionVoter</literal>
|
||||
The most commonly used <interfacename>AccessDecisionVoter</interfacename>
|
||||
provided with Spring Security is the simple <classname>RoleVoter</classname>, which treats
|
||||
configuration attributes as simple role names and votes to grant access if the user has been assigned
|
||||
that role.</para>
|
||||
<para>It will vote if any ConfigAttribute begins with the prefix <literal>ROLE_</literal>.
|
||||
It will vote to grant access if there is a <literal>GrantedAuthority</literal> which returns a
|
||||
It will vote to grant access if there is a <interfacename>GrantedAuthority</interfacename> which returns a
|
||||
<literal>String</literal> representation (via the
|
||||
<literal>getAuthority()</literal> method) exactly equal to one or more
|
||||
<literal>ConfigAttributes</literal> starting with
|
||||
|
@ -222,7 +222,7 @@ boolean supports(Class clazz);
|
|||
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
|
||||
<classname>MethodSecurityInterceptor</classname> 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
|
||||
|
@ -230,7 +230,7 @@ boolean supports(Class clazz);
|
|||
<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>.
|
||||
(ACL) that applies to the current <interfacename>Authentication</interfacename>.
|
||||
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
|
||||
|
@ -252,21 +252,21 @@ boolean supports(Class clazz);
|
|||
<section>
|
||||
<title>Custom Voters</title>
|
||||
<para>It is also possible to implement a custom
|
||||
<literal>AccessDecisionVoter</literal>. Several examples are provided
|
||||
<interfacename>AccessDecisionVoter</interfacename>. Several examples are provided
|
||||
in Spring Security unit tests, including
|
||||
<literal>ContactSecurityVoter</literal> and
|
||||
<literal>DenyVoter</literal>. The
|
||||
<literal>ContactSecurityVoter</literal> abstains from voting decisions
|
||||
where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
|
||||
<literal>ConfigAttribute</literal> is not found. If voting, it queries
|
||||
the <literal>MethodInvocation</literal> to extract the owner of the
|
||||
the <classname>MethodInvocation</classname> to extract the owner of the
|
||||
<literal>Contact</literal> object that is subject of the method call.
|
||||
It votes to grant access if the <literal>Contact</literal> owner
|
||||
matches the principal presented in the
|
||||
<literal>Authentication</literal> object. It could have just as easily
|
||||
<interfacename>Authentication</interfacename> object. It could have just as easily
|
||||
compared the <literal>Contact</literal> owner with some
|
||||
<literal>GrantedAuthority</literal> the
|
||||
<literal>Authentication</literal> object presented. All of this is
|
||||
<interfacename>GrantedAuthority</interfacename> the
|
||||
<interfacename>Authentication</interfacename> object presented. All of this is
|
||||
achieved with relatively few lines of code and demonstrates the
|
||||
flexibility of the authorization model.</para>
|
||||
</section>
|
||||
|
@ -276,8 +276,8 @@ boolean supports(Class clazz);
|
|||
|
||||
<section xml:id="after-invocation">
|
||||
<info><title>After Invocation Handling</title></info>
|
||||
<para>Whilst the <literal>AccessDecisionManager</literal> is called by
|
||||
the <literal>AbstractSecurityInterceptor</literal> before proceeding
|
||||
<para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by
|
||||
the <classname>AbstractSecurityInterceptor</classname> 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
|
||||
|
@ -317,21 +317,21 @@ boolean supports(Class clazz);
|
|||
<para>Please be aware that if you're using
|
||||
<literal>AfterInvocationManager</literal>, you will still need
|
||||
configuration attributes that allow the
|
||||
<literal>MethodSecurityInterceptor</literal>'s
|
||||
<literal>AccessDecisionManager</literal> to allow an operation. If
|
||||
<classname>MethodSecurityInterceptor</classname>'s
|
||||
<interfacename>AccessDecisionManager</interfacename> to allow an operation. If
|
||||
you're using the typical Spring Security included
|
||||
<literal>AccessDecisionManager</literal> implementations, having no
|
||||
<interfacename>AccessDecisionManager</interfacename> implementations, having no
|
||||
configuration attributes defined for a particular secure method
|
||||
invocation will cause each <literal>AccessDecisionVoter</literal> to
|
||||
invocation will cause each <interfacename>AccessDecisionVoter</interfacename> to
|
||||
abstain from voting. In turn, if the
|
||||
<literal>AccessDecisionManager</literal> property
|
||||
<interfacename>AccessDecisionManager</interfacename> property
|
||||
"<literal>allowIfAllAbstainDecisions</literal>" is
|
||||
<literal>false</literal>, an <literal>AccessDeniedException</literal>
|
||||
will be thrown. You may avoid this potential issue by either (i)
|
||||
setting "<literal>allowIfAllAbstainDecisions</literal>" to
|
||||
<literal>true</literal> (although this is generally not recommended)
|
||||
or (ii) simply ensure that there is at least one configuration
|
||||
attribute that an <literal>AccessDecisionVoter</literal> will vote to
|
||||
attribute that an <interfacename>AccessDecisionVoter</interfacename> will vote to
|
||||
grant access for. This latter (recommended) approach is usually
|
||||
achieved through a <literal>ROLE_USER</literal> or
|
||||
<literal>ROLE_AUTHENTICATED</literal> configuration attribute</para>
|
||||
|
@ -357,8 +357,8 @@ boolean supports(Class clazz);
|
|||
|
||||
<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
|
||||
situation the <interfacename>AccessDecisionManager</interfacename> approach
|
||||
provided by the <classname>AbstractSecurityInterceptor</classname> 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
|
||||
|
@ -381,10 +381,10 @@ boolean supports(Class clazz);
|
|||
<literal>AclEntryAfterInvocationProvider</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
|
||||
<interfacename>Authentication</interfacename>. The
|
||||
<literal>AclEntryAfterInvocationProvider</literal> queries the
|
||||
<literal>Acl</literal>Service to determine the ACL that applies for
|
||||
this domain object to this <literal>Authentication</literal>.</para>
|
||||
this domain object to this <interfacename>Authentication</interfacename>.</para>
|
||||
|
||||
<para>Similar to the
|
||||
<literal>AclEntryAfterInvocationProvider</literal> is
|
||||
|
@ -410,7 +410,7 @@ boolean supports(Class clazz);
|
|||
must be a <literal>Collection</literal> or array 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
|
||||
<interfacename>Authentication</interfacename> does not hold one of the listed
|
||||
<literal>requirePermission</literal>s.</para>
|
||||
|
||||
<para>The Contacts sample application demonstrates these two
|
||||
|
@ -437,8 +437,8 @@ boolean supports(Class clazz);
|
|||
|
||||
<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
|
||||
situation the <interfacename>AccessDecisionManager</interfacename> approach
|
||||
provided by the <classname>AbstractSecurityInterceptor</classname> 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
|
||||
|
@ -463,10 +463,10 @@ boolean supports(Class clazz);
|
|||
<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
|
||||
by the <interfacename>Authentication</interfacename>. 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>
|
||||
this domain object to this <interfacename>Authentication</interfacename>.</para>
|
||||
|
||||
<para>Similar to the
|
||||
<literal>BasicAclEntryAfterInvocationProvider</literal> is
|
||||
|
@ -492,7 +492,7 @@ boolean supports(Class clazz);
|
|||
must be a <literal>Collection</literal> or array 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
|
||||
<interfacename>Authentication</interfacename> does not hold one of the listed
|
||||
<literal>requirePermission</literal>s.</para>
|
||||
|
||||
<para>The Contacts sample application demonstrates these two
|
||||
|
@ -505,7 +505,7 @@ boolean supports(Class clazz);
|
|||
|
||||
<para><literal>AuthorizeTag</literal> is used to include content if
|
||||
the current principal holds certain
|
||||
<literal>GrantedAuthority</literal>s.</para>
|
||||
<interfacename>GrantedAuthority</interfacename>s.</para>
|
||||
|
||||
<para>The following JSP fragment illustrates how to use the
|
||||
<literal>AuthorizeTag</literal>:</para>
|
||||
|
|
|
@ -40,21 +40,21 @@
|
|||
|
||||
</programlisting></para>
|
||||
|
||||
<para>The configured <literal>AuthenticationManager</literal>
|
||||
<para>The configured <interfacename>AuthenticationManager</interfacename>
|
||||
processes each authentication request. If authentication fails, the
|
||||
configured <literal>AuthenticationEntryPoint</literal> will be used to
|
||||
configured <interfacename>AuthenticationEntryPoint</interfacename> will be used to
|
||||
retry the authentication process. Usually you will use the
|
||||
<literal>BasicProcessingFilterEntryPoint</literal>, which returns a
|
||||
401 response with a suitable header to retry HTTP Basic
|
||||
authentication. If authentication is successful, the resulting
|
||||
<literal>Authentication</literal> object will be placed into the
|
||||
<literal>SecurityContextHolder</literal>.</para>
|
||||
<interfacename>Authentication</interfacename> object will be placed into the
|
||||
<classname>SecurityContextHolder</classname>.</para>
|
||||
|
||||
<para>If the authentication event was successful, or authentication
|
||||
was not attempted because the HTTP header did not contain a supported
|
||||
authentication request, the filter chain will continue as normal. The
|
||||
only time the filter chain will be interrupted is if authentication
|
||||
fails and the <literal>AuthenticationEntryPoint</literal> is called,
|
||||
fails and the <interfacename>AuthenticationEntryPoint</interfacename> is called,
|
||||
as discussed in the previous paragraph</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -71,16 +71,16 @@
|
|||
<listitem>
|
||||
<para>The user eventually requests a page that is either secure or
|
||||
one of the beans it uses is secure. Spring Security's
|
||||
<literal>ExceptionTranslationFilter</literal> will detect the
|
||||
<classname>ExceptionTranslationFilter</classname> will detect the
|
||||
<literal>AuthenticationException</literal>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Because the user's <literal>Authentication</literal> object
|
||||
<para>Because the user's <interfacename>Authentication</interfacename> object
|
||||
(or lack thereof) caused an
|
||||
<literal>AuthenticationException</literal>, the
|
||||
<literal>ExceptionTranslationFilter</literal> will call the
|
||||
configured <literal>AuthenticationEntryPoint</literal>. If using
|
||||
<classname>ExceptionTranslationFilter</classname> will call the
|
||||
configured <interfacename>AuthenticationEntryPoint</interfacename>. If using
|
||||
CAS, this will be the
|
||||
<literal>CasProcessingFilterEntryPoint</literal> class.</para>
|
||||
</listitem>
|
||||
|
@ -126,11 +126,11 @@
|
|||
<literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>,
|
||||
whilst the credentials will be the service ticket opaque value.
|
||||
This authentication request will then be handed to the configured
|
||||
<literal>AuthenticationManager</literal>.</para>
|
||||
<interfacename>AuthenticationManager</interfacename>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <literal>AuthenticationManager</literal> implementation
|
||||
<para>The <interfacename>AuthenticationManager</interfacename> implementation
|
||||
will be the <literal>ProviderManager</literal>, which is in turn
|
||||
configured with the <literal>CasAuthenticationProvider</literal>.
|
||||
The <literal>CasAuthenticationProvider</literal> only responds to
|
||||
|
@ -205,18 +205,18 @@
|
|||
<listitem>
|
||||
<para><literal>CasAuthenticationProvider</literal> will next
|
||||
request a <literal>CasAuthoritiesPopulator</literal> to advise the
|
||||
<literal>GrantedAuthority</literal> objects that apply to the user
|
||||
<interfacename>GrantedAuthority</interfacename> objects that apply to the user
|
||||
contained in the <literal>TicketResponse</literal>. Spring
|
||||
Security includes a <literal>DaoCasAuthoritiesPopulator</literal>
|
||||
which simply uses the <literal>UserDetailsService</literal>
|
||||
infrastructure to find the <literal>UserDetails</literal> and
|
||||
their associated <literal>GrantedAuthority</literal>s. Note that
|
||||
which simply uses the <interfacename>UserDetailsService</interfacename>
|
||||
infrastructure to find the <interfacename>UserDetails</interfacename> and
|
||||
their associated <interfacename>GrantedAuthority</interfacename>s. Note that
|
||||
the password and enabled/disabled status of
|
||||
<literal>UserDetails</literal> returned by the
|
||||
<literal>UserDetailsService</literal> are ignored, as the CAS
|
||||
<interfacename>UserDetails</interfacename> returned by the
|
||||
<interfacename>UserDetailsService</interfacename> are ignored, as the CAS
|
||||
server is responsible for authentication decisions.
|
||||
<literal>DaoCasAuthoritiesPopulator</literal> is only concerned
|
||||
with retrieving the <literal>GrantedAuthority</literal>s.</para>
|
||||
with retrieving the <interfacename>GrantedAuthority</interfacename>s.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
@ -224,7 +224,7 @@
|
|||
<literal>CasAuthenticationProvider</literal> constructs a
|
||||
<literal>CasAuthenticationToken</literal> including the details
|
||||
contained in the <literal>TicketResponse</literal> and the
|
||||
<literal>GrantedAuthority</literal>s. The
|
||||
<interfacename>GrantedAuthority</interfacename>s. The
|
||||
<literal>CasAuthenticationToken</literal> contains the hash of a
|
||||
key, so that the <literal>CasAuthenticationProvider</literal>
|
||||
knows it created it.</para>
|
||||
|
@ -244,12 +244,12 @@
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>As the <literal>Authentication</literal> object is now in
|
||||
<para>As the <interfacename>Authentication</interfacename> object is now in
|
||||
the well-known location, it is handled like any other
|
||||
authentication approach. Usually the
|
||||
<literal>HttpSessionContextIntegrationFilter</literal> will be
|
||||
used to associate the <literal>Authentication</literal> object
|
||||
with the <literal>SecurityContextHolder</literal> for the duration
|
||||
<classname>HttpSessionContextIntegrationFilter</classname> will be
|
||||
used to associate the <interfacename>Authentication</interfacename> object
|
||||
with the <classname>SecurityContextHolder</classname> for the duration
|
||||
of each request.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
@ -323,7 +323,7 @@
|
|||
<literal>CasProcessingFilter</literal> needs a reference to it.</para>
|
||||
|
||||
<para>For CAS to operate, the
|
||||
<literal>ExceptionTranslationFilter</literal> must have its
|
||||
<classname>ExceptionTranslationFilter</classname> must have its
|
||||
<literal>authenticationEntryPoint</literal> property set to the
|
||||
<literal>CasProcessingFilterEntryPoint</literal> bean.</para>
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<bean id="secureChannelProcessor" class="org.springframework.security.securechannel.SecureChannelProcessor"/>
|
||||
<bean id="insecureChannelProcessor" class="org.springframework.security.securechannel.InsecureChannelProcessor"/>]]>
|
||||
</programlisting>
|
||||
Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
|
||||
Like <classname>FilterSecurityInterceptor</classname>, Apache Ant
|
||||
style paths are also supported by the
|
||||
<literal>ChannelProcessingFilter</literal>.</para>
|
||||
|
||||
|
@ -146,15 +146,15 @@
|
|||
|
||||
<para>To decide whether a security check belongs in a
|
||||
<literal>ChannelProcessor</literal> or an
|
||||
<literal>AccessDecisionVoter</literal>, remember that the former is
|
||||
<interfacename>AccessDecisionVoter</interfacename>, remember that the former is
|
||||
designed to handle unauthenticated requests, whilst the latter is
|
||||
designed to handle authenticated requests. The latter therefore has
|
||||
access to the granted authorities of the authenticated principal. In
|
||||
addition, problems detected by a <literal>ChannelProcessor</literal>
|
||||
will generally cause an HTTP/HTTPS redirection so its requirements can
|
||||
be met, whilst problems detected by an
|
||||
<literal>AccessDecisionVoter</literal> will ultimately result in an
|
||||
<interfacename>AccessDecisionVoter</interfacename> will ultimately result in an
|
||||
<literal>AccessDeniedException</literal> (depending on the governing
|
||||
<literal>AccessDecisionManager</literal>).</para>
|
||||
<interfacename>AccessDecisionManager</interfacename>).</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
<para>To use Spring Security's authentication services,
|
||||
you'll usually need to configure a web filter, together
|
||||
with an <literal>AuthenticationProvider</literal> and
|
||||
<literal>AuthenticationEntryPoint</literal>. In this section we are
|
||||
with an <classname>AuthenticationProvider</classname> and
|
||||
<interfacename>AuthenticationEntryPoint</interfacename>. In this section we are
|
||||
going to explore an example application that needs to support both
|
||||
form-based authentication (so a nice HTML page is presented to a
|
||||
user for them to login) and BASIC authentication (so a web service
|
||||
|
@ -81,8 +81,8 @@
|
|||
each of these authentication mechanisms.</para>
|
||||
|
||||
<para>Recall that
|
||||
<literal>HttpSessionContextIntegrationFilter</literal> keeps the
|
||||
contents of the <literal>SecurityContext</literal> between invocations
|
||||
<classname>HttpSessionContextIntegrationFilter</classname> keeps the
|
||||
contents of the <interfacename>SecurityContext</interfacename> between invocations
|
||||
inside an HTTP session. This means the authentication mechanisms are
|
||||
only used once, being when the principal initially tries to
|
||||
authenticate. The rest of the time the authentication mechanisms sit
|
||||
|
@ -97,13 +97,13 @@
|
|||
|
||||
<para>The major authorization provider for secure objects has
|
||||
previously been introduced as
|
||||
<literal>AbstractSecurityInterceptor</literal>. This class needs to
|
||||
have access to an <literal>AuthenticationManager</literal>. It also
|
||||
<classname>AbstractSecurityInterceptor</classname>. This class needs to
|
||||
have access to an <interfacename>AuthenticationManager</interfacename>. It also
|
||||
has configurable settings to indicate whether an
|
||||
<literal>Authentication</literal> object should be re-authenticated on
|
||||
<interfacename>Authentication</interfacename> object should be re-authenticated on
|
||||
each secure object invocation. By default it just accepts any
|
||||
<literal>Authentication</literal> inside the
|
||||
<literal>SecurityContextHolder</literal> is authenticated if
|
||||
<interfacename>Authentication</interfacename> inside the
|
||||
<classname>SecurityContextHolder</classname> is authenticated if
|
||||
<literal>Authentication.isAuthenticated()</literal> returns true. This
|
||||
is great for performance, but not ideal if you want to ensure
|
||||
up-to-the-moment authentication validity. For such cases you'll
|
||||
|
@ -112,9 +112,9 @@
|
|||
property to true.</para>
|
||||
|
||||
<para>You might be asking yourself, "what's this
|
||||
<literal>AuthenticationManager</literal>?". We haven't explored it
|
||||
<interfacename>AuthenticationManager</interfacename>?". We haven't explored it
|
||||
before, but we have discussed the concept of an
|
||||
<literal>AuthenticationProvider</literal>. Quite simply, an
|
||||
<classname>AuthenticationProvider</classname>. Quite simply, an
|
||||
<interfacename>AuthenticationManager</interfacename> is responsible
|
||||
for passing requests through a chain of AuthenticationProviders. It's
|
||||
a little like the filter chain we discussed earlier, although there
|
||||
|
@ -137,11 +137,11 @@
|
|||
<para>It's probably worth mentioning at this point that your
|
||||
authentication mechanisms (which are usually filters) are also
|
||||
injected with a reference to the
|
||||
<literal>AuthenticationManager</literal>. So both
|
||||
<literal>AbstractSecurityInterceptor</literal> as well as the
|
||||
<interfacename>AuthenticationManager</interfacename>. So both
|
||||
<classname>AbstractSecurityInterceptor</classname> as well as the
|
||||
authentication mechanisms will use the above
|
||||
<literal>ProviderManager</literal> to poll a list of
|
||||
<literal>AuthenticationProvider</literal>s.</para>
|
||||
<classname>AuthenticationProvider</classname>s.</para>
|
||||
|
||||
<para>In our example we have three providers. They are tried in the
|
||||
order shown (which is implied by the use of a <literal>List</literal>
|
||||
|
@ -161,7 +161,7 @@
|
|||
limited to) BASIC and form authentication. Equally, some
|
||||
authentication mechanisms create an authentication request object
|
||||
which can only be interpreted by a single type of
|
||||
<literal>AuthenticationProvider</literal>. An example of this
|
||||
<classname>AuthenticationProvider</classname>. An example of this
|
||||
one-to-one mapping would be JA-SIG CAS, which uses the notion of a
|
||||
service ticket which can therefore only be authenticated by
|
||||
<literal>CasAuthenticationProvider</literal>. A further example of a
|
||||
|
@ -176,11 +176,11 @@
|
|||
to authenticate is made.</para>
|
||||
|
||||
<para>After configuring the correct authentication mechanisms in the
|
||||
<literal>FilterChainProxy</literal>, and ensuring that a corresponding
|
||||
<literal>AuthenticationProvider</literal> is registered in the
|
||||
<classname>FilterChainProxy</classname>, and ensuring that a corresponding
|
||||
<classname>AuthenticationProvider</classname> is registered in the
|
||||
<literal>ProviderManager</literal>, your last step is to configure an
|
||||
<literal>AuthenticationEntryPoint</literal>. Recall that earlier we
|
||||
discussed the role of <literal>ExceptionTranslationFilter</literal>,
|
||||
<interfacename>AuthenticationEntryPoint</interfacename>. Recall that earlier we
|
||||
discussed the role of <classname>ExceptionTranslationFilter</classname>,
|
||||
which is used when HTTP-based requests should receive back an HTTP
|
||||
header or HTTP redirect in order to start authentication. Continuing
|
||||
on with our earlier example:</para>
|
||||
|
@ -202,12 +202,12 @@
|
|||
<property name="forceHttps">< value="false"/>
|
||||
</bean>]]></programlisting></para>
|
||||
|
||||
<para>Notice that the <literal>ExceptionTranslationFilter</literal>
|
||||
<para>Notice that the <classname>ExceptionTranslationFilter</classname>
|
||||
requires two collaborators. The first,
|
||||
<literal>AccessDeniedHandlerImpl</literal>, uses a
|
||||
<literal>RequestDispatcher</literal> forward to display the specified
|
||||
access denied error page. We use a forward so that the
|
||||
<literal>SecurityContextHolder</literal> still contains details of the
|
||||
<classname>SecurityContextHolder</classname> still contains details of the
|
||||
principal, which may be useful for display to the user (in old
|
||||
releases of Spring Security we relied upon the servlet container to
|
||||
handle a 403 error message, which lacked this useful contextual
|
||||
|
@ -221,7 +221,7 @@
|
|||
<literal>AuthenticationProcessinFilterEntryPoint</literal> and the URL
|
||||
of the login page. Your application will usually only have one entry
|
||||
point, and most authentication approaches define their own specific
|
||||
<literal>AuthenticationEntryPoint</literal>. Details of which entry
|
||||
<interfacename>AuthenticationEntryPoint</interfacename>. Details of which entry
|
||||
point to use for each authentication approach is discussed in the
|
||||
authentication approach-specific chapters of this reference
|
||||
guide.</para>
|
||||
|
@ -233,43 +233,43 @@
|
|||
|
||||
<para>As mentioned in the first part of the reference guide, most
|
||||
authentication providers take advantage of the
|
||||
<literal>UserDetails</literal> and
|
||||
<literal>UserDetailsService</literal> interfaces. The contract for
|
||||
<interfacename>UserDetails</interfacename> and
|
||||
<interfacename>UserDetailsService</interfacename> interfaces. The contract for
|
||||
this latter interface consists of a single method:</para>
|
||||
|
||||
<para><programlisting>
|
||||
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
|
||||
</programlisting></para>
|
||||
|
||||
<para>The returned <literal>UserDetails</literal> is an interface that
|
||||
<para>The returned <interfacename>UserDetails</interfacename> is an interface that
|
||||
provides getters that guarantee non-null provision of basic
|
||||
authentication information such as the username, password, granted
|
||||
authorities and whether the user is enabled or disabled. Most
|
||||
authentication providers will use a
|
||||
<literal>UserDetailsService</literal>, even if the username and
|
||||
<interfacename>UserDetailsService</interfacename>, even if the username and
|
||||
password are not actually used as part of the authentication decision.
|
||||
Generally such providers will be using the returned
|
||||
<literal>UserDetails</literal> object just for its
|
||||
<interfacename>UserDetails</interfacename> object just for its
|
||||
<literal>GrantedAuthority[]</literal> information, because some other
|
||||
system (like LDAP or X509 or CAS etc) has undertaken the
|
||||
responsibility of actually validating the credentials.</para>
|
||||
|
||||
<para>A single concrete implementation of
|
||||
<literal>UserDetails</literal> is provided with Spring Security, being
|
||||
<interfacename>UserDetails</interfacename> is provided with Spring Security, being
|
||||
the <literal>User</literal> class. Spring Security users will need to
|
||||
decide when writing their <literal>UserDetailsService</literal> what
|
||||
concrete <literal>UserDetails</literal> class to return. In most cases
|
||||
decide when writing their <interfacename>UserDetailsService</interfacename> what
|
||||
concrete <interfacename>UserDetails</interfacename> class to return. In most cases
|
||||
<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
|
||||
users to write their own <interfacename>UserDetails</interfacename> implementation
|
||||
from scratch. This is not such an unusual situation, and users should
|
||||
not hesitate to simply return their normal domain object that
|
||||
represents a user of the system. This is especially common given that
|
||||
<literal>UserDetails</literal> is often used to store additional
|
||||
<interfacename>UserDetails</interfacename> is often used to store additional
|
||||
principal-related properties (such as their telephone number and email
|
||||
address), so that they can be easily used by web views.</para>
|
||||
|
||||
<para>Given <literal>UserDetailsService</literal> is so simple to
|
||||
<para>Given <interfacename>UserDetailsService</interfacename> is so simple to
|
||||
implement, it should be easy for users to retrieve authentication
|
||||
information using a persistence strategy of their choice. Having said
|
||||
that, Spring Security does include a couple of useful base
|
||||
|
@ -278,12 +278,12 @@
|
|||
<section xml:id="in-memory-service">
|
||||
<info><title>In-Memory Authentication</title></info>
|
||||
<para>Whilst it is easy to use create a custom
|
||||
<literal>UserDetailsService</literal> implementation that extracts
|
||||
<interfacename>UserDetailsService</interfacename> implementation that extracts
|
||||
information from a persistence engine of choice, many applications
|
||||
do not require such complexity. This is particularly true if you're
|
||||
undertaking a rapid prototype or just starting integrating Spring
|
||||
Security, when you don't really want to spend time configuring
|
||||
databases or writing <literal>UserDetailsService</literal>
|
||||
databases or writing <interfacename>UserDetailsService</interfacename>
|
||||
implementations. For this sort of situation, a simple option is to
|
||||
use the <literal>user-service</literal> element from the security
|
||||
<link xlink:href="#namespace-minimal" >namespace</link>:
|
||||
|
@ -316,7 +316,7 @@
|
|||
<title>JDBC Authentication</title>
|
||||
</info>
|
||||
<para>Spring Security also includes a
|
||||
<literal>UserDetailsService</literal> that can obtain authentication
|
||||
<interfacename>UserDetailsService</interfacename> that can obtain authentication
|
||||
information from a JDBC data source. Internally Spring JDBC is used,
|
||||
so it avoids the complexity of a fully-featured object relational
|
||||
mapper (ORM) just to store user details. If your application does
|
||||
|
@ -372,9 +372,9 @@
|
|||
customisation of the SQL statements. Please refer to the JavaDocs for
|
||||
details, but note that the class is not intended for complex custom subclasses.
|
||||
If you have a complex schema or would like a
|
||||
custom <literal>UserDetails</literal> implementation returned,
|
||||
custom <interfacename>UserDetails</interfacename> implementation returned,
|
||||
you'd be better off writing your own
|
||||
<literal>UserDetailsService</literal>. The base implementation
|
||||
<interfacename>UserDetailsService</interfacename>. The base implementation
|
||||
provided with Spring Security is intended for typical situations,
|
||||
rather than catering for all possible requirements.</para>
|
||||
</section>
|
||||
|
@ -403,7 +403,7 @@
|
|||
|
||||
<para>In addition, you will need to add the
|
||||
<literal>org.springframework.security.concurrent.ConcurrentSessionFilter</literal>
|
||||
to your <literal>FilterChainProxy</literal>. The
|
||||
to your <classname>FilterChainProxy</classname>. The
|
||||
<classname>ConcurrentSessionFilter</classname> requires two
|
||||
properties, <literal>sessionRegistry</literal>, which generally points
|
||||
to an instance of <literal>SessionRegistryImpl</literal>, and
|
||||
|
@ -446,7 +446,7 @@
|
|||
<info><title>Authentication Tag Libraries</title></info>
|
||||
|
||||
<para><literal>AuthenticationTag</literal> is used to simply output a
|
||||
property of the current <literal>Authentication</literal> object to the web
|
||||
property of the current <interfacename>Authentication</interfacename> object to the web
|
||||
page.</para>
|
||||
|
||||
<para>The following JSP fragment illustrates how to use the
|
||||
|
@ -456,8 +456,8 @@
|
|||
|
||||
<para>This tag would cause the principal's name to be output. Here we
|
||||
are assuming the <literal>Authentication.getPrincipal()</literal> is a
|
||||
<literal>UserDetails</literal> object, which is generally the case
|
||||
when using one of Spring Security's stadard <literal>AuthenticationProvider</literal>
|
||||
<interfacename>UserDetails</interfacename> object, which is generally the case
|
||||
when using one of Spring Security's stadard <classname>AuthenticationProvider</classname>
|
||||
implementations.</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -48,18 +48,18 @@
|
|||
|
||||
|
||||
<para>As is always the case, the container adapter generated
|
||||
<literal>Authentication</literal> object still needs to be
|
||||
authenticated by an <literal>AuthenticationManager</literal> when
|
||||
<interfacename>Authentication</interfacename> object still needs to be
|
||||
authenticated by an <interfacename>AuthenticationManager</interfacename> when
|
||||
requested to do so by the
|
||||
<literal>AbstractSecurityInterceptor</literal>. The
|
||||
<literal>AuthenticationManager</literal> needs to be certain the
|
||||
adapter-provided <literal>Authentication</literal> object is valid and
|
||||
<classname>AbstractSecurityInterceptor</classname>. The
|
||||
<interfacename>AuthenticationManager</interfacename> needs to be certain the
|
||||
adapter-provided <interfacename>Authentication</interfacename> object is valid and
|
||||
was actually authenticated by a trusted adapter.</para>
|
||||
|
||||
<para>Adapters create <literal>Authentication</literal> objects which
|
||||
<para>Adapters create <interfacename>Authentication</interfacename> objects which
|
||||
are immutable and implement the <literal>AuthByAdapter</literal>
|
||||
interface. These objects store the hash of a key that is defined by
|
||||
the adapter. This allows the <literal>Authentication</literal> object
|
||||
the adapter. This allows the <interfacename>Authentication</interfacename> object
|
||||
to be validated by the <literal>AuthByAdapterProvider</literal>. This
|
||||
authentication provider is defined as follows:</para>
|
||||
|
||||
|
@ -80,13 +80,13 @@
|
|||
<literal>AuthByAdapter</literal> instance that contains a hash code of
|
||||
the key. Later, when an application calls a security interceptor
|
||||
managed resource, the <literal>AuthByAdapter</literal> instance in the
|
||||
<literal>SecurityContext</literal> in the
|
||||
<literal>SecurityContextHolder</literal> will be tested by the
|
||||
<interfacename>SecurityContext</interfacename> in the
|
||||
<classname>SecurityContextHolder</classname> will be tested by the
|
||||
application's <literal>AuthByAdapterProvider</literal>. There is no
|
||||
requirement for additional authentication providers such as
|
||||
<literal>DaoAuthenticationProvider</literal> within the
|
||||
application-specific application context, as the only type of
|
||||
<literal>Authentication</literal> instance that will be presented by
|
||||
<interfacename>Authentication</interfacename> instance that will be presented by
|
||||
the application is from the container adapter.</para>
|
||||
|
||||
<para>Classloader issues are frequent with containers and the use of
|
||||
|
@ -206,7 +206,7 @@
|
|||
<para>In this configuration <literal>acegisecurity.xml</literal>
|
||||
contains the spring context definition including all the
|
||||
authentication manager beans. You have to bear in mind though, that
|
||||
<literal>SecurityContext</literal> is created and destroyed on each
|
||||
<interfacename>SecurityContext</interfacename> is created and destroyed on each
|
||||
login request, so the login operation might become costly.
|
||||
Alternatively, the second approach is to use Spring singleton
|
||||
capabilities through
|
||||
|
@ -230,7 +230,7 @@
|
|||
<para>In the above code fragment,
|
||||
<literal>authenticationManager</literal> is a helper property that
|
||||
defines the expected name of the
|
||||
<literal>AuthenticationManager</literal> in case you have several
|
||||
<interfacename>AuthenticationManager</interfacename> in case you have several
|
||||
defined in the IoC container. The <literal>singletonId</literal>
|
||||
property references a bean defined in a
|
||||
<literal>beanRefFactory.xml</literal> file. This file needs to be
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<info><title>Overview</title></info>
|
||||
|
||||
<para>Spring Security includes a production-quality
|
||||
<literal>AuthenticationProvider</literal> implementation called
|
||||
<classname>AuthenticationProvider</classname> implementation called
|
||||
<literal>DaoAuthenticationProvider</literal>. This authentication
|
||||
provider is compatible with all of the authentication mechanisms that
|
||||
generate a <literal>UsernamePasswordAuthenticationToken</literal>, and
|
||||
|
@ -43,8 +43,8 @@
|
|||
<para>The <literal>PasswordEncoder</literal> and
|
||||
<literal>SaltSource</literal> are optional. A
|
||||
<literal>PasswordEncoder</literal> provides encoding and decoding of
|
||||
passwords presented in the <literal>UserDetails</literal> object that
|
||||
is returned from the configured <literal>UserDetailsService</literal>.
|
||||
passwords presented in the <interfacename>UserDetails</interfacename> object that
|
||||
is returned from the configured <interfacename>UserDetailsService</interfacename>.
|
||||
A <literal>SaltSource</literal> enables the passwords to be populated
|
||||
with a "salt", which enhances the security of the passwords in the
|
||||
authentication repository. <literal>PasswordEncoder</literal>
|
||||
|
@ -54,15 +54,15 @@
|
|||
<literal>SystemWideSaltSource</literal> which encodes all passwords
|
||||
with the same salt, and <literal>ReflectionSaltSource</literal>, which
|
||||
inspects a given property of the returned
|
||||
<literal>UserDetails</literal> object to obtain the salt. Please refer
|
||||
<interfacename>UserDetails</interfacename> object to obtain the salt. Please refer
|
||||
to the JavaDocs for further details on these optional features.</para>
|
||||
|
||||
<para>In addition to the properties above, the
|
||||
<literal>DaoAuthenticationProvider</literal> supports optional caching
|
||||
of <literal>UserDetails</literal> objects. The
|
||||
of <interfacename>UserDetails</interfacename> objects. The
|
||||
<literal>UserCache</literal> interface enables the
|
||||
<literal>DaoAuthenticationProvider</literal> to place a
|
||||
<literal>UserDetails</literal> object into the cache, and retrieve it
|
||||
<interfacename>UserDetails</interfacename> object into the cache, and retrieve it
|
||||
from the cache upon subsequent authentication attempts for the same
|
||||
username. By default the <literal>DaoAuthenticationProvider</literal>
|
||||
uses the <literal>NullUserCache</literal>, which performs no caching.
|
||||
|
@ -105,19 +105,19 @@
|
|||
|
||||
<para>A design decision was made not to support account locking in the
|
||||
<literal>DaoAuthenticationProvider</literal>, as doing so would have
|
||||
increased the complexity of the <literal>UserDetailsService</literal>
|
||||
increased the complexity of the <interfacename>UserDetailsService</interfacename>
|
||||
interface. For instance, a method would be required to increase the
|
||||
count of unsuccessful authentication attempts. Such functionality
|
||||
could be easily provided by leveraging the application event
|
||||
publishing features discussed below.</para>
|
||||
|
||||
<para><literal>DaoAuthenticationProvider</literal> returns an
|
||||
<literal>Authentication</literal> object which in turn has its
|
||||
<interfacename>Authentication</interfacename> object which in turn has its
|
||||
<literal>principal</literal> property set. The principal will be
|
||||
either a <literal>String</literal> (which is essentially the username)
|
||||
or a <literal>UserDetails</literal> object (which was looked up from
|
||||
the <literal>UserDetailsService</literal>). By default the
|
||||
<literal>UserDetails</literal> is returned, as this enables
|
||||
or a <interfacename>UserDetails</interfacename> object (which was looked up from
|
||||
the <interfacename>UserDetailsService</interfacename>). By default the
|
||||
<interfacename>UserDetails</interfacename> is returned, as this enables
|
||||
applications to add extra properties potentially of use in
|
||||
applications, such as the user's full name, email address etc. If
|
||||
using container adapters, or if your applications were written to
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
|
||||
</programlisting></para>
|
||||
|
||||
<para>The configured <literal>UserDetailsService</literal> is needed
|
||||
<para>The configured <interfacename>UserDetailsService</interfacename> is needed
|
||||
because <literal>DigestProcessingFilter</literal> must have direct
|
||||
access to the clear text password of a user. Digest Authentication
|
||||
will NOT work if you are using encoded passwords in your DAO. The DAO
|
||||
|
@ -121,14 +121,14 @@
|
|||
calculations.</para>
|
||||
|
||||
<para>Like <literal>BasicAuthenticationFilter</literal>, if
|
||||
authentication is successful an <literal>Authentication</literal>
|
||||
authentication is successful an <interfacename>Authentication</interfacename>
|
||||
request token will be placed into the
|
||||
<literal>SecurityContextHolder</literal>. If the authentication event
|
||||
<classname>SecurityContextHolder</classname>. If the authentication event
|
||||
was successful, or authentication was not attempted because the HTTP
|
||||
header did not contain a Digest Authentication request, the filter
|
||||
chain will continue as normal. The only time the filter chain will be
|
||||
interrupted is if authentication fails and the
|
||||
<literal>AuthenticationEntryPoint</literal> is called, as discussed in
|
||||
<interfacename>AuthenticationEntryPoint</interfacename> is called, as discussed in
|
||||
the previous paragraph.</para>
|
||||
|
||||
<para>Digest Authentication's RFC offers a range of additional
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
<literal>org.springframework.security.acls</literal> package.</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 (<literal>Authentication</literal>), where
|
||||
(<literal>MethodInvocation</literal>) and what (<literal>SomeDomainObject</literal>). In
|
||||
comprise both who (<interfacename>Authentication</interfacename>), where
|
||||
(<classname>MethodInvocation</classname>) and what (<literal>SomeDomainObject</literal>). In
|
||||
other words, authorization decisions also need to consider the actual domain object
|
||||
instance subject of a method invocation.</para>
|
||||
<para>Imagine you're designing an application for a pet clinic. There will be two main
|
||||
|
@ -32,21 +32,21 @@
|
|||
collection within the <literal>Customer</literal> domain object instance to
|
||||
determine which users have access. By using the
|
||||
<literal>SecurityContextHolder.getContext().getAuthentication()</literal>,
|
||||
you'll be able to access the <literal>Authentication</literal>
|
||||
you'll be able to access the <interfacename>Authentication</interfacename>
|
||||
object.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Write an <literal>AccessDecisionVoter</literal> to enforce the security
|
||||
<para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security
|
||||
from the <literal>GrantedAuthority[]</literal>s stored in the
|
||||
<literal>Authentication</literal> object. This would mean your
|
||||
<literal>AuthenticationManager</literal> would need to populate the
|
||||
<literal>Authentication</literal> with custom
|
||||
<literal>GrantedAuthority</literal>[]s representing each of the
|
||||
<interfacename>Authentication</interfacename> object. This would mean your
|
||||
<interfacename>AuthenticationManager</interfacename> would need to populate the
|
||||
<interfacename>Authentication</interfacename> with custom
|
||||
<interfacename>GrantedAuthority</interfacename>[]s representing each of the
|
||||
<literal>Customer</literal> domain object instances the principal has
|
||||
access to.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Write an <literal>AccessDecisionVoter</literal> to enforce the security
|
||||
<para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security
|
||||
and open the target <literal>Customer</literal> domain object directly. This
|
||||
would mean your voter needs access to a DAO that allows it to retrieve the
|
||||
<literal>Customer</literal> object. It would then access the
|
||||
|
@ -58,16 +58,16 @@
|
|||
authorization checking to your business code. The main problems with this include the
|
||||
enhanced difficulty of unit testing and the fact it would be more difficult to reuse the
|
||||
<literal>Customer</literal> authorization logic elsewhere. Obtaining the
|
||||
<literal>GrantedAuthority[]</literal>s from the <literal>Authentication</literal>
|
||||
<literal>GrantedAuthority[]</literal>s from the <interfacename>Authentication</interfacename>
|
||||
object is also fine, but will not scale to large numbers of
|
||||
<literal>Customer</literal>s. If a user might be able to access 5,000
|
||||
<literal>Customer</literal>s (unlikely in this case, but imagine if it were a popular
|
||||
vet for a large Pony Club!) the amount of memory consumed and time required to construct
|
||||
the <literal>Authentication</literal> object would be undesirable. The final method,
|
||||
the <interfacename>Authentication</interfacename> object would be undesirable. The final method,
|
||||
opening the <literal>Customer</literal> directly from external code, is probably the
|
||||
best of the three. It achieves separation of concerns, and doesn't misuse memory or CPU
|
||||
cycles, but it is still inefficient in that both the
|
||||
<literal>AccessDecisionVoter</literal> and the eventual business method itself will
|
||||
<interfacename>AccessDecisionVoter</interfacename> and the eventual business method itself will
|
||||
perform a call to the DAO responsible for retrieving the <literal>Customer</literal>
|
||||
object. Two accesses per method invocation is clearly undesirable. In addition, with
|
||||
every approach listed you'll need to write your own access control list (ACL)
|
||||
|
@ -119,8 +119,8 @@
|
|||
system ("SID" stands for "security identity"). The only columns are the ID,
|
||||
a textual representation of the SID, and a flag to indicate whether the
|
||||
textual representation refers to a prncipal name or a
|
||||
<literal>GrantedAuthority</literal>. Thus, there is a single row for
|
||||
each unique principal or <literal>GrantedAuthority</literal>. When used in
|
||||
<interfacename>GrantedAuthority</interfacename>. Thus, there is a single row for
|
||||
each unique principal or <interfacename>GrantedAuthority</interfacename>. When used in
|
||||
the context of receiving a permission, a SID is generally called a
|
||||
"recipient".</para>
|
||||
</listitem>
|
||||
|
@ -193,7 +193,7 @@
|
|||
<literal>GrantedAuthority[]</literal>s. A level of indirection is provided
|
||||
by the <literal>Sid</literal> interface, which is an abbreviation of "security
|
||||
identity". Common classes include <literal>PrincipalSid</literal> (to represent
|
||||
the principal inside an <literal>Authentication</literal> object) and
|
||||
the principal inside an <interfacename>Authentication</interfacename> object) and
|
||||
<literal>GrantedAuthoritySid</literal>. The security identity information is
|
||||
stored in the ACL_SID table.</para>
|
||||
</listitem>
|
||||
|
@ -289,7 +289,7 @@ aclService.updateAcl(acl);
|
|||
<para>Once you've used the above techniques to store some ACL information in the database,
|
||||
the next step is to actually use the ACL information as part of authorization decision
|
||||
logic. You have a number of choices here. You could write your own
|
||||
<literal>AccessDecisionVoter</literal> or <literal>AfterInvocationProvider</literal>
|
||||
<interfacename>AccessDecisionVoter</interfacename> or <literal>AfterInvocationProvider</literal>
|
||||
that respectively fires before or after a method invocation. Such classes would use
|
||||
<literal>AclService</literal> to retrieve the relevant ACL and then call
|
||||
<literal>Acl.isGranted(Permission[] permission, Sid[] sids, boolean
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</bean> ]]>
|
||||
</programlisting></para>
|
||||
|
||||
<para>The configured <literal>AuthenticationManager</literal>
|
||||
<para>The configured <interfacename>AuthenticationManager</interfacename>
|
||||
processes each authentication request. If authentication fails, the
|
||||
browser will be redirected to the
|
||||
<literal>authenticationFailureUrl</literal>. The
|
||||
|
@ -40,15 +40,15 @@
|
|||
enabling a reason to be provided to the user on the error page.</para>
|
||||
|
||||
<para>If authentication is successful, the resulting
|
||||
<literal>Authentication</literal> object will be placed into the
|
||||
<literal>SecurityContextHolder</literal>.</para>
|
||||
<interfacename>Authentication</interfacename> object will be placed into the
|
||||
<classname>SecurityContextHolder</classname>.</para>
|
||||
|
||||
<para>Once the <literal>SecurityContextHolder</literal> has been
|
||||
<para>Once the <classname>SecurityContextHolder</classname> has been
|
||||
updated, the browser will need to be redirected to the target URL which
|
||||
is usually indicated by the <literal>HttpSession</literal> attribute stored under
|
||||
<literal>AbstractProcessingFilter.SPRING_SECURITY_TARGET_URL_KEY</literal>.
|
||||
This attribute is automatically set by the
|
||||
<literal>ExceptionTranslationFilter</literal> when an
|
||||
<classname>ExceptionTranslationFilter</classname> when an
|
||||
<literal>AuthenticationException</literal> occurs, so that after login
|
||||
is completed the user can return to what they were originally trying to access.
|
||||
If for some reason the <literal>HttpSession</literal> does not
|
||||
|
|
|
@ -64,7 +64,7 @@ JAASTest {
|
|||
mechanism). Thus, by the time the authentication request is
|
||||
delegated through to JAAS, Spring Security's authentication
|
||||
mechanism will already have fully-populated an
|
||||
<literal>Authentication</literal> object containing all the
|
||||
<interfacename>Authentication</interfacename> object containing all the
|
||||
information required by the JAAS
|
||||
<literal>LoginModule</literal>.</para>
|
||||
|
||||
|
@ -97,9 +97,9 @@ JAASTest {
|
|||
|
||||
<para>JAAS works with principals. Even "roles" are represented as
|
||||
principals in JAAS. Spring Security, on the other hand, works with
|
||||
<literal>Authentication</literal> objects. Each
|
||||
<literal>Authentication</literal> object contains a single
|
||||
principal, and multiple <literal>GrantedAuthority</literal>[]s. To
|
||||
<interfacename>Authentication</interfacename> objects. Each
|
||||
<interfacename>Authentication</interfacename> object contains a single
|
||||
principal, and multiple <interfacename>GrantedAuthority</interfacename>[]s. To
|
||||
facilitate mapping between these different concepts, Spring
|
||||
Security's JAAS package includes an
|
||||
<literal>AuthorityGranter</literal> interface.</para>
|
||||
|
@ -109,7 +109,7 @@ JAASTest {
|
|||
<literal>String</literal>. The
|
||||
<literal>JaasAuthenticationProvider</literal> then creates a
|
||||
<literal>JaasGrantedAuthority</literal> (which implements Spring
|
||||
Security’s <literal>GrantedAuthority</literal> interface) containing
|
||||
Security’s <interfacename>GrantedAuthority</interfacename> interface) containing
|
||||
both the <literal>AuthorityGranter</literal>-returned
|
||||
<literal>String</literal> and the JAAS principal that the
|
||||
<literal>AuthorityGranter</literal> was passed. The
|
||||
|
|
|
@ -396,7 +396,7 @@
|
|||
property. The authenticator would then call the search object to obtain the correct
|
||||
user's DN before attempting to bind as this user.</para>
|
||||
</section>
|
||||
<section>
|
||||
<section xml:id="ldap-custom-user-details">
|
||||
<title>LDAP Attributes and Customized UserDetails</title>
|
||||
<para>
|
||||
The net result of an authentication using <classname>LdapAuthenticationProvider</classname> is the
|
||||
|
|
|
@ -496,7 +496,7 @@
|
|||
</row>
|
||||
<row>
|
||||
<entry> SESSION_CONTEXT_INTEGRATION_FILTER</entry>
|
||||
<entry><literal>HttpSessionContextIntegrationFilter</literal></entry>
|
||||
<entry><classname>HttpSessionContextIntegrationFilter</classname></entry>
|
||||
<entry><literal>http</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -536,7 +536,7 @@
|
|||
</row>
|
||||
<row>
|
||||
<entry> REMEMBER_ME_FILTER </entry>
|
||||
<entry><literal>RememberMeProcessingFilter</literal></entry>
|
||||
<entry><classname>RememberMeProcessingFilter</classname></entry>
|
||||
<entry><literal>http/remember-me</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -546,7 +546,7 @@
|
|||
</row>
|
||||
<row>
|
||||
<entry> EXCEPTION_TRANSLATION_FILTER </entry>
|
||||
<entry><literal>ExceptionTranslationFilter</literal></entry>
|
||||
<entry><classname>ExceptionTranslationFilter</classname></entry>
|
||||
<entry><literal>http</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -556,7 +556,7 @@
|
|||
</row>
|
||||
<row>
|
||||
<entry> FILTER_SECURITY_INTERCEPTOR </entry>
|
||||
<entry><literal>FilterSecurityInterceptor</literal></entry>
|
||||
<entry><classname>FilterSecurityInterceptor</classname></entry>
|
||||
<entry><literal>http</literal></entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -587,8 +587,8 @@
|
|||
</para>
|
||||
<para>
|
||||
Note that you can't replace filters which are created by the use of the <literal><http></literal>
|
||||
element itself - <literal>HttpSessionContextIntegrationFilter</literal>, <literal>ExceptionTranslationFilter</literal> or
|
||||
<literal>FilterSecurityInterceptor</literal>.
|
||||
element itself - <classname>HttpSessionContextIntegrationFilter</classname>, <classname>ExceptionTranslationFilter</classname> or
|
||||
<classname>FilterSecurityInterceptor</classname>.
|
||||
</para>
|
||||
</tip>
|
||||
<para>
|
||||
|
@ -596,11 +596,11 @@
|
|||
an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too.
|
||||
</para>
|
||||
<section xml:id="ns-entry-point-ref">
|
||||
<title>Setting a Custom <literal>AuthenticationEntryPoint</literal></title>
|
||||
<title>Setting a Custom <interfacename>AuthenticationEntryPoint</interfacename></title>
|
||||
<para>
|
||||
If you aren't using form login, OpenID or basic authentication through the namespace, you may
|
||||
want to define an authentication filter and entry point using a traditional bean syntax and link them
|
||||
into the namespace, as we've just seen. The corresponding <literal>AuthenticationEntryPoint</literal> can be set using the
|
||||
into the namespace, as we've just seen. The corresponding <interfacename>AuthenticationEntryPoint</interfacename> can be set using the
|
||||
<literal>entry-point-ref</literal> attribute on the <literal><http></literal> element.
|
||||
</para>
|
||||
<para>
|
||||
|
@ -763,9 +763,9 @@
|
|||
<para>
|
||||
We've touched on the idea that the namespace configuration automatically registers an authentication manager bean for
|
||||
you. This is an instance of Spring Security's <classname>ProviderManager</classname> class, which you may already
|
||||
be familiar with if you've used the framework before. You can't use a custom <literal>AuthenticationProvider</literal> if you are
|
||||
be familiar with if you've used the framework before. You can't use a custom <classname>AuthenticationProvider</classname> if you are
|
||||
using either HTTP or method security through the namespace, but this should not be a problem as you have full control over
|
||||
the <literal>AuthenticationProvider</literal>s that are used.
|
||||
the <classname>AuthenticationProvider</classname>s that are used.
|
||||
</para>
|
||||
<para>
|
||||
You may want to register additional <classname>AuthenticationProvider</classname> beans with the <classname>ProviderManager</classname>
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
<section>
|
||||
<title>PreAuthenticatedProcessingFilterEntryPoint</title>
|
||||
<para>
|
||||
The <literal>AuthenticationEntryPoint</literal> was discussed in the <link xlink:href="#tech-auth-entry-point">technical
|
||||
The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link xlink:href="#tech-auth-entry-point">technical
|
||||
overview</link> chapter. Normally it is responsible for kick-starting the authentication process for an unauthenticated user
|
||||
(when they try to access a protected resource), but in the pre-authenticated case this doesn't apply. You would only
|
||||
configure the <classname>ExceptionTranslationFilter</classname> with an instance of this class if you aren't
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<literal>AuthenticationProcessingFilter</literal>, and is implemented
|
||||
via hooks in the <literal>AbstractProcessingFilter</literal>
|
||||
superclass. The hooks will invoke a concrete
|
||||
<literal>RememberMeServices</literal> at the appropriate times. The
|
||||
<interfacename>RememberMeServices</interfacename> at the appropriate times. The
|
||||
interface looks like this:
|
||||
<programlisting>
|
||||
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
|
||||
|
@ -107,9 +107,9 @@
|
|||
<literal>AbstractProcessingFilter</literal> only calls the
|
||||
<literal>loginFail()</literal> and <literal>loginSuccess()</literal>
|
||||
methods. The <literal>autoLogin()</literal> method is called by
|
||||
<literal>RememberMeProcessingFilter</literal> whenever the
|
||||
<literal>SecurityContextHolder</literal> does not contain an
|
||||
<literal>Authentication</literal>. This interface therefore provides
|
||||
<classname>RememberMeProcessingFilter</classname> whenever the
|
||||
<classname>SecurityContextHolder</classname> does not contain an
|
||||
<interfacename>Authentication</interfacename>. This interface therefore provides
|
||||
the underlying remember-me implementation with sufficient
|
||||
notification of authentication-related events, and delegates to the
|
||||
implementation whenever a candidate web request might contain a cookie
|
||||
|
@ -130,7 +130,7 @@
|
|||
UserDetailsService from which it can retrieve the username and
|
||||
password for signature comparison purposes, and generate the
|
||||
<literal>RememberMeAuthenticationToken</literal> to contain the
|
||||
correct <literal>GrantedAuthority</literal>[]s. Some sort of logout
|
||||
correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of logout
|
||||
command should be provided by the application that invalidates the cookie if
|
||||
the user requests this. <classname>TokenBasedRememberMeServices</classname> also implements Spring Security's
|
||||
<interfacename>LogoutHandler</interfacename> interface so can be used with <classname>LogoutFilter</classname>
|
||||
|
@ -155,13 +155,13 @@
|
|||
</bean>
|
||||
]]>
|
||||
</programlisting>Don't forget to add your
|
||||
<literal>RememberMeServices</literal> implementation to your
|
||||
<interfacename>RememberMeServices</interfacename> implementation to your
|
||||
<literal>AuthenticationProcessingFilter.setRememberMeServices()</literal>
|
||||
property, include the
|
||||
<literal>RememberMeAuthenticationProvider</literal> in your
|
||||
<literal>AuthenticationManager.setProviders()</literal> list, and add
|
||||
<literal>RememberMeProcessingFilter</literal> into your
|
||||
<literal>FilterChainProxy</literal> (typically immediately after your
|
||||
<classname>RememberMeProcessingFilter</classname> into your
|
||||
<classname>FilterChainProxy</classname> (typically immediately after your
|
||||
<literal>AuthenticationProcessingFilter</literal>).</para>
|
||||
</section>
|
||||
<section>
|
||||
|
|
|
@ -4,27 +4,27 @@
|
|||
<section xml:id="runas-overview">
|
||||
<info><title>Overview</title></info>
|
||||
|
||||
<para>The <literal>AbstractSecurityInterceptor</literal> is able to
|
||||
temporarily replace the <literal>Authentication</literal> object in
|
||||
the <literal>SecurityContext</literal> and
|
||||
<literal>SecurityContextHolder</literal> during the secure object
|
||||
<para>The <classname>AbstractSecurityInterceptor</classname> is able to
|
||||
temporarily replace the <interfacename>Authentication</interfacename> object in
|
||||
the <interfacename>SecurityContext</interfacename> and
|
||||
<classname>SecurityContextHolder</classname> during the secure object
|
||||
callback phase. This only occurs if the original
|
||||
<literal>Authentication</literal> object was successfully processed by
|
||||
the <literal>AuthenticationManager</literal> and
|
||||
<literal>AccessDecisionManager</literal>. The
|
||||
<interfacename>Authentication</interfacename> object was successfully processed by
|
||||
the <interfacename>AuthenticationManager</interfacename> and
|
||||
<interfacename>AccessDecisionManager</interfacename>. The
|
||||
<literal>RunAsManager</literal> will indicate the replacement
|
||||
<literal>Authentication</literal> object, if any, that should be used
|
||||
<interfacename>Authentication</interfacename> object, if any, that should be used
|
||||
during the <literal>SecurityInterceptorCallback</literal>.</para>
|
||||
|
||||
<para>By temporarily replacing the <literal>Authentication</literal>
|
||||
<para>By temporarily replacing the <interfacename>Authentication</interfacename>
|
||||
object during the secure object callback phase, the 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. Because Spring Security
|
||||
<interfacename>GrantedAuthority</interfacename> objects. Because Spring Security
|
||||
provides a number of helper classes that automatically configure
|
||||
remoting protocols based on the contents of the
|
||||
<literal>SecurityContextHolder</literal>, these run-as replacements
|
||||
<classname>SecurityContextHolder</classname>, these run-as replacements
|
||||
are particularly useful when calling remote web services</para>
|
||||
</section>
|
||||
|
||||
|
@ -38,12 +38,12 @@
|
|||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>The first method returns the <literal>Authentication</literal>
|
||||
<para>The first method returns the <interfacename>Authentication</interfacename>
|
||||
object that should replace the existing
|
||||
<literal>Authentication</literal> object for the duration of the
|
||||
<interfacename>Authentication</interfacename> object for the duration of the
|
||||
method invocation. If the method returns <literal>null</literal>, it
|
||||
indicates no replacement should be made. The second method is used by
|
||||
the <literal>AbstractSecurityInterceptor</literal> as part of its
|
||||
the <classname>AbstractSecurityInterceptor</classname> as part of its
|
||||
startup validation of configuration attributes. The
|
||||
<literal>supports(Class)</literal> method is called by a security
|
||||
interceptor implementation to ensure the configured
|
||||
|
@ -59,7 +59,7 @@
|
|||
<literal>ConfigAttribute</literal> is found, the replacement
|
||||
<literal>RunAsUserToken</literal> will contain the same principal,
|
||||
credentials and granted authorities as the original
|
||||
<literal>Authentication</literal> object, along with a new
|
||||
<interfacename>Authentication</interfacename> object, along with a new
|
||||
<literal>GrantedAuthorityImpl</literal> for each
|
||||
<literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each
|
||||
new <literal>GrantedAuthorityImpl</literal> will be prefixed with
|
||||
|
@ -70,10 +70,10 @@
|
|||
<literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para>
|
||||
|
||||
<para>The replacement <literal>RunAsUserToken</literal> is just like
|
||||
any other <literal>Authentication</literal> object. It needs to be
|
||||
authenticated by the <literal>AuthenticationManager</literal>,
|
||||
any other <interfacename>Authentication</interfacename> object. It needs to be
|
||||
authenticated by the <interfacename>AuthenticationManager</interfacename>,
|
||||
probably via delegation to a suitable
|
||||
<literal>AuthenticationProvider</literal>. The
|
||||
<classname>AuthenticationProvider</classname>. The
|
||||
<literal>RunAsImplAuthenticationProvider</literal> performs such
|
||||
authentication. It simply accepts as valid any
|
||||
<literal>RunAsUserToken</literal> presented.</para>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
currently logged on user are displayed, and only users with
|
||||
<literal>ROLE_SUPERVISOR</literal> are granted access to delete their
|
||||
contacts. Behind the scenes, the
|
||||
<literal>MethodSecurityInterceptor</literal> is securing the business
|
||||
<classname>MethodSecurityInterceptor</classname> is securing the business
|
||||
objects. </para>
|
||||
<para>The application allows you to modify the access control lists associated
|
||||
with different contacts. Be sure to give this a try and understand how
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</info>
|
||||
|
||||
<para>
|
||||
Prior to Spring Security 2.0, securing <literal>MethodInvocation</literal>s needed quite a
|
||||
Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed quite a
|
||||
lot of boiler plate configuration. Now the recommended approach for method security
|
||||
is to use <link xlink:href="#ns-method-security">namespace configuration</link>.
|
||||
This way the method security infrastructure beans are configured automatically for you so you don't really need to
|
||||
|
@ -67,7 +67,7 @@
|
|||
security interceptors in the same application, with
|
||||
<literal>AspectJSecurityInterceptor</literal> being used for domain
|
||||
object instance security and the AOP Alliance
|
||||
<literal>MethodSecurityInterceptor</literal> being used for services
|
||||
<classname>MethodSecurityInterceptor</classname> being used for services
|
||||
layer security.</para>
|
||||
|
||||
<para>Let's first consider how the
|
||||
|
@ -92,11 +92,11 @@
|
|||
<literal>AspectJSecurityInterceptor</literal> is exactly the same as
|
||||
the AOP Alliance security interceptor. Indeed the two interceptors can
|
||||
share the same <literal>objectDefinitionSource</literal>, as the
|
||||
<literal>ObjectDefinitionSource</literal> works with
|
||||
<interfacename>ObjectDefinitionSource</interfacename> works with
|
||||
<literal>java.lang.reflect.Method</literal>s rather than an AOP
|
||||
library-specific class. Of course, your access decisions have access
|
||||
to the relevant AOP library-specific invocation (ie
|
||||
<literal>MethodInvocation</literal> or <literal>JoinPoint</literal>)
|
||||
<classname>MethodInvocation</classname> or <literal>JoinPoint</literal>)
|
||||
and as such can consider a range of addition criteria when making
|
||||
access decisions (such as method arguments).</para>
|
||||
|
||||
|
@ -178,7 +178,7 @@ public void afterPropertiesSet() throws Exception {
|
|||
<info><title>FilterInvocation Security Interceptor</title></info>
|
||||
|
||||
<para>To secure <classname>FilterInvocation</classname>s, developers need
|
||||
to add a <literal>FilterSecurityInterceptor</literal> to their filter chain.
|
||||
to add a <classname>FilterSecurityInterceptor</classname> to their filter chain.
|
||||
A typical configuration example is provided below:</para>
|
||||
|
||||
<para>In the application context you will need to configure three
|
||||
|
@ -217,43 +217,43 @@ public void afterPropertiesSet() throws Exception {
|
|||
the filter will call the AuthenticationEntryPoint to commence the
|
||||
authentication process (e.g. a user login).</para>
|
||||
|
||||
<para>The <literal>AuthenticationEntryPoint</literal> will be called
|
||||
<para>The <interfacename>AuthenticationEntryPoint</interfacename> will be called
|
||||
if the user requests a secure HTTP resource but they are not
|
||||
authenticated. The class handles presenting the appropriate response
|
||||
to the user so that authentication can begin. Three concrete
|
||||
implementations are provided with Spring Security:
|
||||
<literal>AuthenticationProcessingFilterEntryPoint</literal> for
|
||||
<classname>AuthenticationProcessingFilterEntryPoint</classname> for
|
||||
commencing a form-based authentication,
|
||||
<literal>BasicProcessingFilterEntryPoint</literal> for commencing a
|
||||
HTTP Basic authentication process, and
|
||||
<literal>CasProcessingFilterEntryPoint</literal> for commencing a
|
||||
JA-SIG Central Authentication Service (CAS) login. The
|
||||
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
|
||||
<classname>AuthenticationProcessingFilterEntryPoint</classname> and
|
||||
<literal>CasProcessingFilterEntryPoint</literal> have optional
|
||||
properties related to forcing the use of HTTPS, so please refer to the
|
||||
JavaDocs if you require this.</para>
|
||||
|
||||
<para><literal>FilterSecurityInterceptor</literal> is responsible for
|
||||
<para><classname>FilterSecurityInterceptor</classname> is responsible for
|
||||
handling the security of HTTP resources. Like any other security
|
||||
interceptor, it requires a reference to an
|
||||
<literal>AuthenticationManager</literal> and an
|
||||
<literal>AccessDecisionManager</literal>, which are both discussed in
|
||||
<interfacename>AuthenticationManager</interfacename> and an
|
||||
<interfacename>AccessDecisionManager</interfacename>, which are both discussed in
|
||||
separate sections below. The
|
||||
<literal>FilterSecurityInterceptor</literal> is also configured with
|
||||
<classname>FilterSecurityInterceptor</classname> is also configured with
|
||||
configuration attributes that apply to different HTTP URL requests. A
|
||||
full discussion of configuration attributes is provided in the High
|
||||
Level Design section of this document.</para>
|
||||
|
||||
<para>The <literal>FilterSecurityInterceptor</literal> can be
|
||||
<para>The <classname>FilterSecurityInterceptor</classname> can be
|
||||
configured with configuration attributes in two ways. The first,
|
||||
which is shown above, is using the <literal><filter-invocation-definition-source></literal>
|
||||
namespace element. This is similar to the <literal><filter-chain-map></literal>
|
||||
used to configure a <literal>FilterChainProxy</literal> but the <literal><intercept-url></literal>
|
||||
used to configure a <classname>FilterChainProxy</classname> but the <literal><intercept-url></literal>
|
||||
child elements only use the <literal>pattern</literal> and <literal>access</literal> attributes.
|
||||
The second is by writing your own
|
||||
<literal>ObjectDefinitionSource</literal>, although this is beyond the
|
||||
<interfacename>ObjectDefinitionSource</interfacename>, although this is beyond the
|
||||
scope of this document. Irrespective of the approach used, the
|
||||
<literal>ObjectDefinitionSource</literal> is responsible for returning
|
||||
<interfacename>ObjectDefinitionSource</interfacename> is responsible for returning
|
||||
a <literal>ConfigAttributeDefinition</literal> object that contains
|
||||
all of the configuration attributes associated with a single secure
|
||||
HTTP URL.</para>
|
||||
|
@ -261,24 +261,24 @@ public void afterPropertiesSet() throws Exception {
|
|||
<para>It should be noted that the
|
||||
<literal>FilterSecurityInterceptor.setObjectDefinitionSource()</literal>
|
||||
method actually expects an instance of
|
||||
<literal>FilterInvocationDefinitionSource</literal>. This is a marker
|
||||
interface which subclasses <literal>ObjectDefinitionSource</literal>.
|
||||
It simply denotes the <literal>ObjectDefinitionSource</literal>
|
||||
understands <literal>FilterInvocation</literal>s. In the interests of
|
||||
<interfacename>FilterInvocationDefinitionSource</interfacename>. This is a marker
|
||||
interface which subclasses <interfacename>ObjectDefinitionSource</interfacename>.
|
||||
It simply denotes the <interfacename>ObjectDefinitionSource</interfacename>
|
||||
understands <classname>FilterInvocation</classname>s. In the interests of
|
||||
simplicity we'll continue to refer to the
|
||||
<literal>FilterInvocationDefinitionSource</literal> as an
|
||||
<literal>ObjectDefinitionSource</literal>, as the distinction is of
|
||||
<interfacename>FilterInvocationDefinitionSource</interfacename> as an
|
||||
<interfacename>ObjectDefinitionSource</interfacename>, as the distinction is of
|
||||
little relevance to most users of the
|
||||
<literal>FilterSecurityInterceptor</literal>.</para>
|
||||
<classname>FilterSecurityInterceptor</classname>.</para>
|
||||
|
||||
<para>When using the namespace option to configure the interceptor,
|
||||
commas are used to delimit the different configuration
|
||||
attributes that apply to each HTTP URL. Each configuration attribute
|
||||
is assigned into its own <literal>SecurityConfig</literal> object. The
|
||||
<literal>SecurityConfig</literal> object is discussed in the High
|
||||
Level Design section. The <literal>ObjectDefinitionSource</literal>
|
||||
Level Design section. The <interfacename>ObjectDefinitionSource</interfacename>
|
||||
created by the property editor,
|
||||
<literal>FilterInvocationDefinitionSource</literal>, matches
|
||||
<interfacename>FilterInvocationDefinitionSource</interfacename>, matches
|
||||
configuration attributes against <literal>FilterInvocations</literal>
|
||||
based on expression evaluation of the request URL. Two standard
|
||||
expression syntaxes are supported. The default is to treat all
|
||||
|
@ -317,10 +317,10 @@ public void afterPropertiesSet() throws Exception {
|
|||
<para>As with other security interceptors, the
|
||||
<literal>validateConfigAttributes</literal> property is observed. When
|
||||
set to <literal>true</literal> (the default), at startup time the
|
||||
<literal>FilterSecurityInterceptor</literal> will evaluate if the
|
||||
<classname>FilterSecurityInterceptor</classname> will evaluate if the
|
||||
provided configuration attributes are valid. It does this by checking
|
||||
each configuration attribute can be processed by either the
|
||||
<literal>AccessDecisionManager</literal> or the
|
||||
<interfacename>AccessDecisionManager</interfacename> or the
|
||||
<literal>RunAsManager</literal>. If neither of these can process a
|
||||
given configuration attribute, an exception is thrown.</para>
|
||||
</section>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
</bean></programlisting></para>
|
||||
|
||||
<para>In our example above, the bean is being provided an
|
||||
<literal>AuthenticationManager</literal>, as is normally needed by
|
||||
<interfacename>AuthenticationManager</interfacename>, as is normally needed by
|
||||
authentication mechanisms. Several URLs are also specified, with the
|
||||
values being self-explanatory. It's important to also specify the HTTP
|
||||
header that Spring Security should inspect. If you additionally want
|
||||
|
@ -61,15 +61,15 @@
|
|||
<literal>SiteminderAuthenticationProvider</literal>
|
||||
configured against your <literal>ProviderManager</literal> in order to
|
||||
use the Siteminder authentication mechanism. Normally an
|
||||
<literal>AuthenticationProvider</literal> expects the password
|
||||
<classname>AuthenticationProvider</classname> expects the password
|
||||
property to match what it retrieves from the
|
||||
<literal>UserDetailsSource</literal>, but in this case, authentication
|
||||
has already been handled by Siteminder, so password property is not
|
||||
even relevant. This may sound like a security weakness, but remember
|
||||
that users have to authenticate with Siteminder before your
|
||||
application ever receives the requests, so the purpose of your custom
|
||||
<literal>UserDetailsService</literal> should simply be to build the
|
||||
complete <literal>Authentication</literal> object (ie with suitable
|
||||
<interfacename>UserDetailsService</interfacename> should simply be to build the
|
||||
complete <interfacename>Authentication</interfacename> object (ie with suitable
|
||||
<literal>GrantedAuthority[]</literal>s).</para>
|
||||
|
||||
<para>Advanced tip and word to the wise: If you additionally want to
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
in the <link xlink:href="#technical-overview">Technical Overview</link> chapter.
|
||||
In this part of the reference guide we will examine individual
|
||||
authentication mechanisms and their corresponding
|
||||
<literal>AuthenticationProvider</literal>s. We'll also look at how to
|
||||
<classname>AuthenticationProvider</classname>s. We'll also look at how to
|
||||
configure authentication more generally, including if you have several
|
||||
authentication approaches that need to be chained together.</para>
|
||||
<para>
|
||||
|
@ -213,7 +213,7 @@
|
|||
in a consistent and simple way.</para>
|
||||
|
||||
<para>In this part we'll explore the different
|
||||
<literal>AbstractSecurityInterceptor</literal> implementations, which
|
||||
<classname>AbstractSecurityInterceptor</classname> implementations, which
|
||||
were introduced in Part I. We then move on to explore how to fine-tune
|
||||
authorization through use of domain access control lists.</para>
|
||||
</partintro>
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
are using your own customized versions of classes.</para>
|
||||
<para>In this case, you have a choice in how these filters are added to your web application, in that you can use either
|
||||
Spring's <literal>DelegatingFilterProxy</literal> or
|
||||
<literal>FilterChainProxy</literal>. We'll look at both below.</para>
|
||||
<classname>FilterChainProxy</classname>. We'll look at both below.</para>
|
||||
|
||||
<para>When using <literal>DelegatingFilterProxy</literal>, you will see
|
||||
something like this in the web.xml file:
|
||||
|
@ -135,14 +135,14 @@
|
|||
for more information</para>
|
||||
|
||||
<para>Rather than using <literal>DelegatingFilterProxy</literal>, we
|
||||
strongly recommend that you use <literal>FilterChainProxy</literal> instead.
|
||||
strongly recommend that you use <classname>FilterChainProxy</classname> instead.
|
||||
Whilst <literal>DelegatingFilterProxy</literal> is a very useful class,
|
||||
the problem is that the number of lines of code required for
|
||||
<literal><filter></literal> and
|
||||
<literal><filter-mapping></literal> entries in
|
||||
<literal>web.xml</literal> explodes when using more than a few
|
||||
filters. To overcome this issue, Spring Security provides a
|
||||
<literal>FilterChainProxy</literal> class. It is wired using a
|
||||
<classname>FilterChainProxy</classname> class. It is wired using a
|
||||
<literal>DelegatingFilterProxy</literal> (just like in the example above),
|
||||
but the target class is
|
||||
<literal>org.springframework.security.util.FilterChainProxy</literal>.
|
||||
|
@ -162,9 +162,9 @@
|
|||
</programlisting></para>
|
||||
|
||||
<para>You may notice similarities with the way
|
||||
<literal>FilterSecurityInterceptor</literal> is declared. Both regular
|
||||
<classname>FilterSecurityInterceptor</classname> is declared. Both regular
|
||||
expressions and Ant Paths are supported, and the most specific URIs
|
||||
appear first. At runtime the <literal>FilterChainProxy</literal> will
|
||||
appear first. At runtime the <classname>FilterChainProxy</classname> will
|
||||
locate the first URI pattern that matches the current web request and the list
|
||||
of filter beans specified by the <literal>filters</literal> attribute
|
||||
will be applied to that request. The filters will be invoked in the order
|
||||
|
@ -172,28 +172,28 @@
|
|||
which is applied to a particular URL.</para>
|
||||
|
||||
<para>You may have noticed we have declared two
|
||||
<literal>HttpSessionContextIntegrationFilter</literal>s in the filter
|
||||
<classname>HttpSessionContextIntegrationFilter</classname>s in the filter
|
||||
chain (<literal>ASC</literal> is short for
|
||||
<literal>allowSessionCreation</literal>, a property of
|
||||
<literal>HttpSessionContextIntegrationFilter</literal>). As web
|
||||
<classname>HttpSessionContextIntegrationFilter</classname>). As web
|
||||
services will never present a <literal>jsessionid</literal> on future
|
||||
requests, creating <literal>HttpSession</literal>s for such user
|
||||
agents would be wasteful. If you had a high-volume application which
|
||||
required maximum scalability, we recommend you use the approach shown
|
||||
above. For smaller applications, using a single
|
||||
<literal>HttpSessionContextIntegrationFilter</literal> (with its
|
||||
<classname>HttpSessionContextIntegrationFilter</classname> (with its
|
||||
default <literal>allowSessionCreation</literal> as
|
||||
<literal>true</literal>) would likely be sufficient.</para>
|
||||
|
||||
<para>In relation to lifecycle issues, the
|
||||
<literal>FilterChainProxy</literal> will always delegate
|
||||
<classname>FilterChainProxy</classname> will always delegate
|
||||
<literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
|
||||
methods through to the underlaying <literal>Filter</literal>s if such
|
||||
methods are called against <literal>FilterChainProxy</literal> itself.
|
||||
In this case, <literal>FilterChainProxy</literal> guarantees to only
|
||||
methods are called against <classname>FilterChainProxy</classname> itself.
|
||||
In this case, <classname>FilterChainProxy</classname> guarantees to only
|
||||
initialize and destroy each <literal>Filter</literal> once,
|
||||
irrespective of how many times it is declared by the
|
||||
<literal>FilterInvocationDefinitionSource</literal>. You control the
|
||||
<interfacename>FilterInvocationDefinitionSource</interfacename>. You control the
|
||||
overall choice as to whether these methods are called or not via the
|
||||
<literal>targetFilterLifecycle</literal> initialization parameter of the
|
||||
<literal>DelegatingFilterProxy</literal> that proxies
|
||||
|
@ -222,17 +222,17 @@
|
|||
|
||||
<listitem>
|
||||
<para><literal>ConcurrentSessionFilter</literal>, because it
|
||||
doesn't use any <literal>SecurityContextHolder</literal>
|
||||
doesn't use any <classname>SecurityContextHolder</classname>
|
||||
functionality but needs to update the
|
||||
<literal>SessionRegistry</literal> to reflect ongoing requests
|
||||
<interfacename>SessionRegistry</interfacename> to reflect ongoing requests
|
||||
from the principal</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>HttpSessionContextIntegrationFilter</literal>, so a
|
||||
<literal>SecurityContext</literal> can be setup in the
|
||||
<literal>SecurityContextHolder</literal> at the beginning of a web
|
||||
request, and any changes to the <literal>SecurityContext</literal>
|
||||
<para><classname>HttpSessionContextIntegrationFilter</classname>, so a
|
||||
<interfacename>SecurityContext</interfacename> can be setup in the
|
||||
<classname>SecurityContextHolder</classname> at the beginning of a web
|
||||
request, and any changes to the <interfacename>SecurityContext</interfacename>
|
||||
can be copied to the <literal>HttpSession</literal> when the web
|
||||
request ends (ready for use with the next web request)</para>
|
||||
</listitem>
|
||||
|
@ -243,8 +243,8 @@
|
|||
<literal>CasProcessingFilter</literal>,
|
||||
<literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
|
||||
JbossIntegrationFilter</literal> etc - so that the
|
||||
<literal>SecurityContextHolder</literal> can be modified to
|
||||
contain a valid <literal>Authentication</literal> request
|
||||
<classname>SecurityContextHolder</classname> can be modified to
|
||||
contain a valid <interfacename>Authentication</interfacename> request
|
||||
token</para>
|
||||
</listitem>
|
||||
|
||||
|
@ -257,46 +257,46 @@
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>RememberMeProcessingFilter</literal>, so that if no
|
||||
<para><classname>RememberMeProcessingFilter</classname>, so that if no
|
||||
earlier authentication processing mechanism updated the
|
||||
<literal>SecurityContextHolder</literal>, and the request presents
|
||||
<classname>SecurityContextHolder</classname>, and the request presents
|
||||
a cookie that enables remember-me services to take place, a
|
||||
suitable remembered
|
||||
<literal>Authentication</literal> object will
|
||||
<interfacename>Authentication</interfacename> object will
|
||||
be put there</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AnonymousProcessingFilter</literal>, so that if no
|
||||
earlier authentication processing mechanism updated the
|
||||
<literal>SecurityContextHolder</literal>, an anonymous
|
||||
<literal>Authentication</literal> object will be put there</para>
|
||||
<classname>SecurityContextHolder</classname>, an anonymous
|
||||
<interfacename>Authentication</interfacename> object will be put there</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>ExceptionTranslationFilter</literal>, to catch any
|
||||
<para><classname>ExceptionTranslationFilter</classname>, to catch any
|
||||
Spring Security exceptions so that either an HTTP error response
|
||||
can be returned or an appropriate
|
||||
<literal>AuthenticationEntryPoint</literal> can be launched</para>
|
||||
<interfacename>AuthenticationEntryPoint</interfacename> can be launched</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>FilterSecurityInterceptor</literal>, to protect web
|
||||
<para><classname>FilterSecurityInterceptor</classname>, to protect web
|
||||
URIs</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>All of the above filters use
|
||||
<literal>DelegatingFilterProxy</literal> or
|
||||
<literal>FilterChainProxy</literal>. It is recommended that a single
|
||||
<classname>FilterChainProxy</classname>. It is recommended that a single
|
||||
<literal>DelegatingFilterProxy</literal> proxy through to a single
|
||||
<literal>FilterChainProxy</literal> for each application, with that
|
||||
<literal>FilterChainProxy</literal> defining all of Spring Security
|
||||
<classname>FilterChainProxy</classname> for each application, with that
|
||||
<classname>FilterChainProxy</classname> defining all of Spring Security
|
||||
filters.</para>
|
||||
|
||||
<para>If you're using SiteMesh, ensure Spring Security filters execute
|
||||
before the SiteMesh filters are called. This enables the
|
||||
<literal>SecurityContextHolder</literal> to be populated in time for
|
||||
<classname>SecurityContextHolder</classname> to be populated in time for
|
||||
use by SiteMesh decorators</para>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@
|
|||
SecurityContextHolder, SecurityContext and Authentication Objects
|
||||
</title>
|
||||
<para>The most fundamental object is
|
||||
<literal>SecurityContextHolder</literal>. This is where we store
|
||||
<classname>SecurityContextHolder</classname>. This is where we store
|
||||
details of the present security context of the application, which
|
||||
includes details of the principal currently using the application. By
|
||||
default the <literal>SecurityContextHolder</literal> uses a
|
||||
default the <classname>SecurityContextHolder</classname> uses a
|
||||
<literal>ThreadLocal</literal> to store these details, which means
|
||||
that the security context is always available to methods in the same
|
||||
thread of execution, even if the security context is not explicitly
|
||||
|
@ -70,17 +70,17 @@
|
|||
You can change the mode from the default
|
||||
<literal>SecurityContextHolder.MODE_THREADLOCAL</literal> in two ways.
|
||||
The first is to set a system property. Alternatively, call a static
|
||||
method on <literal>SecurityContextHolder</literal>. Most applications
|
||||
method on <classname>SecurityContextHolder</classname>. Most applications
|
||||
won't need to change from the default, but if you do, take a look at
|
||||
the JavaDocs for <literal>SecurityContextHolder</literal> to learn
|
||||
the JavaDocs for <classname>SecurityContextHolder</classname> to learn
|
||||
more.</para>
|
||||
|
||||
<para>Inside the <literal>SecurityContextHolder</literal> we store
|
||||
<para>Inside the <classname>SecurityContextHolder</classname> we store
|
||||
details of the principal currently interacting with the application.
|
||||
Spring Security uses an <literal>Authentication</literal> object to
|
||||
Spring Security uses an <interfacename>Authentication</interfacename> object to
|
||||
represent this information. Whilst you won't normally need to create
|
||||
an <literal>Authentication</literal> object yourself, it is fairly
|
||||
common for users to query the <literal>Authentication</literal>
|
||||
an <interfacename>Authentication</interfacename> object yourself, it is fairly
|
||||
common for users to query the <interfacename>Authentication</interfacename>
|
||||
object. You can use the following code block - from anywhere in your
|
||||
application - to obtain the name of the authenticated user, for example:</para>
|
||||
|
||||
|
@ -95,14 +95,14 @@ if (obj instanceof UserDetails) {
|
|||
|
||||
<para>The above code introduces a number of interesting relationships
|
||||
and key objects. First, you will notice that there is an intermediate
|
||||
object between <literal>SecurityContextHolder</literal> and
|
||||
<literal>Authentication</literal>. The
|
||||
object between <classname>SecurityContextHolder</classname> and
|
||||
<interfacename>Authentication</interfacename>. The
|
||||
<literal>SecurityContextHolder.getContext()</literal> method is
|
||||
actually returning a <literal>SecurityContext</literal>.
|
||||
actually returning a <interfacename>SecurityContext</interfacename>.
|
||||
|
||||
<!-- Commented out as Captcha sandboxed
|
||||
Spring
|
||||
Security uses a few different <literal>SecurityContext</literal>
|
||||
Security uses a few different <interfacename>SecurityContext</interfacename>
|
||||
implementations, such as if we need to store special information
|
||||
related to a request that is not principal-specific.
|
||||
|
||||
|
@ -111,7 +111,7 @@ if (obj instanceof UserDetails) {
|
|||
current request came from a human user or not. Because such a decision
|
||||
has nothing at all to do with the principal the request may or may not
|
||||
be authenticated as, we store it in the
|
||||
<literal>SecurityContext</literal>. -->
|
||||
<interfacename>SecurityContext</interfacename>. -->
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -119,40 +119,40 @@ if (obj instanceof UserDetails) {
|
|||
<title>The UserDetailsService</title>
|
||||
|
||||
<para>Another item to note from the above code fragment is that you
|
||||
can obtain a principal from the <literal>Authentication</literal>
|
||||
can obtain a principal from the <interfacename>Authentication</interfacename>
|
||||
object. The principal is just an <literal>Object</literal>. Most of
|
||||
the time this can be cast into a <literal>UserDetails</literal>
|
||||
object. <literal>UserDetails</literal> is a central interface in
|
||||
the time this can be cast into a <interfacename>UserDetails</interfacename>
|
||||
object. <interfacename>UserDetails</interfacename> is a central interface in
|
||||
Spring Security. It represents a principal, but in an extensible and
|
||||
application-specific way. Think of <literal>UserDetails</literal> as
|
||||
application-specific way. Think of <interfacename>UserDetails</interfacename> as
|
||||
the adapter between your own user database and what Spring Security
|
||||
needs inside the <literal>SecurityContextHolder</literal>. Being a
|
||||
needs inside the <classname>SecurityContextHolder</classname>. Being a
|
||||
representation of something from your own user database, quite often
|
||||
you will cast the <literal>UserDetails</literal> to the original
|
||||
you will cast the <interfacename>UserDetails</interfacename> to the original
|
||||
object that your application provided, so you can call
|
||||
business-specific methods (like <literal>getEmail()</literal>,
|
||||
<literal>getEmployeeNumber()</literal> and so on).</para>
|
||||
|
||||
<para>By now you're probably wondering, so when do I provide a
|
||||
<literal>UserDetails</literal> object? How do I do that? I thought you
|
||||
<interfacename>UserDetails</interfacename> object? How do I do that? I thought you
|
||||
said this thing was declarative and I didn't need to write any Java
|
||||
code - what gives? The short answer is that there is a special
|
||||
interface called <literal>UserDetailsService</literal>. The only
|
||||
interface called <interfacename>UserDetailsService</interfacename>. The only
|
||||
method on this interface accepts a <literal>String</literal>-based
|
||||
username argument and returns a <literal>UserDetails</literal>. Most
|
||||
username argument and returns a <interfacename>UserDetails</interfacename>. Most
|
||||
authentication providers that ship with Spring Security delegate to a
|
||||
<literal>UserDetailsService</literal> as part of the authentication
|
||||
process. The <literal>UserDetailsService</literal> is used to build
|
||||
the <literal>Authentication</literal> object that is stored in the
|
||||
<literal>SecurityContextHolder</literal>. The good news is that we
|
||||
provide a number of <literal>UserDetailsService</literal>
|
||||
<interfacename>UserDetailsService</interfacename> as part of the authentication
|
||||
process. The <interfacename>UserDetailsService</interfacename> is used to build
|
||||
the <interfacename>Authentication</interfacename> object that is stored in the
|
||||
<classname>SecurityContextHolder</classname>. The good news is that we
|
||||
provide a number of <interfacename>UserDetailsService</interfacename>
|
||||
implementations, including one that uses an in-memory map and another
|
||||
that uses JDBC. Most users tend to write their own, though, with such
|
||||
implementations often simply sitting on top of an existing Data Access
|
||||
Object (DAO) that represents their employees, customers, or other
|
||||
users of the enterprise application. Remember the advantage that
|
||||
whatever your UserDetailsService returns can always be obtained from
|
||||
the <literal>SecurityContextHolder</literal>, as per the above code
|
||||
the <classname>SecurityContextHolder</classname>, as per the above code
|
||||
fragment.</para>
|
||||
</section>
|
||||
|
||||
|
@ -161,23 +161,23 @@ if (obj instanceof UserDetails) {
|
|||
<title>GrantedAuthority</title>
|
||||
|
||||
<para>Besides the principal, another important method provided by
|
||||
<literal>Authentication</literal> is
|
||||
<interfacename>Authentication</interfacename> is
|
||||
<literal>getAuthorities(</literal>). This method provides an array of
|
||||
<literal>GrantedAuthority</literal> objects. A
|
||||
<literal>GrantedAuthority</literal> is, not surprisingly, an authority
|
||||
<interfacename>GrantedAuthority</interfacename> objects. A
|
||||
<interfacename>GrantedAuthority</interfacename> is, not surprisingly, an authority
|
||||
that is granted to the principal. Such authorities are usually
|
||||
"roles", such as <literal>ROLE_ADMINISTRATOR</literal> or
|
||||
<literal>ROLE_HR_SUPERVISOR</literal>. These roles are later on
|
||||
configured for web authorization, method authorization and domain
|
||||
object authorization. Other parts of Spring Security are capable of
|
||||
interpreting these authorities, and expect them to be present.
|
||||
<literal>GrantedAuthority</literal> objects are usually loaded by the
|
||||
<literal>UserDetailsService</literal>.</para>
|
||||
<interfacename>GrantedAuthority</interfacename> objects are usually loaded by the
|
||||
<interfacename>UserDetailsService</interfacename>.</para>
|
||||
|
||||
<para>Usually the <literal>GrantedAuthority</literal> objects are
|
||||
<para>Usually the <interfacename>GrantedAuthority</interfacename> objects are
|
||||
application-wide permissions. They are not specific to a given domain
|
||||
object. Thus, you wouldn't likely have a
|
||||
<literal>GrantedAuthority</literal> to represent a permission to
|
||||
<interfacename>GrantedAuthority</interfacename> to represent a permission to
|
||||
<literal>Employee</literal> object number 54, because if there are
|
||||
thousands of such authorities you would quickly run out of memory (or,
|
||||
at the very least, cause the application to take a long time to
|
||||
|
@ -186,16 +186,16 @@ if (obj instanceof UserDetails) {
|
|||
domain object security capabilities for this purpose.</para>
|
||||
|
||||
<para>Last but not least, sometimes you will need to store the
|
||||
<literal>SecurityContext</literal> between HTTP requests. Other times
|
||||
<interfacename>SecurityContext</interfacename> between HTTP requests. Other times
|
||||
the principal will re-authenticate on every request, although most of
|
||||
the time it will be stored. The
|
||||
<literal>HttpSessionContextIntegrationFilter</literal> is responsible
|
||||
for storing a <literal>SecurityContext</literal> between HTTP
|
||||
<classname>HttpSessionContextIntegrationFilter</classname> is responsible
|
||||
for storing a <interfacename>SecurityContext</interfacename> between HTTP
|
||||
requests. As suggested by the name of the class, the
|
||||
<literal>HttpSession</literal> is used to store this information. You
|
||||
should never interact directly with the <literal>HttpSession</literal>
|
||||
for security purposes. There is simply no justification for doing so -
|
||||
always use the <literal>SecurityContextHolder</literal>
|
||||
always use the <classname>SecurityContextHolder</classname>
|
||||
instead.</para>
|
||||
|
||||
</section>
|
||||
|
@ -208,41 +208,41 @@ if (obj instanceof UserDetails) {
|
|||
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para><literal>SecurityContextHolder</literal>, to provide any
|
||||
type access to the <literal>SecurityContext</literal>.</para>
|
||||
<para><classname>SecurityContextHolder</classname>, to provide any
|
||||
type access to the <interfacename>SecurityContext</interfacename>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>SecurityContext</literal>, to hold the
|
||||
<literal>Authentication</literal> and possibly request-specific
|
||||
<para><interfacename>SecurityContext</interfacename>, to hold the
|
||||
<interfacename>Authentication</interfacename> and possibly request-specific
|
||||
security information.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>HttpSessionContextIntegrationFilter</literal>, to
|
||||
store the <literal>SecurityContext</literal> in the
|
||||
<para><classname>HttpSessionContextIntegrationFilter</classname>, to
|
||||
store the <interfacename>SecurityContext</interfacename> in the
|
||||
<literal>HttpSession</literal> between web requests.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>Authentication</literal>, to represent the
|
||||
<para><interfacename>Authentication</interfacename>, to represent the
|
||||
principal in a Spring Security-specific manner.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>GrantedAuthority</literal>, to reflect the
|
||||
<para><interfacename>GrantedAuthority</interfacename>, to reflect the
|
||||
application-wide permissions granted to a principal.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>UserDetails</literal>, to provide the necessary
|
||||
<para><interfacename>UserDetails</interfacename>, to provide the necessary
|
||||
information to build an Authentication object from your
|
||||
application's DAOs.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>UserDetailsService</literal>, to create a
|
||||
<literal>UserDetails</literal> when passed in a
|
||||
<para><interfacename>UserDetailsService</interfacename>, to create a
|
||||
<interfacename>UserDetails</interfacename> when passed in a
|
||||
<literal>String</literal>-based username (or certificate ID or
|
||||
alike).</para>
|
||||
</listitem>
|
||||
|
@ -321,37 +321,37 @@ if (obj instanceof UserDetails) {
|
|||
|
||||
<para>Spring Security has distinct classes responsible for most of the
|
||||
steps described above. The main participants (in the order that they
|
||||
are used) are the <literal>ExceptionTranslationFilter</literal>, an
|
||||
<literal>AuthenticationEntryPoint</literal>, an authentication
|
||||
mechanism, and an <literal>AuthenticationProvider</literal>.</para>
|
||||
are used) are the <classname>ExceptionTranslationFilter</classname>, an
|
||||
<interfacename>AuthenticationEntryPoint</interfacename>, an authentication
|
||||
mechanism, and an <classname>AuthenticationProvider</classname>.</para>
|
||||
|
||||
<section>
|
||||
<title>ExceptionTranslationFilter</title>
|
||||
<para><literal>ExceptionTranslationFilter</literal> is a Spring
|
||||
<para><classname>ExceptionTranslationFilter</classname> is a Spring
|
||||
Security filter that has responsibility for detecting any Spring
|
||||
Security exceptions that are thrown. Such exceptions will generally be
|
||||
thrown by an <literal>AbstractSecurityInterceptor</literal>, which is
|
||||
thrown by an <classname>AbstractSecurityInterceptor</classname>, which is
|
||||
the main provider of authorization services. We will discuss
|
||||
<literal>AbstractSecurityInterceptor</literal> in the next section,
|
||||
<classname>AbstractSecurityInterceptor</classname> in the next section,
|
||||
but for now we just need to know that it produces Java exceptions and
|
||||
knows nothing about HTTP or how to go about authenticating a
|
||||
principal. Instead the <literal>ExceptionTranslationFilter</literal>
|
||||
principal. Instead the <classname>ExceptionTranslationFilter</classname>
|
||||
offers this service, with specific responsibility for either returning
|
||||
error code 403 (if the principal has been authenticated and therefore
|
||||
simply lacks sufficient access - as per step seven above), or
|
||||
launching an <literal>AuthenticationEntryPoint</literal> (if the
|
||||
launching an <interfacename>AuthenticationEntryPoint</interfacename> (if the
|
||||
principal has not been authenticated and therefore we need to go
|
||||
commence step three).</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="tech-auth-entry-point">
|
||||
<title>AuthenticationEntryPoint</title>
|
||||
<para>The <literal>AuthenticationEntryPoint</literal> is responsible
|
||||
<para>The <interfacename>AuthenticationEntryPoint</interfacename> is responsible
|
||||
for step three in the above list. As you can imagine, each web
|
||||
application will have a default authentication strategy (well, this
|
||||
can be configured like nearly everything else in Spring Security, but
|
||||
let's keep it simple for now). Each major authentication system will
|
||||
have its own <literal>AuthenticationEntryPoint</literal>
|
||||
have its own <interfacename>AuthenticationEntryPoint</interfacename>
|
||||
implementation, which takes actions such as described in step
|
||||
three.</para>
|
||||
|
||||
|
@ -363,7 +363,7 @@ if (obj instanceof UserDetails) {
|
|||
authentication details from a user agent (usually a web browser), and
|
||||
that name is "authentication mechanism". After the authentication
|
||||
details are collected from the user agent, an
|
||||
"<literal>Authentication</literal> request" object is built and then
|
||||
"<interfacename>Authentication</interfacename> request" object is built and then
|
||||
presented to an
|
||||
<interfacename>AuthenticationProvider</interfacename>.</para>
|
||||
</section>
|
||||
|
@ -371,31 +371,31 @@ if (obj instanceof UserDetails) {
|
|||
<section>
|
||||
<title>AuthenticationProvider</title>
|
||||
<para>The last player in the Spring Security authentication process is
|
||||
an <literal>AuthenticationProvider</literal>. Quite simply, it is
|
||||
responsible for taking an <literal>Authentication</literal> request
|
||||
an <classname>AuthenticationProvider</classname>. Quite simply, it is
|
||||
responsible for taking an <interfacename>Authentication</interfacename> request
|
||||
object and deciding whether or not it is valid. The provider will
|
||||
either throw an exception or return a fully populated
|
||||
<literal>Authentication</literal> object. Remember our good friends,
|
||||
<literal>UserDetails</literal> and
|
||||
<literal>UserDetailsService</literal>? If not, head back to the
|
||||
<interfacename>Authentication</interfacename> object. Remember our good friends,
|
||||
<interfacename>UserDetails</interfacename> and
|
||||
<interfacename>UserDetailsService</interfacename>? If not, head back to the
|
||||
previous section and refresh your memory. Most
|
||||
<literal>AuthenticationProvider</literal>s will ask a
|
||||
<literal>UserDetailsService</literal> to provide a
|
||||
<literal>UserDetails</literal> object. As mentioned earlier, most
|
||||
<classname>AuthenticationProvider</classname>s will ask a
|
||||
<interfacename>UserDetailsService</interfacename> to provide a
|
||||
<interfacename>UserDetails</interfacename> object. As mentioned earlier, most
|
||||
application will provide their own
|
||||
<literal>UserDetailsService</literal>, although some will be able to
|
||||
<interfacename>UserDetailsService</interfacename>, although some will be able to
|
||||
use the JDBC or in-memory implementation that ships with Spring
|
||||
Security. The resultant <literal>UserDetails</literal> object - and
|
||||
Security. The resultant <interfacename>UserDetails</interfacename> object - and
|
||||
particularly the <literal>GrantedAuthority[]</literal>s contained
|
||||
within the <literal>UserDetails</literal> object - will be used when
|
||||
building the fully populated <literal>Authentication</literal>
|
||||
within the <interfacename>UserDetails</interfacename> object - will be used when
|
||||
building the fully populated <interfacename>Authentication</interfacename>
|
||||
object.</para>
|
||||
<para>After the authentication mechanism receives back the
|
||||
fully-populated <literal>Authentication</literal> object, it will deem
|
||||
the request valid, put the <literal>Authentication</literal> into the
|
||||
<literal>SecurityContextHolder</literal>, and cause the original
|
||||
fully-populated <interfacename>Authentication</interfacename> object, it will deem
|
||||
the request valid, put the <interfacename>Authentication</interfacename> into the
|
||||
<classname>SecurityContextHolder</classname>, and cause the original
|
||||
request to be retried (step seven above). If, on the other hand, the
|
||||
<literal>AuthenticationProvider</literal> rejected the request, the
|
||||
<classname>AuthenticationProvider</classname> rejected the request, the
|
||||
authentication mechanism will ask the user agent to retry (step two
|
||||
above).</para>
|
||||
|
||||
|
@ -405,11 +405,11 @@ if (obj instanceof UserDetails) {
|
|||
<title>Setting the SecurityContextHolder Contents Directly</title>
|
||||
<para>Whilst this describes the typical authentication workflow, the
|
||||
good news is that Spring Security doesn't mind how you put an
|
||||
<literal>Authentication</literal> inside the
|
||||
<literal>SecurityContextHolder</literal>. The only critical
|
||||
requirement is that the <literal>SecurityContextHolder</literal>
|
||||
contains an <literal>Authentication</literal> that represents a
|
||||
principal before the <literal>AbstractSecurityInterceptor</literal>
|
||||
<interfacename>Authentication</interfacename> inside the
|
||||
<classname>SecurityContextHolder</classname>. The only critical
|
||||
requirement is that the <classname>SecurityContextHolder</classname>
|
||||
contains an <interfacename>Authentication</interfacename> that represents a
|
||||
principal before the <classname>AbstractSecurityInterceptor</classname>
|
||||
needs to authorize a request.</para>
|
||||
|
||||
<para>You can (and many users do) write their own filters or MVC
|
||||
|
@ -474,22 +474,22 @@ if (obj instanceof UserDetails) {
|
|||
<title>AbstractSecurityInterceptor</title>
|
||||
|
||||
<para>Each secure object type supported by Spring Security has its own class,
|
||||
which is a subclass of <literal>AbstractSecurityInterceptor</literal>.
|
||||
Importantly, by the time the <literal>AbstractSecurityInterceptor</literal> is called, the
|
||||
<literal>SecurityContextHolder</literal> will contain a valid
|
||||
<literal>Authentication</literal> if the principal has been
|
||||
which is a subclass of <classname>AbstractSecurityInterceptor</classname>.
|
||||
Importantly, by the time the <classname>AbstractSecurityInterceptor</classname> is called, the
|
||||
<classname>SecurityContextHolder</classname> will contain a valid
|
||||
<interfacename>Authentication</interfacename> if the principal has been
|
||||
authenticated.</para>
|
||||
|
||||
<para><literal>AbstractSecurityInterceptor</literal> provides a
|
||||
<para><classname>AbstractSecurityInterceptor</classname> provides a
|
||||
consistent workflow for handling secure object requests, typically:
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>Look up the "configuration attributes" associated with the
|
||||
present request</para></listitem>
|
||||
<listitem><para>Submitting the secure object, current <literal>Authentication</literal>
|
||||
and configuration attributes to the <literal>AccessDecisionManager</literal> for
|
||||
<listitem><para>Submitting the secure object, current <interfacename>Authentication</interfacename>
|
||||
and configuration attributes to the <interfacename>AccessDecisionManager</interfacename> for
|
||||
an authorization decision</para></listitem>
|
||||
<listitem><para>Optionally change the <literal>Authentication</literal> under which the invocation
|
||||
<listitem><para>Optionally change the <interfacename>Authentication</interfacename> under which the invocation
|
||||
takes place</para></listitem>
|
||||
<listitem><para>Allow the secure object to proceed (assuming access was granted)</para></listitem>
|
||||
<listitem><para>Call the <literal>AfterInvocationManager</literal> if configured, once the invocation
|
||||
|
@ -501,9 +501,9 @@ if (obj instanceof UserDetails) {
|
|||
<title>What are Configuration Attributes?</title>
|
||||
<para>
|
||||
A "configuration attribute" can be thought of as a String that has special meaning to the classes used by
|
||||
<literal>AbstractSecurityInterceptor</literal>. They may be simple role names or have more complex meaning, depending on the
|
||||
how sophisticated the <literal>AccessDecisionManager</literal> implementation is.
|
||||
The <literal>AbstractSecurityInterceptor</literal> is configured with an <literal>ObjectDefinitionSource</literal> which
|
||||
<classname>AbstractSecurityInterceptor</classname>. They may be simple role names or have more complex meaning, depending on the
|
||||
how sophisticated the <interfacename>AccessDecisionManager</interfacename> implementation is.
|
||||
The <classname>AbstractSecurityInterceptor</classname> is configured with an <interfacename>ObjectDefinitionSource</interfacename> which
|
||||
it uses to look up the attributes for a secure object. Usually this configuration will be hidden from the user. Configuration
|
||||
attributes will be entered as annotations on secured methods, or as access attributes on secured URLs (using the
|
||||
namespace <literal><intercept-url></literal> syntax).
|
||||
|
@ -512,14 +512,14 @@ if (obj instanceof UserDetails) {
|
|||
|
||||
<section>
|
||||
<title>RunAsManager</title>
|
||||
<para>Assuming <literal>AccessDecisionManager</literal> decides to
|
||||
allow the request, the <literal>AbstractSecurityInterceptor</literal>
|
||||
<para>Assuming <interfacename>AccessDecisionManager</interfacename> decides to
|
||||
allow the request, the <classname>AbstractSecurityInterceptor</classname>
|
||||
will normally just proceed with the request. Having said that, on rare
|
||||
occasions users may want to replace the
|
||||
<literal>Authentication</literal> inside the
|
||||
<literal>SecurityContext</literal> with a different
|
||||
<literal>Authentication</literal>, which is handled by the
|
||||
<literal>AccessDecisionManager</literal> calling a
|
||||
<interfacename>Authentication</interfacename> inside the
|
||||
<interfacename>SecurityContext</interfacename> with a different
|
||||
<interfacename>Authentication</interfacename>, which is handled by the
|
||||
<interfacename>AccessDecisionManager</interfacename> calling a
|
||||
<literal>RunAsManager</literal>. This might be useful in reasonably
|
||||
unusual situations, such as if a services layer method needs to call a
|
||||
remote system and present a different identity. Because Spring
|
||||
|
@ -532,18 +532,18 @@ if (obj instanceof UserDetails) {
|
|||
<title>AfterInvocationManager</title>
|
||||
<para>Following the secure object proceeding and then returning -
|
||||
which may mean a method invocation completing or a filter chain
|
||||
proceeding - the <literal>AbstractSecurityInterceptor</literal> gets
|
||||
proceeding - the <classname>AbstractSecurityInterceptor</classname> gets
|
||||
one final chance to handle the invocation. At this stage the
|
||||
<literal>AbstractSecurityInterceptor</literal> is interested in
|
||||
<classname>AbstractSecurityInterceptor</classname> is interested in
|
||||
possibly modifying the return object. We might want this to happen
|
||||
because an authorization decision couldn't be made "on the way in" to
|
||||
a secure object invocation. Being highly pluggable,
|
||||
<literal>AbstractSecurityInterceptor</literal> will pass control to an
|
||||
<classname>AbstractSecurityInterceptor</classname> will pass control to an
|
||||
<literal>AfterInvocationManager</literal> to actually modify the
|
||||
object if needed. This class can even entirely replace the object, or
|
||||
throw an exception, or not change it in any way.</para>
|
||||
|
||||
<para><literal>AbstractSecurityInterceptor</literal> and its related objects
|
||||
<para><classname>AbstractSecurityInterceptor</classname> and its related objects
|
||||
are shown in <xref linkend="abstract-security-interceptor"/>.
|
||||
|
||||
<figure xml:id="abstract-security-interceptor">
|
||||
|
@ -570,9 +570,9 @@ if (obj instanceof UserDetails) {
|
|||
around advice semantics) is capable of being made into a secure
|
||||
object. Having said that, most Spring applications will simply use the
|
||||
three currently supported secure object types (AOP Alliance
|
||||
<literal>MethodInvocation</literal>, AspectJ
|
||||
<classname>MethodInvocation</classname>, AspectJ
|
||||
<literal>JoinPoint</literal> and web request
|
||||
<literal>FilterInvocation</literal>) with complete
|
||||
<classname>FilterInvocation</classname>) with complete
|
||||
transparency.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<listitem>
|
||||
<para><literal>subject-principal-regex</literal>. The regular expression used to
|
||||
extract a username from the certificate's subject name. The default value is
|
||||
shown above. This is the username which will be passed to the <literal>UserDetailsService</literal> to load the authorities for the
|
||||
shown above. This is the username which will be passed to the <interfacename>UserDetailsService</interfacename> to load the authorities for the
|
||||
user.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
|
Loading…
Reference in New Issue