|
@@ -1,19 +1,15 @@
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
<?oxygen RNGSchema="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="xml"?>
|
|
|
<article class="faq" xml:id="spring-security-faq" xmlns="http://docbook.org/ns/docbook"
|
|
|
- xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"><info>
|
|
|
- <title>Frequently Answered Questions (FAQ)</title>
|
|
|
- </info>
|
|
|
+ xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"><info><title>Frequently Answered
|
|
|
+ Questions (FAQ)</title></info>
|
|
|
<qandaset>
|
|
|
<qandadiv>
|
|
|
<title>General</title>
|
|
|
<qandaentry xml:id="faq-other-concerns">
|
|
|
- <question>
|
|
|
- <para>Will Spring Security take care of all my application security
|
|
|
- requirements?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> Spring Security provides you with a very flexible framework for your
|
|
|
+ <question><para>Will Spring Security take care of all my application security
|
|
|
+ requirements?</para></question>
|
|
|
+ <answer><para> Spring Security provides you with a very flexible framework for your
|
|
|
authentication and authorization requirements, but there are many other
|
|
|
considerations for building a secure application that are outside its scope.
|
|
|
Web applications are vulnerable to all kinds of attacks which you should be
|
|
@@ -21,141 +17,113 @@
|
|
|
code with them in mind from the beginning. Check out the <link
|
|
|
xlink:href="http://www.owasp.org/">OWASP web site</link> for information
|
|
|
on the major issues facing web application developers and the
|
|
|
- countermeasures you can use against them.</para>
|
|
|
- </answer>
|
|
|
+ countermeasures you can use against them.</para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-web-xml">
|
|
|
- <question>
|
|
|
- <para>Why not just use web.xml security?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>Let's assume you're developing an enterprise application based on Spring.
|
|
|
- There are four security concerns you typically need to address:
|
|
|
+ <question><para>Why not just use web.xml security?</para></question>
|
|
|
+ <answer><para>Let's assume you're developing an enterprise application based on
|
|
|
+ Spring. There are four security concerns you typically need to address:
|
|
|
authentication, web request security, service layer security (i.e. your
|
|
|
methods that implement business logic), and domain object instance security
|
|
|
(i.e. different domain objects have different permissions). With these
|
|
|
- typical requirements in mind: <orderedlist>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Authentication</emphasis>: The servlet specification
|
|
|
- provides an approach to authentication. However, you will need
|
|
|
- to configure the container to perform authentication which
|
|
|
- typically requires editing of container-specific "realm"
|
|
|
- settings. This makes a non-portable configuration, and if you
|
|
|
- need to write an actual Java class to implement the container's
|
|
|
- authentication interface, it becomes even more non-portable.
|
|
|
- With Spring Security you achieve complete portability - right
|
|
|
- down to the WAR level. Also, Spring Security offers a choice of
|
|
|
+ typical requirements in mind:
|
|
|
+ <orderedlist><listitem><para><emphasis>Authentication</emphasis>:
|
|
|
+ The servlet specification provides an approach to
|
|
|
+ authentication. However, you will need to configure the
|
|
|
+ container to perform authentication which typically requires
|
|
|
+ editing of container-specific "realm" settings. This makes a
|
|
|
+ non-portable configuration, and if you need to write an actual
|
|
|
+ Java class to implement the container's authentication
|
|
|
+ interface, it becomes even more non-portable. With Spring
|
|
|
+ Security you achieve complete portability - right down to the
|
|
|
+ WAR level. Also, Spring Security offers a choice of
|
|
|
production-proven authentication providers and mechanisms,
|
|
|
meaning you can switch your authentication approaches at
|
|
|
deployment time. This is particularly valuable for software
|
|
|
vendors writing products that need to work in an unknown target
|
|
|
- environment.</para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Web request security:</emphasis> The servlet
|
|
|
- specification provides an approach to secure your request URIs.
|
|
|
- However, these URIs can only be expressed in the servlet
|
|
|
- specification's own limited URI path format. Spring Security
|
|
|
- provides a far more comprehensive approach. For instance, you
|
|
|
- can use Ant paths or regular expressions, you can consider parts
|
|
|
- of the URI other than simply the requested page (e.g. you can
|
|
|
- consider HTTP GET parameters) and you can implement your own
|
|
|
- runtime source of configuration data. This means your web
|
|
|
- request security can be dynamically changed during the actual
|
|
|
- execution of your webapp.</para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Service layer and domain object security:</emphasis>
|
|
|
- The absence of support in the servlet specification for services
|
|
|
- layer security or domain object instance security represent
|
|
|
- serious limitations for multi-tiered applications. Typically
|
|
|
- developers either ignore these requirements, or implement
|
|
|
- security logic within their MVC controller code (or even worse,
|
|
|
- inside the views). There are serious disadvantages with this
|
|
|
- approach: <orderedlist>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Separation of concerns:</emphasis>
|
|
|
- Authorization is a crosscutting concern and should
|
|
|
- be implemented as such. MVC controllers or views
|
|
|
- implementing authorization code makes it more
|
|
|
- difficult to test both the controller and
|
|
|
- authorization logic, more difficult to debug, and
|
|
|
- will often lead to code duplication.</para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Support for rich clients and web
|
|
|
- services:</emphasis> If an additional client type
|
|
|
- must ultimately be supported, any authorization code
|
|
|
- embedded within the web layer is non-reusable. It
|
|
|
- should be considered that Spring remoting exporters
|
|
|
- only export service layer beans (not MVC
|
|
|
- controllers). As such authorization logic needs to
|
|
|
- be located in the services layer to support a
|
|
|
- multitude of client types.</para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Layering issues:</emphasis> An MVC
|
|
|
- controller or view is simply the incorrect
|
|
|
- architectural layer to implement authorization
|
|
|
- decisions concerning services layer methods or
|
|
|
- domain object instances. Whilst the Principal may be
|
|
|
- passed to the services layer to enable it to make
|
|
|
- the authorization decision, doing so would introduce
|
|
|
- an additional argument on every services layer
|
|
|
- method. A more elegant approach is to use a
|
|
|
- ThreadLocal to hold the Principal, although this
|
|
|
- would likely increase development time to a point
|
|
|
- where it would become more economical (on a
|
|
|
- cost-benefit basis) to simply use a dedicated
|
|
|
- security framework.</para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para><emphasis>Authorisation code quality:</emphasis>
|
|
|
- It is often said of web frameworks that they "make
|
|
|
- it easier to do the right things, and harder to do
|
|
|
- the wrong things". Security frameworks are the same,
|
|
|
- because they are designed in an abstract manner for
|
|
|
- a wide range of purposes. Writing your own
|
|
|
- authorization code from scratch does not provide the
|
|
|
- "design check" a framework would offer, and in-house
|
|
|
- authorization code will typically lack the
|
|
|
- improvements that emerge from widespread deployment,
|
|
|
- peer review and new versions. </para>
|
|
|
- </listitem>
|
|
|
- </orderedlist></para>
|
|
|
- </listitem>
|
|
|
- </orderedlist></para>
|
|
|
- <para> For simple applications, servlet specification security may just be
|
|
|
- enough. Although when considered within the context of web container
|
|
|
- portability, configuration requirements, limited web request security
|
|
|
- flexibility, and non-existent services layer and domain object instance
|
|
|
- security, it becomes clear why developers often look to alternative
|
|
|
- solutions. </para>
|
|
|
- </answer>
|
|
|
+ environment.</para></listitem><listitem><para><emphasis>Web
|
|
|
+ request security:</emphasis> The servlet specification
|
|
|
+ provides an approach to secure your request URIs. However, these
|
|
|
+ URIs can only be expressed in the servlet specification's own
|
|
|
+ limited URI path format. Spring Security provides a far more
|
|
|
+ comprehensive approach. For instance, you can use Ant paths or
|
|
|
+ regular expressions, you can consider parts of the URI other
|
|
|
+ than simply the requested page (e.g. you can consider HTTP GET
|
|
|
+ parameters) and you can implement your own runtime source of
|
|
|
+ configuration data. This means your web request security can be
|
|
|
+ dynamically changed during the actual execution of your
|
|
|
+ webapp.</para></listitem><listitem><para><emphasis>Service layer
|
|
|
+ and domain object security:</emphasis> The absence of
|
|
|
+ support in the servlet specification for services layer security
|
|
|
+ or domain object instance security represent serious limitations
|
|
|
+ for multi-tiered applications. Typically developers either
|
|
|
+ ignore these requirements, or implement security logic within
|
|
|
+ their MVC controller code (or even worse, inside the views).
|
|
|
+ There are serious disadvantages with this approach:
|
|
|
+ <orderedlist><listitem><para><emphasis>Separation
|
|
|
+ of concerns:</emphasis> Authorization is a
|
|
|
+ crosscutting concern and should be implemented as
|
|
|
+ such. MVC controllers or views implementing
|
|
|
+ authorization code makes it more difficult to test
|
|
|
+ both the controller and authorization logic, more
|
|
|
+ difficult to debug, and will often lead to code
|
|
|
+ duplication.</para></listitem><listitem><para><emphasis>Support
|
|
|
+ for rich clients and web services:</emphasis> If
|
|
|
+ an additional client type must ultimately be
|
|
|
+ supported, any authorization code embedded within
|
|
|
+ the web layer is non-reusable. It should be
|
|
|
+ considered that Spring remoting exporters only
|
|
|
+ export service layer beans (not MVC controllers). As
|
|
|
+ such authorization logic needs to be located in the
|
|
|
+ services layer to support a multitude of client
|
|
|
+ types.</para></listitem><listitem><para><emphasis>Layering
|
|
|
+ issues:</emphasis> An MVC controller or view is
|
|
|
+ simply the incorrect architectural layer to
|
|
|
+ implement authorization decisions concerning
|
|
|
+ services layer methods or domain object instances.
|
|
|
+ Whilst the Principal may be passed to the services
|
|
|
+ layer to enable it to make the authorization
|
|
|
+ decision, doing so would introduce an additional
|
|
|
+ argument on every services layer method. A more
|
|
|
+ elegant approach is to use a ThreadLocal to hold the
|
|
|
+ Principal, although this would likely increase
|
|
|
+ development time to a point where it would become
|
|
|
+ more economical (on a cost-benefit basis) to simply
|
|
|
+ use a dedicated security
|
|
|
+ framework.</para></listitem><listitem><para><emphasis>Authorisation
|
|
|
+ code quality:</emphasis> It is often said of web
|
|
|
+ frameworks that they "make it easier to do the right
|
|
|
+ things, and harder to do the wrong things". Security
|
|
|
+ frameworks are the same, because they are designed
|
|
|
+ in an abstract manner for a wide range of purposes.
|
|
|
+ Writing your own authorization code from scratch
|
|
|
+ does not provide the "design check" a framework
|
|
|
+ would offer, and in-house authorization code will
|
|
|
+ typically lack the improvements that emerge from
|
|
|
+ widespread deployment, peer review and new versions.
|
|
|
+ </para></listitem></orderedlist></para></listitem></orderedlist></para><para>
|
|
|
+ For simple applications, servlet specification security may just be enough.
|
|
|
+ Although when considered within the context of web container portability,
|
|
|
+ configuration requirements, limited web request security flexibility, and
|
|
|
+ non-existent services layer and domain object instance security, it becomes
|
|
|
+ clear why developers often look to alternative solutions. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-requirements">
|
|
|
- <question>
|
|
|
- <para>What Java and Spring Framework versions are required?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> Spring Security 2.0.x requires a minimum JDK version of 1.4 and is built
|
|
|
- against Spring 2.0.x. It should also be compatible with applications using
|
|
|
- Spring 2.5.x. </para>
|
|
|
- <para> Spring Security 3.0 requires JDK 1.5 as a minimum and will also require
|
|
|
- Spring 3.0. </para>
|
|
|
- </answer>
|
|
|
+ <question><para>What Java and Spring Framework versions are
|
|
|
+ required?</para></question>
|
|
|
+ <answer><para> Spring Security 2.0.x requires a minimum JDK version of 1.4 and is
|
|
|
+ built against Spring 2.0.x. It should also be compatible with applications
|
|
|
+ using Spring 2.5.x. </para><para> Spring Security 3.0 requires JDK 1.5 as a
|
|
|
+ minimum and will also require Spring 3.0. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-start-simple">
|
|
|
- <question>
|
|
|
- <para> I'm new to Spring Security and I need to build an application that
|
|
|
+ <question><para> I'm new to Spring Security and I need to build an application that
|
|
|
supports CAS single sign-on over HTTPS, while allowing Basic authentication
|
|
|
locally for certain URLs, authenticating against multiple back end user
|
|
|
information sources (LDAP and JDBC). I've copied some configuration files I
|
|
|
- found but it doesn't work. What could be wrong? </para>
|
|
|
- <para>Or subsititute an alternative complex scenario...</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> Realistically, you need an understanding of the technolgies you are
|
|
|
+ found but it doesn't work. What could be wrong? </para><para>Or subsititute
|
|
|
+ an alternative complex scenario...</para></question>
|
|
|
+ <answer><para> Realistically, you need an understanding of the technolgies you are
|
|
|
intending to use before you can successfully build applications with them.
|
|
|
Security is complicated. Setting up a simple configuration using a login
|
|
|
form and some hard-coded users using Spring Security's namespace is
|
|
@@ -164,251 +132,208 @@
|
|
|
scenario like this you will almost certainly be frustrated. There is a big
|
|
|
jump in the learning curve required to set up systems like CAS, configure
|
|
|
LDAP servers and install SSL certificates properly. So you need to take
|
|
|
- things one step at a time. </para>
|
|
|
- <para> From a Spring Security perspective, the first thing you should do is
|
|
|
- follow the <quote>Getting Started</quote> guide on the web site. This will
|
|
|
- take you through a series of steps to get up and running and get some idea
|
|
|
- of how the framework operates. If you are using other technologies which you
|
|
|
- aren't familiar with then you should do some research and try to make sure
|
|
|
- you can use them in isolation before combining them in a complex system.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
+ things one step at a time. </para><para> From a Spring Security perspective,
|
|
|
+ the first thing you should do is follow the <quote>Getting Started</quote>
|
|
|
+ guide on the web site. This will take you through a series of steps to get
|
|
|
+ up and running and get some idea of how the framework operates. If you are
|
|
|
+ using other technologies which you aren't familiar with then you should do
|
|
|
+ some research and try to make sure you can use them in isolation before
|
|
|
+ combining them in a complex system. </para></answer>
|
|
|
</qandaentry>
|
|
|
</qandadiv>
|
|
|
<qandadiv>
|
|
|
<title>Common Problems</title>
|
|
|
<qandaentry xml:id="faq-login-loop">
|
|
|
- <question>
|
|
|
- <para>My application goes into an "endless loop" when I try to login, what's
|
|
|
- going on?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>A common user problem with infinite loop and redirecting to the login page
|
|
|
- is caused by accidently configuring the login page as a "secured" resource.
|
|
|
- Make sure your configuration allows anonymous access to the login page,
|
|
|
- either by excluding it from the security filter chain or marking it as
|
|
|
- requiring ROLE_ANONYMOUS.</para>
|
|
|
- <para>If your AccessDecisionManager includes an AutheticatedVoter, you can use
|
|
|
- the attribute "IS_AUTHENTICATED_ANONYMOUSLY". This is automatically
|
|
|
- available if you are using the standard namespace configuration setup. </para>
|
|
|
- <para> From Spring Security 2.0.1 onwards, when you are using namespace-based
|
|
|
- configuration, a check will be made on loading the application context and a
|
|
|
- warning message logged if your login page appears to be protected. </para>
|
|
|
- </answer>
|
|
|
+ <question><para>My application goes into an "endless loop" when I try to login,
|
|
|
+ what's going on?</para></question>
|
|
|
+ <answer><para>A common user problem with infinite loop and redirecting to the login
|
|
|
+ page is caused by accidently configuring the login page as a "secured"
|
|
|
+ resource. Make sure your configuration allows anonymous access to the login
|
|
|
+ page, either by excluding it from the security filter chain or marking it as
|
|
|
+ requiring ROLE_ANONYMOUS.</para><para>If your AccessDecisionManager includes
|
|
|
+ an AuthenticatedVoter, you can use the attribute
|
|
|
+ "IS_AUTHENTICATED_ANONYMOUSLY". This is automatically available if you are
|
|
|
+ using the standard namespace configuration setup. </para><para> From Spring
|
|
|
+ Security 2.0.1 onwards, when you are using namespace-based configuration, a
|
|
|
+ check will be made on loading the application context and a warning message
|
|
|
+ logged if your login page appears to be protected. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-anon-access-denied">
|
|
|
- <question>
|
|
|
- <para>I get an exception with the message "Access is denied (user is
|
|
|
- anonymous);". What's wrong?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> This is a debug level message which occurs the first time an anonymous
|
|
|
- user attempts to access a protected resource.
|
|
|
+ <question><para>I get an exception with the message "Access is denied (user is
|
|
|
+ anonymous);". What's wrong?</para></question>
|
|
|
+ <answer><para> This is a debug level message which occurs the first time an
|
|
|
+ anonymous user attempts to access a protected resource.
|
|
|
<programlisting>
|
|
|
DEBUG [ExceptionTranslationFilter] - Access is denied (user is anonymous); redirecting to authentication entry point
|
|
|
org.springframework.security.AccessDeniedException: Access is denied
|
|
|
at org.springframework.security.vote.AffirmativeBased.decide(AffirmativeBased.java:68)
|
|
|
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:262)
|
|
|
</programlisting>
|
|
|
- It is normal and shouldn't be anything to worry about. </para>
|
|
|
- </answer>
|
|
|
+ It is normal and shouldn't be anything to worry about. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-cached-secure-page">
|
|
|
- <question>
|
|
|
- <para>Why can I still see a secured page even after I've logged out of my application?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>The most common reason for this is that your browser has cached the page and you are seeing a
|
|
|
- copy which is being retrieved from the browsers cache. Verify this by checking whether the browser is actually sending
|
|
|
- the request (check your server access logs, the debug log or use a suitable browser debugging plugin such as <quote>Tamper Data</quote>
|
|
|
- for Firefox). This has nothing to do with Spring Security and you should configure your application or server to set the
|
|
|
- appropriate <literal>Cache-Control</literal> response headers. Note that SSL requests are never cached.</para>
|
|
|
- </answer>
|
|
|
+ <question><para>Why can I still see a secured page even after I've logged out of my
|
|
|
+ application?</para></question>
|
|
|
+ <answer><para>The most common reason for this is that your browser has cached the
|
|
|
+ page and you are seeing a copy which is being retrieved from the browsers
|
|
|
+ cache. Verify this by checking whether the browser is actually sending the
|
|
|
+ request (check your server access logs, the debug log or use a suitable
|
|
|
+ browser debugging plugin such as <quote>Tamper Data</quote> for Firefox).
|
|
|
+ This has nothing to do with Spring Security and you should configure your
|
|
|
+ application or server to set the appropriate
|
|
|
+ <literal>Cache-Control</literal> response headers. Note that SSL
|
|
|
+ requests are never cached.</para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="auth-exception-credentials-not-found">
|
|
|
- <question>
|
|
|
- <para>I get an exception with the message "An Authentication object was not
|
|
|
- found in the SecurityContext". What's wrong?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> This is a another debug level message which occurs the first time an
|
|
|
+ <question><para>I get an exception with the message "An Authentication object was
|
|
|
+ not found in the SecurityContext". What's wrong?</para></question>
|
|
|
+ <answer><para> This is a another debug level message which occurs the first time an
|
|
|
anonymous user attempts to access a protected resource, but when you do not
|
|
|
- have an <classname>AnonymousAuthenticationFilter</classname> in your filter chain configuration.
|
|
|
+ have an <classname>AnonymousAuthenticationFilter</classname> in your filter
|
|
|
+ chain configuration.
|
|
|
<programlisting>
|
|
|
DEBUG [ExceptionTranslationFilter] - Authentication exception occurred; redirecting to authentication entry point
|
|
|
org.springframework.security.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
|
|
|
at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
|
|
|
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)
|
|
|
</programlisting>
|
|
|
- It is normal and shouldn't be anything to worry about. </para>
|
|
|
- </answer>
|
|
|
+ It is normal and shouldn't be anything to worry about. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-tomcat-https-session">
|
|
|
- <question>
|
|
|
- <para> I'm using Tomcat and have enabled HTTPS for my login page, switching back
|
|
|
- to HTTP afterwards. It doesn't work - I just end up back at the login page
|
|
|
- after authenticating. </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> This happens because Tomcat sessions created under HTTPS cannot
|
|
|
+ <question><para> I'm using Tomcat and have enabled HTTPS for my login page,
|
|
|
+ switching back to HTTP afterwards. It doesn't work - I just end up back at
|
|
|
+ the login page after authenticating. </para></question>
|
|
|
+ <answer><para> This happens because Tomcat sessions created under HTTPS cannot
|
|
|
subsequently be used under HTTP and any session state is lost (including the
|
|
|
security context information). Starting a session in HTTP first should work
|
|
|
- as the session cookie won't be marked as secure. </para>
|
|
|
- </answer>
|
|
|
+ as the session cookie won't be marked as secure. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-no-security-on-forward">
|
|
|
- <question>
|
|
|
- <para> I'm forwarding a request to another URL using the RequestDispatcher, but
|
|
|
- my security constraints aren't being applied. </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> Filters are not applied by default to forwards or includes. If you really
|
|
|
- want the security filters to be applied to forwards and/or includes, then
|
|
|
- you have to configure these explicitly in your web.xml using the
|
|
|
+ <question><para> I'm forwarding a request to another URL using the
|
|
|
+ RequestDispatcher, but my security constraints aren't being applied.
|
|
|
+ </para></question>
|
|
|
+ <answer><para> Filters are not applied by default to forwards or includes. If you
|
|
|
+ really want the security filters to be applied to forwards and/or includes,
|
|
|
+ then you have to configure these explicitly in your web.xml using the
|
|
|
<dispatcher> element, a child element of <filter-mapping>.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
+ </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-session-listener-missing">
|
|
|
- <question>
|
|
|
- <para> I'm trying to use the concurrent session-control support but it won't let
|
|
|
- me log back in, even if I'm sure I've logged out and haven't exceeded the
|
|
|
- allowed sessions. </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>Make sure you have added the listener to your web.xml file. It is
|
|
|
+ <question><para> I'm trying to use the concurrent session-control support but it
|
|
|
+ won't let me log back in, even if I'm sure I've logged out and haven't
|
|
|
+ exceeded the allowed sessions. </para></question>
|
|
|
+ <answer><para>Make sure you have added the listener to your web.xml file. It is
|
|
|
essential to make sure that the Spring Security session registry is notified
|
|
|
when a session is destroyed. Without it, the session information will not be
|
|
|
- removed from the registry.</para>
|
|
|
- <programlisting><![CDATA[
|
|
|
+ removed from the registry.</para><programlisting><![CDATA[
|
|
|
<listener>
|
|
|
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
|
|
</listener> ]]>
|
|
|
- </programlisting>
|
|
|
- </answer>
|
|
|
+ </programlisting></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-no-filters-no-context">
|
|
|
- <question>
|
|
|
- <para>I have a user who has definitely been authenticated, but when I try to
|
|
|
- access the <classname>SecurityContextHolder</classname> during some
|
|
|
+ <question><para>I have a user who has definitely been authenticated, but when I try
|
|
|
+ to access the <classname>SecurityContextHolder</classname> during some
|
|
|
requests, the <interfacename>Authentication</interfacename> is null. Why
|
|
|
- can't I see the user information? </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>If you have excluded the request from the security filter chain using the
|
|
|
- attribute <literal>filters='none'</literal> in the
|
|
|
+ can't I see the user information? </para></question>
|
|
|
+ <answer><para>If you have excluded the request from the security filter chain using
|
|
|
+ the attribute <literal>filters='none'</literal> in the
|
|
|
<literal><intercept-url></literal> element that matches the URL
|
|
|
pattern, then the <classname>SecurityContextHolder</classname> will not be
|
|
|
populated for that request. Check the debug log to see whether the request
|
|
|
is passing through the filter chain. (You are reading the debug log,
|
|
|
- right?).</para>
|
|
|
- </answer>
|
|
|
+ right?).</para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-method-security-in-web-context">
|
|
|
- <question><para>I have added Spring Security's <global-method-security> element to my application context but if I add
|
|
|
- security annotations to my Spring MVC controller beans (Struts actions etc.) then they don't seem to have an effect.</para>
|
|
|
- </question>
|
|
|
- <answer><para>
|
|
|
- The application context which holds the Spring MVC beans for the dispatcher servlet is a child application context
|
|
|
- of the main application context which is loaded using the <classname>ContextLoaderListener</classname> you define in your
|
|
|
- <filename>web.xml</filename>. The beans in the child context are not visible in the parent context so you need to either
|
|
|
- move the <global-method-security> declaration to the web context or moved the beans you want secured into the main
|
|
|
- application context.
|
|
|
- </para>
|
|
|
- <para>Generally we would recommend applying method security at the service layer rather than on individual web
|
|
|
- controllers.</para>
|
|
|
- </answer>
|
|
|
+ <question><para>I have added Spring Security's <global-method-security>
|
|
|
+ element to my application context but if I add security annotations to my
|
|
|
+ Spring MVC controller beans (Struts actions etc.) then they don't seem to
|
|
|
+ have an effect.</para></question>
|
|
|
+ <answer><para> The application context which holds the Spring MVC beans for the
|
|
|
+ dispatcher servlet is a child application context of the main application
|
|
|
+ context which is loaded using the
|
|
|
+ <classname>ContextLoaderListener</classname> you define in your
|
|
|
+ <filename>web.xml</filename>. The beans in the child context are not
|
|
|
+ visible in the parent context so you need to either move the
|
|
|
+ <global-method-security> declaration to the web context or moved the
|
|
|
+ beans you want secured into the main application context.
|
|
|
+ </para><para>Generally we would recommend applying method security at the
|
|
|
+ service layer rather than on individual web controllers.</para></answer>
|
|
|
</qandaentry>
|
|
|
</qandadiv>
|
|
|
<qandadiv>
|
|
|
<title>Spring Security Architecture Questions</title>
|
|
|
<qandaentry xml:id="faq-where-is-class-x">
|
|
|
- <question>
|
|
|
- <para>How do I know which package class X is in?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>The best way of locating classes is by installing the Spring Security
|
|
|
+ <question><para>How do I know which package class X is in?</para></question>
|
|
|
+ <answer><para>The best way of locating classes is by installing the Spring Security
|
|
|
source in your IDE. The distribution includes source jars for each of the
|
|
|
modules the project is divided up into. Add these to your project source
|
|
|
path and you can navigate directly to Spring Security classes
|
|
|
(<command>Ctrl-Shift-T</command> in Eclipse). This also makes debugging
|
|
|
easer and allows you to troubleshoot exceptions by looking directly at the
|
|
|
- code where they occur to see what's going on there. </para>
|
|
|
- </answer>
|
|
|
+ code where they occur to see what's going on there. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-namespace-to-bean-mapping">
|
|
|
- <question>
|
|
|
- <para>How do the namespace elements map to conventional bean
|
|
|
- configurations?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>There is a general overview of what beans are created by the namespace in
|
|
|
- the namespace appendix of the reference guide. If want to know the full
|
|
|
+ <question><para>How do the namespace elements map to conventional bean
|
|
|
+ configurations?</para></question>
|
|
|
+ <answer><para>There is a general overview of what beans are created by the namespace
|
|
|
+ in the namespace appendix of the reference guide. If want to know the full
|
|
|
details then the code is in the <filename>spring-security-config</filename>
|
|
|
module within the Spring Security 3.0 distribution. You should probably read
|
|
|
the chapters on namespace parsing in the standard Spring Framework reference
|
|
|
- documentation first. </para>
|
|
|
- </answer>
|
|
|
+ documentation first. </para></answer>
|
|
|
</qandaentry>
|
|
|
</qandadiv>
|
|
|
<qandadiv>
|
|
|
<title>Common <quote>Howto</quote> Requests</title>
|
|
|
<qandaentry xml:id="faq-extra-login-fields">
|
|
|
- <question>
|
|
|
- <para>I need to login in with more information than just the username. How do I
|
|
|
- add support for extra login fields (e.g. a company name)?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>This question comes up repeatedly in the Spring Security forum so you will
|
|
|
- find more information there by searching the archives (or through
|
|
|
- google).</para>
|
|
|
- <para> The submitted login information is processed by an instance of
|
|
|
- <classname>UsernamePasswordAuthenticationFilter</classname>. You will need to
|
|
|
- customize this class to handle the extra data field(s). One option is to use
|
|
|
- your own customized authentication token class (rather than the standard
|
|
|
- <classname>UsernamePasswordAuthenticationToken</classname>), another is
|
|
|
- simply to concatenate the extra fields with the username (for example, using
|
|
|
- a ":" as the separator) and pass them in the username property of
|
|
|
- <classname>UsernamePasswordAuthenticationToken</classname>. </para>
|
|
|
- <para> You will also need to customize the actual authentication process. If you
|
|
|
- are using a custom authentication token class, for example, you will have to
|
|
|
- write an <classname>AuthenticationProvider</classname> to handle it (or
|
|
|
- extend the standard <classname>DaoAuthenticationProvider</classname>). If
|
|
|
- you have concatenated the fields, you can implement your own
|
|
|
+ <question><para>I need to login in with more information than just the username. How
|
|
|
+ do I add support for extra login fields (e.g. a company
|
|
|
+ name)?</para></question>
|
|
|
+ <answer><para>This question comes up repeatedly in the Spring Security forum so you
|
|
|
+ will find more information there by searching the archives (or through
|
|
|
+ google).</para><para> The submitted login information is processed by an
|
|
|
+ instance of <classname>UsernamePasswordAuthenticationFilter</classname>. You
|
|
|
+ will need to customize this class to handle the extra data field(s). One
|
|
|
+ option is to use your own customized authentication token class (rather than
|
|
|
+ the standard <classname>UsernamePasswordAuthenticationToken</classname>),
|
|
|
+ another is simply to concatenate the extra fields with the username (for
|
|
|
+ example, using a ":" as the separator) and pass them in the username
|
|
|
+ property of <classname>UsernamePasswordAuthenticationToken</classname>.
|
|
|
+ </para><para> You will also need to customize the actual authentication
|
|
|
+ process. If you are using a custom authentication token class, for example,
|
|
|
+ you will have to write an <classname>AuthenticationProvider</classname> to
|
|
|
+ handle it (or extend the standard
|
|
|
+ <classname>DaoAuthenticationProvider</classname>). If you have
|
|
|
+ concatenated the fields, you can implement your own
|
|
|
<interfacename>UserDetailsService</interfacename> which splits them up
|
|
|
- and loads the appropriate user data for authentication. </para>
|
|
|
- </answer>
|
|
|
+ and loads the appropriate user data for authentication. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-dynamic-url-metadata">
|
|
|
- <question>
|
|
|
- <para>How do I define the secured URLs within an application
|
|
|
- dynamically?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>People often ask about how to store the mapping between secured URLs and
|
|
|
- security metadata attributes in a database, rather than in the application
|
|
|
- context. </para>
|
|
|
- <para> The first thing you should ask yourself is if you really need to do this.
|
|
|
- If an application requires securing, then it also requires that the security
|
|
|
- be tested thoroughly based on a defined policy. It may require auditing and
|
|
|
- acceptance testing before being rolled out into a production environment. A
|
|
|
- security-conscious organization should be aware that the benefits of their
|
|
|
- diligent testing process could be wiped out instantly by allowing the
|
|
|
- security settings to be modified at runtime by changing a row or two in a
|
|
|
- configuration database. If you have taken this into account (perhaps using
|
|
|
- multiple layers of security within your application) then Spring Security
|
|
|
- allows you to fully customize the source of security metadata. You can make
|
|
|
- it fully dynamic if you choose. </para>
|
|
|
- <para> Both method and web security are protected by subclasses of
|
|
|
+ <question><para>How do I define the secured URLs within an application
|
|
|
+ dynamically?</para></question>
|
|
|
+ <answer><para>People often ask about how to store the mapping between secured URLs
|
|
|
+ and security metadata attributes in a database, rather than in the
|
|
|
+ application context. </para><para> The first thing you should ask yourself
|
|
|
+ is if you really need to do this. If an application requires securing, then
|
|
|
+ it also requires that the security be tested thoroughly based on a defined
|
|
|
+ policy. It may require auditing and acceptance testing before being rolled
|
|
|
+ out into a production environment. A security-conscious organization should
|
|
|
+ be aware that the benefits of their diligent testing process could be wiped
|
|
|
+ out instantly by allowing the security settings to be modified at runtime by
|
|
|
+ changing a row or two in a configuration database. If you have taken this
|
|
|
+ into account (perhaps using multiple layers of security within your
|
|
|
+ application) then Spring Security allows you to fully customize the source
|
|
|
+ of security metadata. You can make it fully dynamic if you choose.
|
|
|
+ </para><para> Both method and web security are protected by subclasses of
|
|
|
<classname>AbstractSecurityInterceptor</classname> which is configured
|
|
|
with a <interfacename>SecurityMetadataSource</interfacename> from which it
|
|
|
- obtains the metadata for a particular method or filter invocation <footnote>
|
|
|
- <para>This class previouly went by the rather obscure name of
|
|
|
- <classname>ObjectDefinitionSource</classname>, but has been
|
|
|
- renamed in Spring Security 3.0</para>
|
|
|
- </footnote>. For web security, the interceptor class is
|
|
|
- <classname>FilterSecurityInterceptor</classname> and it uses the marker
|
|
|
- interface
|
|
|
+ obtains the metadata for a particular method or filter invocation
|
|
|
+ <footnote><para>This class previouly went by the rather obscure name
|
|
|
+ of <classname>ObjectDefinitionSource</classname>, but has been
|
|
|
+ renamed in Spring Security 3.0</para></footnote>. For web security,
|
|
|
+ the interceptor class is <classname>FilterSecurityInterceptor</classname>
|
|
|
+ and it uses the marker interface
|
|
|
<interfacename>FilterInvocationSecurityMetadataSource</interfacename>.
|
|
|
The <quote>secured object</quote> type it operates on is a
|
|
|
<classname>FilterInvocation</classname>. The default implementation
|
|
@@ -416,20 +341,20 @@
|
|
|
when configuring the interceptor explicitly, stores the list of URL patterns
|
|
|
and their corresponding list of <quote>configuration attributes</quote>
|
|
|
(instances of <interfacename>ConfigAttribute</interfacename>) in an
|
|
|
- in-memory map. </para>
|
|
|
- <para> To load the data from an alternative source, you must be using an
|
|
|
- explicitly declared security filter chain (typically Spring Security's
|
|
|
- <classname>FilterChainProxy</classname>) in order to customize the
|
|
|
- <classname>FilterSecurityInterceptor</classname> bean. You can't use the
|
|
|
- namespace. You would then implement
|
|
|
+ in-memory map. </para><para> To load the data from an alternative source,
|
|
|
+ you must be using an explicitly declared security filter chain (typically
|
|
|
+ Spring Security's <classname>FilterChainProxy</classname>) in order to
|
|
|
+ customize the <classname>FilterSecurityInterceptor</classname> bean. You
|
|
|
+ can't use the namespace. You would then implement
|
|
|
<interfacename>FilterInvocationSecurityMetadataSource</interfacename> to
|
|
|
load the data as you please for a particular
|
|
|
- <classname>FilterInvocation</classname><footnote>
|
|
|
- <para>The <classname>FilterInvocation</classname> object contains the
|
|
|
+ <classname>FilterInvocation</classname><footnote><para>The
|
|
|
+ <classname>FilterInvocation</classname> object contains the
|
|
|
<classname>HttpServletRequest</classname>, so you can obtain the
|
|
|
URL or any other relevant information on which to base your decision
|
|
|
- on what the list of returned attributes will contain.</para>
|
|
|
- </footnote>. A very basic outline would look something like this: <programlisting language="java"><![CDATA[
|
|
|
+ on what the list of returned attributes will
|
|
|
+ contain.</para></footnote>. A very basic outline would look something
|
|
|
+ like this: <programlisting language="java"><![CDATA[
|
|
|
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
|
|
|
|
|
|
public List<ConfigAttribute> getAttributes(Object object) {
|
|
@@ -454,54 +379,46 @@
|
|
|
}
|
|
|
]]></programlisting> For more information, look at the code for
|
|
|
<classname>DefaultFilterInvocationSecurityMetadataSource</classname>.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
+ </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-what-dependencies">
|
|
|
- <question>
|
|
|
- <para>How do I know which dependencies to add to my application to work with
|
|
|
- Spring Security?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>It will depend on what features you are using and what type of application
|
|
|
- you are developing. With Spring Security 3.0, the project jars are divided
|
|
|
- into clearly distinct areas of functionality, so it is straightforward to
|
|
|
- work out which Spring Security jars you need from your application
|
|
|
- requirements. All applications will need the
|
|
|
+ <question><para>How do I know which dependencies to add to my application to work
|
|
|
+ with Spring Security?</para></question>
|
|
|
+ <answer><para>It will depend on what features you are using and what type of
|
|
|
+ application you are developing. With Spring Security 3.0, the project jars
|
|
|
+ are divided into clearly distinct areas of functionality, so it is
|
|
|
+ straightforward to work out which Spring Security jars you need from your
|
|
|
+ application requirements. All applications will need the
|
|
|
<filename>spring-security-core</filename> jar. If you're developing a
|
|
|
web application, you need the <filename>spring-security-web</filename> jar.
|
|
|
If you're using security namespace configuration you need the
|
|
|
<filename>spring-security-config</filename> jar, for LDAP support you
|
|
|
- need the <filename>spring-security-ldap</filename> jar and so on. </para>
|
|
|
- <para> For third-party jars the situation isn't always quite so obvious. A good
|
|
|
- starting point is to copy those from one of the pre-built sample
|
|
|
- applications WEB-INF/lib directories. For a basic application, you can start
|
|
|
- with the tutorial sample. If you want to use LDAP, with an embedded test
|
|
|
- server, then use the LDAP sample as a starting point. </para>
|
|
|
- <para> If you are building your project with maven, then adding the appropriate
|
|
|
- Spring Security modules as dependencies to your pom.xml will automatically
|
|
|
- pull in the core jars that the framework requires. Any which are marked as
|
|
|
- "optional" in the Spring Security POM files will have to be added to your
|
|
|
- own pom.xml file if you need them. </para>
|
|
|
- </answer>
|
|
|
+ need the <filename>spring-security-ldap</filename> jar and so on.
|
|
|
+ </para><para> For third-party jars the situation isn't always quite so
|
|
|
+ obvious. A good starting point is to copy those from one of the pre-built
|
|
|
+ sample applications WEB-INF/lib directories. For a basic application, you
|
|
|
+ can start with the tutorial sample. If you want to use LDAP, with an
|
|
|
+ embedded test server, then use the LDAP sample as a starting point.
|
|
|
+ </para><para> If you are building your project with maven, then adding the
|
|
|
+ appropriate Spring Security modules as dependencies to your pom.xml will
|
|
|
+ automatically pull in the core jars that the framework requires. Any which
|
|
|
+ are marked as "optional" in the Spring Security POM files will have to be
|
|
|
+ added to your own pom.xml file if you need them. </para></answer>
|
|
|
</qandaentry>
|
|
|
<qandaentry xml:id="faq-ldap-authorities">
|
|
|
- <question>
|
|
|
- <para>How do I authenticate against LDAP but load user roles from a
|
|
|
- database?</para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para> The <code>LdapAuthenticationProvider</code> bean (which handles normal
|
|
|
- LDAP authentication in Spring Security) is configured with two separate
|
|
|
- strategy interfaces, one which performs the authenticatation and one which
|
|
|
- loads the user authorities, called
|
|
|
+ <question><para>How do I authenticate against LDAP but load user roles from a
|
|
|
+ database?</para></question>
|
|
|
+ <answer><para> The <code>LdapAuthenticationProvider</code> bean (which handles
|
|
|
+ normal LDAP authentication in Spring Security) is configured with two
|
|
|
+ separate strategy interfaces, one which performs the authenticatation and
|
|
|
+ one which loads the user authorities, called
|
|
|
<interfacename>LdapAuthenticator</interfacename> and
|
|
|
<interfacename>LdapAuthoritiesPopulator</interfacename> respectively.
|
|
|
- The <classname>DefaultLdapAuthoitiesPopulator</classname> loads the user
|
|
|
+ The <classname>DefaultLdapAuthoritiesPopulator</classname> loads the user
|
|
|
authorities from the LDAP directory and has various configuration parameters
|
|
|
- to allow you to specify how these should be retrieved. </para>
|
|
|
- <para> To use JDBC instead, you can implement the interface yourself, using
|
|
|
- whatever SQL is appropriate for your schema: <programlisting language="java"><![CDATA[
|
|
|
+ to allow you to specify how these should be retrieved. </para><para> To use
|
|
|
+ JDBC instead, you can implement the interface yourself, using whatever SQL
|
|
|
+ is appropriate for your schema: <programlisting language="java"><![CDATA[
|
|
|
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
|
|
@Autowired
|
|
|
JdbcTemplate template;
|
|
@@ -523,8 +440,7 @@
|
|
|
section on configuring LDAP using explicit Spring beans in the LDAP chapter
|
|
|
of the reference manual. Note that you can't use the namespace for
|
|
|
configuration in this case. You should also consult the Javadoc for the
|
|
|
- relevant classes and interfaces. </para>
|
|
|
- </answer>
|
|
|
+ relevant classes and interfaces. </para></answer>
|
|
|
</qandaentry>
|
|
|
</qandadiv>
|
|
|
</qandaset>
|