mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-01 09:42:13 +00:00
updates to faq and codebase article
This commit is contained in:
parent
31e2319f8a
commit
b50d37fa66
@ -9,7 +9,7 @@
|
|||||||
<personname>Luke Taylor</personname>
|
<personname>Luke Taylor</personname>
|
||||||
<affiliation><orgname>SpringSource</orgname></affiliation></author>
|
<affiliation><orgname>SpringSource</orgname></affiliation></author>
|
||||||
<abstract>
|
<abstract>
|
||||||
<para>An quick introduction to the code modules and package structure of the Spring
|
<para>A quick introduction to the code modules and package structure of the Spring
|
||||||
Security 3.0 codebase.</para>
|
Security 3.0 codebase.</para>
|
||||||
</abstract>
|
</abstract>
|
||||||
</info>
|
</info>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<para>In versions prior to 3.0, most of Spring Security's code was contained in the
|
<para>In versions prior to 3.0, most of Spring Security's code was contained in the
|
||||||
<filename>spring-security-core</filename> jar<footnote>
|
<filename>spring-security-core</filename> jar<footnote>
|
||||||
<para>There was also an additional <filename>spring-security-core-tiger</filename>
|
<para>There was also an additional <filename>spring-security-core-tiger</filename>
|
||||||
jar which contained the Java 5 specific code. In Spring Security 3.0 Java 5 is
|
jar which contained the Java 5 specific code. In Spring Security 3.0, Java 5 is
|
||||||
the minimum supported platform, so this code is now part of the core.</para>
|
the minimum supported platform, so this code is now part of the core.</para>
|
||||||
</footnote>. Over the years, as more features have been added, it has become more
|
</footnote>. Over the years, as more features have been added, it has become more
|
||||||
difficult to track the dependencies both within the codebase itself and also on third
|
difficult to track the dependencies both within the codebase itself and also on third
|
||||||
@ -79,8 +79,8 @@
|
|||||||
table.<table xml:id="jar-files-3.0">
|
table.<table xml:id="jar-files-3.0">
|
||||||
<title>Spring Security Jars</title>
|
<title>Spring Security Jars</title>
|
||||||
<tgroup cols="3" align="left">
|
<tgroup cols="3" align="left">
|
||||||
<colspec colnum="1" colname="c1" colwidth="0.6*"/>
|
<colspec colnum="1" colname="c1" colwidth="0.59*"/>
|
||||||
<colspec colnum="2" colname="c2" colwidth="0.9*"/>
|
<colspec colnum="2" colname="c2" colwidth="0.92*"/>
|
||||||
<colspec colnum="3" colname="c3" colwidth="0.88*"/>
|
<colspec colnum="3" colname="c3" colwidth="0.88*"/>
|
||||||
<colspec colnum="4" colname="c4" colwidth="1.61*"/>
|
<colspec colnum="4" colname="c4" colwidth="1.61*"/>
|
||||||
<thead>
|
<thead>
|
||||||
@ -183,7 +183,7 @@
|
|||||||
<interfacename>AuthenticationManager</interfacename> and related classes (such
|
<interfacename>AuthenticationManager</interfacename> and related classes (such
|
||||||
as authentication exception classes), the simple DAO-based authentication provider
|
as authentication exception classes), the simple DAO-based authentication provider
|
||||||
and password-encoders. <figure xml:id="structure-3.0">
|
and password-encoders. <figure xml:id="structure-3.0">
|
||||||
<title>Spring Security 2.0.4 Package Structure</title>
|
<title>Spring Security 3.0.0.M1 Package Structure</title>
|
||||||
<mediaobject>
|
<mediaobject>
|
||||||
<imageobject>
|
<imageobject>
|
||||||
<imagedata fileref="images/spring-security-3.0.0.M1.png" align="center"
|
<imagedata fileref="images/spring-security-3.0.0.M1.png" align="center"
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
<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
|
<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
|
can use Ant paths or regular expressions, you can consider parts
|
||||||
of the URI other than simply the requested page (eg you can
|
of the URI other than simply the requested page (e.g. you can
|
||||||
consider HTTP GET parameters), and you can implement your own
|
consider HTTP GET parameters) and you can implement your own
|
||||||
runtime source of configuration data. This means your web
|
runtime source of configuration data. This means your web
|
||||||
request security can be dynamically changed during the actual
|
request security can be dynamically changed during the actual
|
||||||
execution of your webapp.</para>
|
execution of your webapp.</para>
|
||||||
@ -43,7 +43,8 @@
|
|||||||
developers either ignore these requirements, or implement
|
developers either ignore these requirements, or implement
|
||||||
security logic within their MVC controller code (or even worse,
|
security logic within their MVC controller code (or even worse,
|
||||||
inside the views). There are serious disadvantages with this
|
inside the views). There are serious disadvantages with this
|
||||||
approach: <orderedlist>
|
approach:
|
||||||
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><emphasis>Separation of concerns:</emphasis>
|
<para><emphasis>Separation of concerns:</emphasis>
|
||||||
Authorization is a crosscutting concern and should
|
Authorization is a crosscutting concern and should
|
||||||
@ -112,10 +113,39 @@
|
|||||||
<para> Spring Security 2.0.x requires a minimum JDK version of 1.4 and is built
|
<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
|
against Spring 2.0.x. It should also be compatible with applications using
|
||||||
Spring 2.5.x. </para>
|
Spring 2.5.x. </para>
|
||||||
<para> Spring Security 3.0 will require JDK 1.5 as a minimum and will also
|
<para> Spring Security 3.0 requires JDK 1.5 as a minimum and will also
|
||||||
require Spring 3.0. </para>
|
require Spring 3.0. </para>
|
||||||
</answer>
|
</answer>
|
||||||
</qandaentry></qandadiv>
|
</qandaentry>
|
||||||
|
<qandaentry>
|
||||||
|
<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 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 reasonably straightforward. Moving to using a
|
||||||
|
backed JDBC database is also easy enough. But if you try and jump
|
||||||
|
straight to a complicated deployment 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>
|
||||||
|
</qandaentry>
|
||||||
|
|
||||||
|
</qandadiv>
|
||||||
<qandadiv>
|
<qandadiv>
|
||||||
<title>Common Problems</title>
|
<title>Common Problems</title>
|
||||||
<qandaentry xml:id="faq-login-loop">
|
<qandaentry xml:id="faq-login-loop">
|
||||||
@ -181,7 +211,8 @@
|
|||||||
<answer>
|
<answer>
|
||||||
<para> This happens because Tomcat sessions created under HTTPS cannot
|
<para> This happens because Tomcat sessions created under HTTPS cannot
|
||||||
subsequently be used under HTTP and any session state is lost (including the
|
subsequently be used under HTTP and any session state is lost (including the
|
||||||
security context information). Starting in HTTP first should work. </para>
|
security context information). Starting a session in HTTP first should work as the
|
||||||
|
session cookie won't be marked as secure. </para>
|
||||||
</answer>
|
</answer>
|
||||||
</qandaentry>
|
</qandaentry>
|
||||||
<qandaentry xml:id="faq-no-security-on-forward">
|
<qandaentry xml:id="faq-no-security-on-forward">
|
||||||
@ -208,17 +239,40 @@
|
|||||||
essential to make sure that the Spring Security session registry is notified
|
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
|
when a session is destroyed. Without it, the session information will not be
|
||||||
removed from the registry.</para>
|
removed from the registry.</para>
|
||||||
<programlisting>
|
<programlisting><![CDATA[
|
||||||
<listener>
|
<listener>
|
||||||
<listener-classorg.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
||||||
</listener>
|
</listener> ]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</answer>
|
</answer>
|
||||||
</qandaentry>
|
</qandaentry>
|
||||||
</qandadiv>
|
</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 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>
|
||||||
|
</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 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>
|
||||||
|
</qandaentry>
|
||||||
|
</qandadiv>
|
||||||
<qandadiv>
|
<qandadiv>
|
||||||
<title>Common <quote>Howto</quote> Requests</title>
|
<title>Common <quote>Howto</quote> Requests</title>
|
||||||
<qandaentry xml:id="extra-login-fields">
|
<qandaentry xml:id="faq-extra-login-fields">
|
||||||
<question>
|
<question>
|
||||||
<para>I need to login in with more information than just the username. How do I
|
<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>
|
add support for extra login fields (e.g. a company name)?</para>
|
||||||
@ -244,25 +298,149 @@
|
|||||||
and loads the appropriate user data for authentication. </para>
|
and loads the appropriate user data for authentication. </para>
|
||||||
</answer>
|
</answer>
|
||||||
</qandaentry>
|
</qandaentry>
|
||||||
<qandaentry xml:id="what-dependencies">
|
<qandaentry>
|
||||||
|
<question xml:id="faq-dynamic-url-metadata">
|
||||||
|
<para>How do I define the secured URLs withing 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 <interfacename>FilterInvocationSecurityMetadataSource</interfacename>.
|
||||||
|
The <quote>secured object</quote> type it operates on is a <classname>FilterInvocation</classname>.
|
||||||
|
The default implementation which is used (both in the namespace <literal><http></literal>
|
||||||
|
and 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
|
||||||
|
<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>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[
|
||||||
|
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
|
||||||
|
|
||||||
|
public List<ConfigAttribute> getAttributes(Object object) {
|
||||||
|
FilterInvocation fi = (FilterInvocation) object;
|
||||||
|
String url = fi.getRequestUrl();
|
||||||
|
String httpMethod = fi.getRequest().getMethod();
|
||||||
|
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
|
||||||
|
|
||||||
|
// Lookup your database (or other source) using this information and populate the
|
||||||
|
// list of attributes
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<ConfigAttribute> getAllConfigAttributes() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supports(Class<?> clazz) {
|
||||||
|
return FilterInvocation.class.isAssignableFrom(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></programlisting>
|
||||||
|
For more information, look at the code for <classname>DefaultFilterInvocationSecurityMetadataSource</classname>.
|
||||||
|
</para>
|
||||||
|
</answer>
|
||||||
|
</qandaentry>
|
||||||
|
<qandaentry xml:id="faq-what-dependencies">
|
||||||
<question>
|
<question>
|
||||||
<para>How do I know what dependencies to add to my application to work with
|
<para>How do I know which dependencies to add to my application to work with
|
||||||
Spring Security?</para>
|
Spring Security?</para>
|
||||||
</question>
|
</question>
|
||||||
<answer>
|
<answer>
|
||||||
<para> There is no definite answer here, (it will depend on what features you
|
<para>It will depend on what features you
|
||||||
are using), but a good starting point is to copy those from one of the
|
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
|
pre-built sample applications WEB-INF/lib directories. For a basic
|
||||||
application, you can start with the tutorial sample. If you want to use
|
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
|
LDAP, with an embedded test server, then use the LDAP sample as a starting
|
||||||
point. </para>
|
point. </para>
|
||||||
<para> If you are building your project with maven, then adding the appropriate
|
<para> If you are building your project with maven, then adding the appropriate
|
||||||
Spring Security modules to your pom.xml will automatically pull in the core
|
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
|
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
|
Spring Security POM files will have to be added to your own pom.xml file if
|
||||||
you need them. </para>
|
you need them. </para>
|
||||||
</answer>
|
</answer>
|
||||||
</qandaentry>
|
</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
|
||||||
|
<interfacename>LdapAuthenticator</interfacename> and <interfacename>LdapAuthoritiesPopulator</interfacename>
|
||||||
|
respectively. The <classname>DefaultLdapAuthoitiesPopulator</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[
|
||||||
|
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||||
|
@Autowired
|
||||||
|
JdbcTemplate template;
|
||||||
|
|
||||||
|
List<GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
|
||||||
|
List<GrantedAuthority> = template.query("select role from roles where username = ?", new String[] {username}, new RowMapper<GrantedAuthority>() {
|
||||||
|
/**
|
||||||
|
* We're assuming here that you're using the standard convention of using the role
|
||||||
|
* prefix "ROLE_" to mark attributes which are supported by Spring Security's RoleVoter.
|
||||||
|
*/
|
||||||
|
public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
return new GrantedAuthorityImpl("ROLE_" + rs.getString(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></programlisting>
|
||||||
|
You would then add a bean of this type to your application context and inject it into the <code>LdapAuthenticationProvider</code>.
|
||||||
|
This is covered in the 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>
|
||||||
|
</qandaentry>
|
||||||
</qandadiv>
|
</qandadiv>
|
||||||
</qandaset>
|
</qandaset>
|
||||||
</article>
|
</article>
|
||||||
|
@ -57,3 +57,7 @@ div.table td {
|
|||||||
padding-left: 7px;
|
padding-left: 7px;
|
||||||
padding-right: 7px;
|
padding-right: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.question {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user