updates to faq and codebase article
This commit is contained in:
parent
31e2319f8a
commit
b50d37fa66
|
@ -9,7 +9,7 @@
|
|||
<personname>Luke Taylor</personname>
|
||||
<affiliation><orgname>SpringSource</orgname></affiliation></author>
|
||||
<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>
|
||||
</abstract>
|
||||
</info>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<para>In versions prior to 3.0, most of Spring Security's code was contained in the
|
||||
<filename>spring-security-core</filename> jar<footnote>
|
||||
<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>
|
||||
</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
|
||||
|
@ -79,8 +79,8 @@
|
|||
table.<table xml:id="jar-files-3.0">
|
||||
<title>Spring Security Jars</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<colspec colnum="1" colname="c1" colwidth="0.6*"/>
|
||||
<colspec colnum="2" colname="c2" colwidth="0.9*"/>
|
||||
<colspec colnum="1" colname="c1" colwidth="0.59*"/>
|
||||
<colspec colnum="2" colname="c2" colwidth="0.92*"/>
|
||||
<colspec colnum="3" colname="c3" colwidth="0.88*"/>
|
||||
<colspec colnum="4" colname="c4" colwidth="1.61*"/>
|
||||
<thead>
|
||||
|
@ -183,7 +183,7 @@
|
|||
<interfacename>AuthenticationManager</interfacename> and related classes (such
|
||||
as authentication exception classes), the simple DAO-based authentication provider
|
||||
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>
|
||||
<imageobject>
|
||||
<imagedata fileref="images/spring-security-3.0.0.M1.png" align="center"
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
<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 (eg you can
|
||||
consider HTTP GET parameters), and you can implement your own
|
||||
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>
|
||||
|
@ -43,7 +43,8 @@
|
|||
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>
|
||||
approach:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para><emphasis>Separation of concerns:</emphasis>
|
||||
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
|
||||
against Spring 2.0.x. It should also be compatible with applications using
|
||||
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>
|
||||
</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>
|
||||
<title>Common Problems</title>
|
||||
<qandaentry xml:id="faq-login-loop">
|
||||
|
@ -181,7 +211,8 @@
|
|||
<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 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>
|
||||
</qandaentry>
|
||||
<qandaentry xml:id="faq-no-security-on-forward">
|
||||
|
@ -208,17 +239,40 @@
|
|||
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>
|
||||
<listener>
|
||||
<listener-classorg.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
||||
</listener>
|
||||
<programlisting><![CDATA[
|
||||
<listener>
|
||||
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
||||
</listener> ]]>
|
||||
</programlisting>
|
||||
</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 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>
|
||||
<title>Common <quote>Howto</quote> Requests</title>
|
||||
<qandaentry xml:id="extra-login-fields">
|
||||
<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>
|
||||
|
@ -244,25 +298,149 @@
|
|||
and loads the appropriate user data for authentication. </para>
|
||||
</answer>
|
||||
</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>
|
||||
<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>
|
||||
</question>
|
||||
<answer>
|
||||
<para> There is no definite answer here, (it will depend on what features you
|
||||
are using), but a good starting point is to copy those from one of the
|
||||
<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 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
|
||||
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
|
||||
<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>
|
||||
</qandaset>
|
||||
</article>
|
||||
|
|
|
@ -57,3 +57,7 @@ div.table td {
|
|||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.question {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue