manual reorganization

This commit is contained in:
Luke Taylor 2009-06-07 21:00:50 +00:00
parent 01b8def455
commit 31e2319f8a
40 changed files with 1798 additions and 1074 deletions

View File

@ -24,7 +24,7 @@
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);;
create unique index ix_auth_username on authorities (username,authority);
</programlisting></para>
<section>
<title>Group Authorities</title>
@ -121,8 +121,10 @@ create table acl_entry (
id bigint generated by default as identity(start with 100) not null primary key,
acl_object_identity bigint not null,ace_order int not null,sid bigint not null,
mask integer not null,granting boolean not null,audit_success boolean not null,
audit_failure boolean not null,constraint unique_uk_4 unique(acl_object_identity,ace_order),
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
audit_failure boolean not null,
constraint unique_uk_4 unique(acl_object_identity,ace_order),
constraint foreign_fk_4 foreign key(acl_object_identity)
references acl_object_identity(id),
constraint foreign_fk_5 foreign key(sid) references acl_sid(id) );
</programlisting></para>
@ -148,9 +150,9 @@ create table acl_object_identity(
owner_sid bigint,
entries_inheriting boolean not null,
constraint unique_uk_3 unique(object_id_class,object_id_identity),
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id));
constraint foreign_fk_1 foreign key(parent_object) references acl_object_identity(id),
constraint foreign_fk_2 foreign key(object_id_class) references acl_class(id),
constraint foreign_fk_3 foreign key(owner_sid) references acl_sid(id));
create table acl_entry(
id bigserial primary key,
@ -162,7 +164,8 @@ create table acl_entry(
audit_success boolean not null,
audit_failure boolean not null,
constraint unique_uk_4 unique(acl_object_identity,ace_order),
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
constraint foreign_fk_4 foreign key(acl_object_identity)
references acl_object_identity(id),
constraint foreign_fk_5 foreign key(sid) references acl_sid(id));
</programlisting>
</para>

View File

@ -70,7 +70,8 @@
<interfacename>AccessDecisionManager</interfacename> interface contains three
methods:
<programlisting>
void decide(Authentication authentication, Object secureObject, List&lt;ConfigAttribute&gt; config) throws AccessDeniedException;
void decide(Authentication authentication, Object secureObject,
List&lt;ConfigAttribute&gt; config) throws AccessDeniedException;
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
</programlisting>
@ -106,11 +107,13 @@
<figure xml:id="authz-access-voting">
<title>Voting Decision Manager</title>
<mediaobject>
<!--
<imageobject role="fo">
<imagedata align="center" fileref="resources/images/AccessDecisionVoting.gif" format="GIF"/>
</imageobject>
<imageobject role="html">
<imagedata align="center" fileref="images/AccessDecisionVoting.gif" format="GIF"/>
-->
<imageobject>
<imagedata align="center" scalefit="1" fileref="images/AccessDecisionVoting.gif" format="GIF"/>
</imageobject>
</mediaobject>
</figure>
@ -227,11 +230,8 @@ boolean supports(Class clazz);
<figure xml:id="authz-after-invocation">
<title>After Invocation Implementation</title>
<mediaobject>
<imageobject role="fo">
<imagedata align="center" fileref="resources/images/AfterInvocation.gif" format="GIF"/>
</imageobject>
<imageobject role="html">
<imagedata align="center" fileref="images/AfterInvocation.gif" format="GIF"/>
<imageobject>
<imagedata align="center" scalefit="1" fileref="images/AfterInvocation.gif" format="GIF"/>
</imageobject>
</mediaobject>
@ -319,7 +319,7 @@ boolean supports(Class clazz);
follows:
<programlisting><![CDATA[
<bean id="afterAclCollectionRead"
class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
<constructor-arg ref="aclService"/>
<constructor-arg>
<list>

View File

@ -27,17 +27,17 @@
<literal>BasicProcessingFilter</literal> and its required
collaborator:</para>
<para><programlisting language="xml">
&lt;bean id="basicProcessingFilter" class="org.springframework.security.web.authentication.www.BasicProcessingFilter"&gt;
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint"&gt;
&lt;property name="realmName"&gt;&lt;value&gt;Name Of Your Realm&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;
<para><programlisting language="xml"><![CDATA[
<bean id="basicProcessingFilter"
class="org.springframework.security.web.authentication.www.BasicProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint">
<property name="realmName" value="Name Of Your Realm"/>
</bean>]]>
</programlisting></para>
<para>The configured <interfacename>AuthenticationManager</interfacename>

View File

@ -274,8 +274,10 @@
to your application context. This represents your service:</para>
<para><programlisting><![CDATA[
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
<bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>]]>
</programlisting></para>
@ -294,7 +296,8 @@
<para><programlisting><![CDATA[
<security:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" class="org.springframework.security.cas.web.CasProcessingFilter">
<bean id="casProcessingFilter"
class="org.springframework.security.cas.web.CasProcessingFilter">
<security:custom-filter after="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/casfailed.jsp"/>
@ -335,7 +338,8 @@
<para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its
collaborators:
<programlisting><![CDATA[
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<security:custom-authentication-provider />
<property name="userDetailsService" ref="userService"/>
<property name="serviceProperties" ref="serviceProperties" />

View File

@ -38,23 +38,28 @@
<info><title>Configuration</title></info>
<para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security namespace</link>
by means of the <literal>requires-channel</literal> attribute on the <literal>&lt;intercept-url&gt;</literal>
element and this is the simplest (and recommended approach)</para>
element and this is the simplest (and recommended approach).</para>
<para>To confiure channel security explicitly, you would define the following the filter in your application
context:
<programlisting><![CDATA[
<bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<bean id="channelProcessingFilter"
class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<property name="channelDecisionManager" ref="channelDecisionManager"/>
<property name="filterInvocationDefinitionSource">
<property name="filterInvocationSecurityMetadataSource">
<security:filter-invocation-definition-source path-type="regex">
<security:intercept-url pattern="\A/secure/.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/acegilogin.jsp.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/j_spring_security_check.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/secure/.*\Z"
access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/acegilogin.jsp.*\Z"
access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/j_spring_security_check.*\Z"
access="REQUIRES_SECURE_CHANNEL"/>
<security:intercept-url pattern="\A/.*\Z" access="ANY_CHANNEL"/>
</security:filter-invocation-definition-source>
</property>
</bean>
<bean id="channelDecisionManager" class="org.springframework.security.access.channel.ChannelDecisionManagerImpl">
<bean id="channelDecisionManager"
class="org.springframework.security.access.channel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
@ -63,8 +68,10 @@
</property>
</bean>
<bean id="secureChannelProcessor" class="org.springframework.security.access.channel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="org.springframework.security.access.channel.InsecureChannelProcessor"/>]]>
<bean id="secureChannelProcessor"
class="org.springframework.security.access.channel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor"
class="org.springframework.security.access.channel.InsecureChannelProcessor"/>]]>
</programlisting>
Like <classname>FilterSecurityInterceptor</classname>, Apache Ant
style paths are also supported by the

View File

@ -48,7 +48,17 @@
<bean id="filterChainProxy"
class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**" filters="httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter"/>
<security:filter-chain pattern="/**" filters="
securityContextPersistenceFilter,
logoutFilter,
authenticationProcessingFilter,
basicProcessingFilter,
securityContextHolderAwareRequestFilter,
rememberMeProcessingFilter,
anonymousProcessingFilter,
exceptionTranslationFilter,
filterInvocationInterceptor,
switchUserProcessingFilter"/>
</security:filter-chain-map>
</bean>]]></programlisting></para>
@ -123,16 +133,17 @@
shipped with Spring Security, so let's look at how it's configured for
the example we're using in this chapter:</para>
<para><programlisting>&lt;bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager"&gt;
&lt;property name="providers"&gt;
&lt;list&gt;
&lt;ref local="daoAuthenticationProvider"/&gt;
&lt;ref local="anonymousAuthenticationProvider"/&gt;
&lt;ref local="rememberMeAuthenticationProvider"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para><programlisting><![CDATA[
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>]]></programlisting></para>
<para>It's probably worth mentioning at this point that your
authentication mechanisms (which are usually filters) are also
@ -187,8 +198,8 @@
<para><programlisting><![CDATA[
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/>
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
@ -196,10 +207,10 @@
</property>
</bean>
<bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
<property name="forceHttps">< value="false"/>
<property name="forceHttps" value="false"/>
</bean>]]></programlisting></para>
<para>Notice that the <classname>ExceptionTranslationFilter</classname>
@ -288,17 +299,16 @@
use the <literal>user-service</literal> element from the security
<link xlink:href="#namespace-minimal" >namespace</link>:
<programlisting><![CDATA[
<user-service id="userDetailsService">
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
<user-service id="userDetailsService">
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
]]>
</programlisting>
This also suppots the use of an external properties file:
<programlisting><![CDATA[
<user-service id="userDetailsService" properties="users.properties"/>
]]>
</programlisting>
<user-service id="userDetailsService" properties="users.properties"/>
]]></programlisting>
The properties file should contain entries in the form
<programlisting>
username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]
@ -363,7 +373,8 @@
authority VARCHAR(50) NOT NULL
);
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users(username);
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users \
foreign key (username) REFERENCES users(username);
</programlisting>
</para>
@ -394,10 +405,12 @@
<para>To use concurrent session support, you'll need to add the
following to <literal>web.xml</literal>:
<programlisting>
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.security.web.session.HttpSessionEventPublisher&lt;/listener-class&gt;
&lt;/listener&gt;
<programlisting><![CDATA[
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener> ]]>
</programlisting>
</para>
@ -424,7 +437,7 @@
<para>
<programlisting><![CDATA[
<bean id="authenticationManager"
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<!-- your providers go here -->
@ -432,11 +445,12 @@
<property name="sessionController" ref="concurrentSessionController"/>
</bean>
<bean id="concurrentSessionController"
class="org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl">
<bean id="concurrentSessionController" class=
"org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl">
<property name="maximumSessions" value="1"/>
<property name="sessionRegistry">
<bean class="org.springframework.security.authentication.concurrent.SessionRegistryImpl"/>
<bean
class="org.springframework.security.authentication.concurrent.SessionRegistryImpl"/>
<property>
</bean>
]]></programlisting></para>

View File

@ -85,7 +85,8 @@
<property name="cacheName" value="userCache"/>
</bean>
<bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
<bean id="userCache"
class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
<property name="cache" ref="userCacheBackend"/>
</bean>]]>
</programlisting></para>

View File

@ -91,15 +91,15 @@
<para><programlisting>
<![CDATA[
<bean id="digestProcessingFilter"
class="org.springframework.security.web.authentication.www.DigestProcessingFilter">
<bean id="digestProcessingFilter" class=
"org.springframework.security.web.authentication.www.DigestProcessingFilter">
<property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="authenticationEntryPoint" ref="digestProcessingFilterEntryPoint"/>
<property name="userCache" ref="userCache"/>
</bean>
<bean id="digestProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.www.DigestProcessingFilterEntryPoint">
<bean id="digestProcessingFilterEntryPoint" class=
"org.springframework.security.web.authentication.www.DigestProcessingFilterEntryPoint">
<property name="realmName" value="Contacts Realm via Digest Authentication"/>
<property name="key" value="acegi"/>
<property name="nonceValiditySeconds" value="10"/>

View File

@ -1,15 +1,17 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="form"><info><title>Form Authentication Mechanism</title></info>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="form">
<info><title>Form Authentication Mechanism</title></info>
<section xml:id="form-overview">
<info><title>Overview</title></info>
<para>HTTP Form Authentication involves using the
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> to process a login
form. This is the most common way for an application to authenticate end
users. Form-based authentication is entirely compatible with the DAO
users. Form-based authentication is entirely compatible with the DAO, LDAP
and JAAS authentication providers.</para>
<para>This is also the mechanism used by the &lt;form-login&gt; element from the namespace
and it's recommended that you use that unless you have specific customization requirements.
</para>
</section>
<section xml:id="form-config">
@ -21,38 +23,47 @@
<literal>/j_spring_security_check</literal>). You should add an
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> to your application context:
<programlisting><![CDATA[
<bean id="authenticationProcessingFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter">
<bean id="authenticationProcessingFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/login.jsp?login_error=1"/>
<property name="defaultTargetUrl" value="/"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
</bean> ]]>
</programlisting></para>
<para>The configured <interfacename>AuthenticationManager</interfacename>
processes each authentication request. If authentication fails, the
browser will be redirected to the
<literal>authenticationFailureUrl</literal>. The
<literal>AuthenticationException</literal> will be placed into the
<literal>HttpSession</literal> attribute indicated by
<literal>AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY</literal>,
enabling a reason to be provided to the user on the error page.</para>
<para>
The configured <interfacename>AuthenticationManager</interfacename>
processes each authentication request. The destination following a successful authentication
or an authentication failure is controlled by the <interfacename>AuthenticationSuccessHandler</interfacename>
and <interfacename>AuthenticationFailureHandler</interfacename> interfaces, respectively.
The filter has properties which allow you to set these
<footnote><para>In versions prior to 3.0, the application flow at this point had evolved to a stage
was controlled by a mix of properties on this class and strategy plugins. The
decision was made for 3.0 to refactor the code to make these two strategies entirely responsible.
</para></footnote>.
Some standard implementations are supplied for these such as
<classname>SimpleUrlAuthenticationSuccessHandler</classname>,
<classname>SavedRequestAwareAuthenticationSuccessHandler</classname>,
<classname>SimpleUrlAuthenticationFailureHandler</classname> and
<classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at the Javadoc
for these classes to see how they work.
</para>
<para>If authentication is successful, the resulting
<interfacename>Authentication</interfacename> object will be placed into the
<classname>SecurityContextHolder</classname>.</para>
<classname>SecurityContextHolder</classname>.
The configured AuthenticationSuccessHandler will then be called to either redirect or forward
the user to the approprate destination. By default a <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>
is used, which means that the user will be redirected to the original destination they requested before they were asked to
login.
<note>
<para>
The <classname>ExceptionTranslationFilter</classname> caches the original request a user makes.
When the user authenticates, the request handler makes use of this cached request to obtain the original
URL and redirect to it. The original request is then rebuilt and used as an alternative.
</para>
</note>
If authentication fails, the configured <interfacename>AuthenticationFailureHandler</interfacename> will be invoked.
</para>
<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>AbstractAuthenticationProcessingFilter.SPRING_SECURITY_TARGET_URL_KEY</literal>.
This attribute is automatically set by the
<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
indicate the target URL, the browser will be redirected to the
<literal>defaultTargetUrl</literal> property.</para>
</section>
</chapter>

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,308 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xml:id="introduction"
xmlns="http://docbook.org/ns/docbook"
<chapter version="5.0" xml:id="introduction" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Introduction</title>
<sect1 xml:id="what-is-acegi-security">
<title>What is Spring Security?</title>
<para>Spring Security provides comprehensive security services for
J2EE-based enterprise software applications. There is a particular
emphasis on supporting projects built using The Spring Framework,
which is the leading J2EE solution for enterprise software
development. If you're not using Spring for developing enterprise
applications, we warmly encourage you to take a closer look at it.
Some familiarity with Spring - and in particular dependency injection
principles - will help you get up to speed with Spring Security more
easily.</para>
<para>People use Spring Security for many reasons, but most are drawn
to the project after finding the security features of J2EE's Servlet
Specification or EJB Specification lack the depth required for typical
enterprise application scenarios. Whilst mentioning these standards,
it's important to recognise that they are not portable at a WAR or EAR
level. Therefore, if you switch server environments, it is typically a
lot of work to reconfigure your application's security in the new
target environment. Using Spring Security overcomes these problems,
and also brings you dozens of other useful, entirely customisable
security features.</para>
<para>As you probably know, security comprises two major operations.
The first is known as "authentication", which is the process of
establishing a principal is who they claim to be. A "principal"
generally means a user, device or some other system which can perform
an action in your application. "Authorization" refers to the process
of deciding whether a principal is allowed to perform an action in
your application. To arrive at the point where an authorization
decision is needed, the identity of the principal has already been
established by the authentication process. These concepts are common,
and not at all specific to Spring Security.</para>
<para>At an authentication level, Spring Security supports a wide
range of authentication models. Most of these authentication models
are either provided by third parties, or are developed by relevant
standards bodies such as the Internet Engineering Task Force. In
addition, Spring Security provides its own set of authentication
features. Specifically, Spring Security currently supports
authentication integration with all of these technologies:</para>
<itemizedlist spacing="compact">
<listitem>
<para>HTTP BASIC authentication headers (an IEFT RFC-based
standard)</para>
</listitem>
<listitem>
<para>HTTP Digest authentication headers (an IEFT RFC-based
standard)</para>
</listitem>
<listitem>
<para>HTTP X.509 client certificate exchange (an IEFT RFC-based
standard)</para>
</listitem>
<listitem>
<para>LDAP (a very common approach to cross-platform
authentication needs, especially in large environments)</para>
</listitem>
<listitem>
<para>Form-based authentication (for simple user interface
needs)</para>
</listitem>
<listitem>
<para>OpenID authentication</para>
</listitem>
<listitem>
<para>Computer Associates Siteminder</para>
</listitem>
<listitem>
<para>JA-SIG Central Authentication Service (otherwise known as
CAS, which is a popular open source single sign on system)</para>
</listitem>
<listitem>
<para>Transparent authentication context propagation for Remote
Method Invocation (RMI) and HttpInvoker (a Spring remoting
protocol)</para>
</listitem>
<listitem>
<para>Automatic "remember-me" authentication (so you can tick a
box to avoid re-authentication for a predetermined period of
time)</para>
</listitem>
<listitem>
<para>Anonymous authentication (allowing every call to
automatically assume a particular security identity)</para>
</listitem>
<listitem>
<para>Run-as authentication (which is useful if one call should
proceed with a different security identity)</para>
</listitem>
<listitem>
<para>Java Authentication and Authorization Service (JAAS)</para>
</listitem>
<listitem>
<para>Container integration with JBoss, Jetty, Resin and Tomcat
(so you can still use Container Manager Authentication if
desired)</para>
</listitem>
<listitem>
<para>Java Open Source Single Sign On (JOSSO) *</para>
</listitem>
<listitem>
<para>OpenNMS Network Management Platform *</para>
</listitem>
<listitem>
<para>AppFuse *</para>
</listitem>
<listitem>
<para>AndroMDA *</para>
</listitem>
<listitem>
<para>Mule ESB *</para>
</listitem>
<listitem>
<para>Direct Web Request (DWR) *</para>
</listitem>
<listitem>
<para>Grails *</para>
</listitem>
<listitem>
<para>Tapestry *</para>
</listitem>
<listitem>
<para>JTrac *</para>
</listitem>
<listitem>
<para>Jasypt *</para>
</listitem>
<listitem>
<para>Roller *</para>
</listitem>
<listitem>
<para>Elastic Plath *</para>
</listitem>
<listitem>
<para>Atlassian Crowd *</para>
</listitem>
<listitem>
<para>Your own authentication systems (see below)</para>
</listitem>
</itemizedlist>
<para>(* Denotes provided by a third party; check our <link
xlink:href="http://acegisecurity.org/powering.html">integration page</link>
for links to the latest details)</para>
<para>Many independent software vendors (ISVs) adopt Spring Security
because of this significant choice of flexible authentication models.
Doing so allows them to quickly integrate their solutions with
whatever their end clients need, without undertaking a lot of
engineering or requiring the client to change their environment. If
none of the above authentication mechanisms suit your needs, Spring
Security is an open platform and it is quite simple to write your own
authentication mechanism. Many corporate users of Spring Security need
to integrate with "legacy" systems that don't follow any particular
security standards, and Spring Security is happy to "play nicely" with
such systems.</para>
<para>Sometimes the mere process of authentication isn't enough.
Sometimes you need to also differentiate security based on the way a
principal is interacting with your application. For example, you might
want to ensure requests only arrive over HTTPS, in order to protect
passwords from eavesdropping or end users from man-in-the-middle
attacks. Or, you might want to ensure that an actual human being is
making the requests and not some robot or other automated process.
This is especially helpful to protect password recovery processes from
brute force attacks, or simply to make it harder for people to
duplicate your application's key content. To help you achieve these
goals, Spring Security fully supports automatic "channel security",
together with JCaptcha integration for human user detection.</para>
<para>Irrespective of how authentication was undertaken, Spring
Security provides a deep set of authorization capabilities. There are
three main areas of interest in respect of authorization, these being
authorizing web requests, authorizing methods can be invoked, and
authorizing access to individual domain object instances. To help you
understand the differences, consider the authorization capabilities
found in the Servlet Specification web pattern security, EJB Container
Managed Security and file system security respectively. Spring
Security provides deep capabilities in all of these important areas,
which we'll explore later in this reference guide.</para>
</sect1>
<sect1 xml:id="history">
<title>History</title>
<para>Spring Security began in late 2003 as "The Acegi Security System
for Spring". A question was posed on the Spring Developers' mailing
list asking whether there had been any consideration given to a
Spring-based security implementation. At the time the Spring community
was relatively small (especially by today's size!), and indeed Spring
itself had only existed as a SourceForge project from early 2003. The
response to the question was that it was a worthwhile area, although a
lack of time currently prevented its exploration.</para>
<para>With that in mind, a simple security implementation was built
and not released. A few weeks later another member of the Spring
community inquired about security, and at the time this code was
offered to them. Several other requests followed, and by January 2004
around twenty people were using the code. These pioneering users were
joined by others who suggested a SourceForge project was in order,
which was duly established in March 2004.</para>
<para>In those early days, the project didn't have any of its own
authentication modules. Container Managed Security was relied upon for
the authentication process, with Acegi Security instead focusing on
authorization. This was suitable at first, but as more and more users
requested additional container support, the fundamental limitation of
container-specific authentication realm interfaces was experienced.
There was also a related issue of adding new JARs to the container's
classpath, which was a common source of end user confusion and
misconfiguration.</para>
<para>Acegi Security-specific authentication services were
subsequently introduced. Around a year later, Acegi Security became an
official Spring Framework subproject. The 1.0.0 final release was
published in May 2006 - after more than two and a half years of active
use in numerous production software projects and many hundreds of
improvements and community contributions.</para>
<para>Acegi Security became an official Spring Portfolio project
towards the end of 2007 and was rebranded as "Spring Security".</para>
<para>Today Spring Security enjoys a strong and active open source
community. There are thousands of messages about Spring Security on
the support forums. There is an active core of developers work
who work on the code itself and an active community which also
regularly share patches and support their peers.</para>
</sect1>
<sect1 xml:id="release-numbering">
<title>Release Numbering</title>
<para>It is useful to understand how Spring Security release numbers
work, as it will help you identify the effort (or lack thereof)
involved in migrating to future releases of the project. Officially,
we use the Apache Portable Runtime Project versioning guidelines,
which can be viewed at
<literal>http://apr.apache.org/versioning.html</literal>. We quote the
introduction contained on that page for your convenience:</para>
<para><quote>Versions are denoted using a standard triplet of
integers: MAJOR.MINOR.PATCH. The basic intent is that MAJOR versions
are incompatible, large-scale upgrades of the API. MINOR versions
retain source and binary compatibility with older minor versions, and
changes in the PATCH level are perfectly compatible, forwards and
backwards.</quote></para>
</sect1>
<sect1 xml:id="get-source">
<title>Getting the Source</title>
<para>
Since Spring Security is an Open Source project, we'd strongly encourage you to
check out the source code using subversion. This will give you full access to all the sample
applications and you can build the most up to date version of the project easily.
Having the source for a project is also a huge help in debugging. Exception stack traces are no
longer obscure black-box issues but you can get straight to the line that's causing the problem
and work out what's happening. The source is the ultimate documentation for a project and often
the simplest place to find out how something actually works.
</para>
<para>
To obtain the source for the project trunk, use the following subversion command:
<programlisting>
svn checkout http://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/trunk/
<title>Introduction</title>
<sect1 xml:id="what-is-acegi-security">
<title>What is Spring Security?</title>
<para>Spring Security provides comprehensive security services for J2EE-based enterprise
software applications. There is a particular emphasis on supporting projects built using
The Spring Framework, which is the leading J2EE solution for enterprise software
development. If you're not using Spring for developing enterprise applications, we
warmly encourage you to take a closer look at it. Some familiarity with Spring - and in
particular dependency injection principles - will help you get up to speed with Spring
Security more easily.</para>
<para>People use Spring Security for many reasons, but most are drawn to the project after
finding the security features of J2EE's Servlet Specification or EJB Specification lack
the depth required for typical enterprise application scenarios. Whilst mentioning these
standards, it's important to recognise that they are not portable at a WAR or EAR level.
Therefore, if you switch server environments, it is typically a lot of work to
reconfigure your application's security in the new target environment. Using Spring
Security overcomes these problems, and also brings you dozens of other useful, entirely
customisable security features.</para>
<para>As you probably know, security comprises two major operations. The first is known as
"authentication", which is the process of establishing a principal is who they claim to
be. A "principal" generally means a user, device or some other system which can perform
an action in your application. "Authorization" refers to the process of deciding whether
a principal is allowed to perform an action in your application. To arrive at the point
where an authorization decision is needed, the identity of the principal has already
been established by the authentication process. These concepts are common, and not at
all specific to Spring Security.</para>
<para>At an authentication level, Spring Security supports a wide range of authentication
models. Most of these authentication models are either provided by third parties, or are
developed by relevant standards bodies such as the Internet Engineering Task Force. In
addition, Spring Security provides its own set of authentication features. Specifically,
Spring Security currently supports authentication integration with all of these
technologies:</para>
<itemizedlist spacing="compact">
<listitem>
<para>HTTP BASIC authentication headers (an IEFT RFC-based standard)</para>
</listitem>
<listitem>
<para>HTTP Digest authentication headers (an IEFT RFC-based standard)</para>
</listitem>
<listitem>
<para>HTTP X.509 client certificate exchange (an IEFT RFC-based standard)</para>
</listitem>
<listitem>
<para>LDAP (a very common approach to cross-platform authentication needs,
especially in large environments)</para>
</listitem>
<listitem>
<para>Form-based authentication (for simple user interface needs)</para>
</listitem>
<listitem>
<para>OpenID authentication</para>
</listitem>
<listitem>
<para>Computer Associates Siteminder</para>
</listitem>
<listitem>
<para>JA-SIG Central Authentication Service (otherwise known as CAS, which is a
popular open source single sign on system)</para>
</listitem>
<listitem>
<para>Transparent authentication context propagation for Remote Method Invocation
(RMI) and HttpInvoker (a Spring remoting protocol)</para>
</listitem>
<listitem>
<para>Automatic "remember-me" authentication (so you can tick a box to avoid
re-authentication for a predetermined period of time)</para>
</listitem>
<listitem>
<para>Anonymous authentication (allowing every call to automatically assume a
particular security identity)</para>
</listitem>
<listitem>
<para>Run-as authentication (which is useful if one call should proceed with a
different security identity)</para>
</listitem>
<listitem>
<para>Java Authentication and Authorization Service (JAAS)</para>
</listitem>
<listitem>
<para>Container integration with JBoss, Jetty, Resin and Tomcat (so you can still
use Container Manager Authentication if desired)</para>
</listitem>
<listitem>
<para>Java Open Source Single Sign On (JOSSO) *</para>
</listitem>
<listitem>
<para>OpenNMS Network Management Platform *</para>
</listitem>
<listitem>
<para>AppFuse *</para>
</listitem>
<listitem>
<para>AndroMDA *</para>
</listitem>
<listitem>
<para>Mule ESB *</para>
</listitem>
<listitem>
<para>Direct Web Request (DWR) *</para>
</listitem>
<listitem>
<para>Grails *</para>
</listitem>
<listitem>
<para>Tapestry *</para>
</listitem>
<listitem>
<para>JTrac *</para>
</listitem>
<listitem>
<para>Jasypt *</para>
</listitem>
<listitem>
<para>Roller *</para>
</listitem>
<listitem>
<para>Elastic Path *</para>
</listitem>
<listitem>
<para>Atlassian Crowd *</para>
</listitem>
<listitem>
<para>Your own authentication systems (see below)</para>
</listitem>
</itemizedlist>
<para>(* Denotes provided by a third party; check our <link
xlink:href="http://acegisecurity.org/powering.html">integration page</link> for
links to the latest details)</para>
<para>Many independent software vendors (ISVs) adopt Spring Security because of this
significant choice of flexible authentication models. Doing so allows them to quickly
integrate their solutions with whatever their end clients need, without undertaking a
lot of engineering or requiring the client to change their environment. If none of the
above authentication mechanisms suit your needs, Spring Security is an open platform and
it is quite simple to write your own authentication mechanism. Many corporate users of
Spring Security need to integrate with "legacy" systems that don't follow any particular
security standards, and Spring Security is happy to "play nicely" with such
systems.</para>
<para>Sometimes the mere process of authentication isn't enough. Sometimes you need to also
differentiate security based on the way a principal is interacting with your
application. For example, you might want to ensure requests only arrive over HTTPS, in
order to protect passwords from eavesdropping or end users from man-in-the-middle
attacks. Or, you might want to ensure that an actual human being is making the requests
and not some robot or other automated process. This is especially helpful to protect
password recovery processes from brute force attacks, or simply to make it harder for
people to duplicate your application's key content. To help you achieve these goals,
Spring Security fully supports automatic "channel security", together with JCaptcha
integration for human user detection.</para>
<para>Irrespective of how authentication was undertaken, Spring Security provides a deep set
of authorization capabilities. There are three main areas of interest in respect of
authorization, these being authorizing web requests, authorizing methods can be invoked,
and authorizing access to individual domain object instances. To help you understand the
differences, consider the authorization capabilities found in the Servlet Specification
web pattern security, EJB Container Managed Security and file system security
respectively. Spring Security provides deep capabilities in all of these important
areas, which we'll explore later in this reference guide.</para>
</sect1>
<sect1 xml:id="history">
<title>History</title>
<para>Spring Security began in late 2003 as "The Acegi Security System for Spring". A
question was posed on the Spring Developers' mailing list asking whether there had been
any consideration given to a Spring-based security implementation. At the time the
Spring community was relatively small (especially by today's size!), and indeed Spring
itself had only existed as a SourceForge project from early 2003. The response to the
question was that it was a worthwhile area, although a lack of time currently prevented
its exploration.</para>
<para>With that in mind, a simple security implementation was built and not released. A few
weeks later another member of the Spring community inquired about security, and at the
time this code was offered to them. Several other requests followed, and by January 2004
around twenty people were using the code. These pioneering users were joined by others
who suggested a SourceForge project was in order, which was duly established in March
2004.</para>
<para>In those early days, the project didn't have any of its own authentication modules.
Container Managed Security was relied upon for the authentication process, with Acegi
Security instead focusing on authorization. This was suitable at first, but as more and
more users requested additional container support, the fundamental limitation of
container-specific authentication realm interfaces was experienced. There was also a
related issue of adding new JARs to the container's classpath, which was a common source
of end user confusion and misconfiguration.</para>
<para>Acegi Security-specific authentication services were subsequently introduced. Around a
year later, Acegi Security became an official Spring Framework subproject. The 1.0.0
final release was published in May 2006 - after more than two and a half years of active
use in numerous production software projects and many hundreds of improvements and
community contributions.</para>
<para>Acegi Security became an official Spring Portfolio project towards the end of 2007 and
was rebranded as "Spring Security".</para>
<para>Today Spring Security enjoys a strong and active open source community. There are
thousands of messages about Spring Security on the support forums. There is an active
core of developers work who work on the code itself and an active community which also
regularly share patches and support their peers.</para>
</sect1>
<sect1 xml:id="release-numbering">
<title>Release Numbering</title>
<para>It is useful to understand how Spring Security release numbers work, as it will help
you identify the effort (or lack thereof) involved in migrating to future releases of
the project. Officially, we use the Apache Portable Runtime Project versioning
guidelines, which can be viewed at
<literal>http://apr.apache.org/versioning.html</literal>. We quote the introduction
contained on that page for your convenience:</para>
<para><quote>Versions are denoted using a standard triplet of integers: MAJOR.MINOR.PATCH.
The basic intent is that MAJOR versions are incompatible, large-scale upgrades of
the API. MINOR versions retain source and binary compatibility with older minor
versions, and changes in the PATCH level are perfectly compatible, forwards and
backwards.</quote></para>
</sect1>
<sect1 xml:id="get-source">
<title>Getting the Source</title>
<para> Since Spring Security is an Open Source project, we'd strongly encourage you to check
out the source code using subversion. This will give you full access to all the sample
applications and you can build the most up to date version of the project easily. Having
the source for a project is also a huge help in debugging. Exception stack traces are no
longer obscure black-box issues but you can get straight to the line that's causing the
problem and work out what's happening. The source is the ultimate documentation for a
project and often the simplest place to find out how something actually works. </para>
<para> To obtain the source for the project trunk, use the following subversion command:
<programlisting>
svn checkout https://src.springframework.org/svn/spring-security/trunk/
</programlisting>
You can checkout specific versions from <literal>http://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/tags/</literal>.
</para>
</sect1>
</chapter>
You can checkout specific versions from
<literal>https://src.springframework.org/svn/spring-security/tags/</literal>.
</para>
</sect1>
</chapter>

View File

@ -32,14 +32,16 @@ JAASTest {
above JAAS login configuration file:
<programlisting><![CDATA[
<bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<property name="loginConfig" value="/WEB-INF/login.conf"/>
<property name="loginContextName" value="JAASTest"/>
<property name="callbackHandlers">
<list>
<bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
<bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
</list>
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<property name="loginConfig" value="/WEB-INF/login.conf"/>
<property name="loginContextName" value="JAASTest"/>
<property name="callbackHandlers">
<list>
<bean
class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
<bean
class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
</list>
</property>
<property name="authorityGranters">
<list>

View File

@ -69,8 +69,8 @@
<literal>url</literal>
attribute:
<programlisting><![CDATA[
<ldap-server url="ldap://springframework.org:389/dc=springframework,dc=org" />
]]>
<ldap-server url="ldap://springframework.org:389/dc=springframework,dc=org" />
]]>
</programlisting>
</para>
<section>
@ -85,8 +85,8 @@
<literal>url</literal>
attribute:
<programlisting><![CDATA[
<ldap-server root="dc=springframework,dc=org"/>
]]>
<ldap-server root="dc=springframework,dc=org"/>
]]>
</programlisting>
Here we've specified that the root DIT of the directory should be
<quote>dc=springframework,dc=org</quote>, which is the default. Used this way, the
@ -96,7 +96,7 @@
<literal>ldif</literal>
attribute, which defines an LDIF resource to be loaded:
<programlisting><![CDATA[
<ldap-server ldif="classpath:users.ldif" />
<ldap-server ldif="classpath:users.ldif" />
]]></programlisting>
This makes it a lot easier to get up and running with LDAP, since it can be
inconvenient to work all the time with an external server. It also insulates the
@ -113,7 +113,7 @@
<para>
This is the most common LDAP authentication scenario.
<programlisting><![CDATA[
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people"/>
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people"/>
]]></programlisting>
This simple example would obtain the DN for the user by substituting the user login
name in the supplied pattern and attempting to bind as that user with the login
@ -121,7 +121,8 @@
directory. If instead you wished to configure an LDAP search filter to locate the
user, you could use the following:
<programlisting><![CDATA[
<ldap-authentication-provider user-search-filter="(uid={0})" user-search-base="ou=people"/>
<ldap-authentication-provider user-search-filter="(uid={0})"
user-search-base="ou=people"/>
]]></programlisting>
If used with the server definition above, this would perform a search under the DN
<literal>ou=people,dc=springframework,dc=org</literal>
@ -167,7 +168,8 @@
</itemizedlist>
So if we used the following configuration
<programlisting><![CDATA[
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups" />
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people"
group-search-base="ou=groups" />
]]></programlisting>
and authenticated successfully as user
<quote>ben</quote>, the subsequent loading of authorities would perform a search
@ -195,9 +197,8 @@
using namespace configuration then you can skip this section and the next one.
</para>
<para>
The main LDAP provider class is
<classname>org.springframework.security.ldap.authentication.LdapAuthenticationProvider</classname>.
This bean doesn't actually do much itself but delegates the work to two other beans, an
The main LDAP provider class, <classname>LdapAuthenticationProvider</classname>,
doesn't actually do much itself but delegates the work to two other beans, an
<interfacename>LdapAuthenticator</interfacename>
and an
<interfacename>LdapAuthoritiesPopulator</interfacename>
@ -260,8 +261,8 @@
<info>
<title>BindAuthenticator</title>
</info>
<para>The class
<classname>org.springframework.security.ldap.authentication.BindAuthenticator</classname>
<para>The class <classname>BindAuthenticator</classname> in the package
<filename>org.springframework.security.ldap.authentication</filename>
implements the bind authentication strategy. It simply attempts to bind as the
user.</para>
</section>
@ -269,8 +270,7 @@
<info>
<title>PasswordComparisonAuthenticator</title>
</info>
<para>The class
<classname>org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator</classname>
<para>The class <classname>PasswordComparisonAuthenticator</classname>
implements the password comparison authentication strategy.</para>
</section>
<section xml:id="ldap-ldap-authenticators-active-directory">
@ -350,22 +350,23 @@
</bean>
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userDnPatterns">
<list><value>uid={0},ou=people</value></list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupRoleAttribute" value="ou"/>
</bean>
</constructor-arg>
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userDnPatterns">
<list><value>uid={0},ou=people</value></list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupRoleAttribute" value="ou"/>
</bean>
</constructor-arg>
</bean>]]>
</programlisting>
This would set up the provider to access an LDAP server with URL
@ -410,9 +411,10 @@
to and from LDAP context data:
<programlisting><![CDATA[
public interface UserDetailsContextMapper {
UserDetails mapUserFromContext(DirContextOperations ctx, String username, GrantedAuthority[] authority);
UserDetails mapUserFromContext(DirContextOperations ctx, String username,
GrantedAuthority[] authority);
void mapUserToContext(UserDetails user, DirContextAdapter ctx);
void mapUserToContext(UserDetails user, DirContextAdapter ctx);
}]]>
</programlisting>
Only the first method is relevant for authentication. If you provide an implementation of this interface, you can

View File

@ -34,8 +34,10 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
...
</beans>
]]></programlisting> In many of the examples you will see (and in the sample) applications, we
@ -47,8 +49,10 @@
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
...
</beans:beans>
]]></programlisting> We'll assume this syntax is being used from now on in this chapter. </para>
@ -109,8 +113,7 @@
<section xml:id="ns-web-xml">
<title><literal>web.xml</literal> Configuration</title>
<para> The first thing you need to do is add the following filter declaration to your
<literal>web.xml</literal> file: <programlisting language="xml">
<![CDATA[
<literal>web.xml</literal> file: <programlisting language="xml"><![CDATA[
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
@ -245,7 +248,8 @@
<http>
<intercept-url pattern='/login.htm*' filters='none'/>
<intercept-url pattern='/**' access='ROLE_USER' />
<form-login login-page='/login.htm' default-target-url='/home.htm' always-use-default-target='true' />
<form-login login-page='/login.htm' default-target-url='/home.htm'
always-use-default-target='true' />
</http>
]]>
</programlisting></para>
@ -276,7 +280,8 @@
<literal>user-service-ref</literal> attribute: <programlisting language="xml"><![CDATA[
<authentication-provider user-service-ref='myUserDetailsService'/>
<beans:bean id="myUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:bean id="myUserDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
]]>
@ -292,8 +297,10 @@
<authentication-provider>
<password-encoder hash="sha"/>
<user-service>
<user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f" authorities="ROLE_USER" />
<user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"
authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
]]>
@ -304,9 +311,9 @@
<classname>UserDetails</classname> object which is loaded by your
<classname>UserDetailsService</classname>. For example, to use the
<literal>username</literal> property, you would use <programlisting><![CDATA[
<password-encoder hash="sha">
<salt-source user-property="username"/>
</password-encoder>
<password-encoder hash="sha">
<salt-source user-property="username"/>
</password-encoder>
]]></programlisting> You can use a custom password encoder bean by using the
<literal>ref</literal> attribute of <literal>password-encoder</literal>. This should
contain the name of a bean in the application context which is an instance of Spring
@ -336,8 +343,7 @@
to an HTTPS URL. The available options are "http", "https" or "any". Using the value "any"
means that either HTTP or HTTPS can be used. </para>
<para> If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a
list of port mappings as follows: <programlisting>
<![CDATA[
list of port mappings as follows: <programlisting><![CDATA[
<http>
...
<port-mappings>
@ -354,9 +360,11 @@
additions. First you need to add the following listener to your <filename>web.xml</filename>
file to keep Spring Security updated about session lifecycle events: <programlisting language="xml">
<![CDATA[
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
]]></programlisting> Then add the following line to your application context: <programlisting language="xml"><![CDATA[
<http>
...
@ -384,7 +392,8 @@
]]></programlisting> You should then register yourself with an OpenID provider (such as
myopenid.com), and add the user information to your in-memory
<literal>&lt;user-service&gt;</literal>: <programlisting><![CDATA[
<user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
<user name="http://jimi.hendrix.myopenid.com/" password="notused"
authorities="ROLE_USER" />
]]></programlisting> You should be able to login using the <literal>myopenid.com</literal> site to
authenticate. </para>
</section>
@ -566,9 +575,9 @@
</section>
<section xml:id="ns-method-security">
<title>Method Security</title>
<para> Spring Security 2.0 has improved support substantially for adding security to your
service layer methods. If you are using Java 5 or greater, then support for JSR-250 security
annotations is provided, as well as the framework's native <literal>@Secured</literal>
<para>From version 2.0 onwards Spring Security has improved support substantially for adding security to your
service layer methods. It provides support for JSR-250 security
as well as the framework's native <literal>@Secured</literal>
annotation. You can apply security to a single bean, using the
<literal>intercept-methods</literal> element to decorate the bean declaration, or you can
secure multiple beans across the entire service layer using the AspectJ style pointcuts. </para>
@ -607,7 +616,8 @@
you to apply security to many beans with only a simple declaration. Consider the following
example: <programlisting language="xml"><![CDATA[
<global-method-security>
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="ROLE_USER"/>
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))"
access="ROLE_USER"/>
</global-method-security>
]]>
</programlisting> This will protect all methods on beans declared in the application
@ -691,7 +701,8 @@
you can then use this name elsewhere in your application context. <programlisting language="xml"><![CDATA[
<security:authentication-manager alias="authenticationManager"/>
<bean id="customizedFormLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter">
<bean id="customizedFormLoginFilter"
class="com.somecompany.security.web.CustomFormLoginFilter">
<security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER "/>
<property name="authenticationManager" ref="authenticationManager"/>
...

View File

@ -150,19 +150,19 @@
<para>
A typical configuration using this filter would look like this:
<programlisting><![CDATA[
<bean id="siteminderFilter"
class="org.springframework.security.web.authentication.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
<bean id="siteminderFilter" class=
"org.springframework.security.web.authentication.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
<security:custom-filter position="PRE_AUTH_FILTER" />
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<security:custom-authentication-provider />
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>

View File

@ -29,14 +29,15 @@
In essence a cookie is sent to the browser upon successful interactive authentication, with the
cookie being composed as follows:
<programlisting>
base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
base64(username + ":" + expirationTime + ":" +
md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
username: As identifiable to the <interfacename>UserDetailsService</interfacename>
password: That matches the one in the retrieved UserDetails
expirationTime: The date and time when the remember-me token expires, expressed in milliseconds
key: A private key to prevent modification of the remember-me token
username: As identifiable to the <interfacename>UserDetailsService</interfacename>
password: That matches the one in the retrieved UserDetails
expirationTime: The date and time when the remember-me token expires,
expressed in milliseconds
key: A private key to prevent modification of the remember-me token
</programlisting></para>
<para>As such the remember-me token is valid only for the period
specified, and provided that the username, password and key does not
change. Notably, this has a potential security issue in that a
@ -97,10 +98,11 @@
superclass. The hooks will invoke a concrete
<interfacename>RememberMeServices</interfacename> at the appropriate times. The
interface looks like this:
<programlisting>
<programlisting language="java">
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
void loginFail(HttpServletRequest request, HttpServletResponse response);
void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication);
void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication);
</programlisting>
Please refer to the JavaDocs for a fuller discussion on what the
methods do, although note at this stage that
@ -137,20 +139,21 @@
to have the cookie cleared automatically.
</para>
<para>The beans required in an application context to enable remember-me services are as follows:
<programlisting><![CDATA[
<bean id="rememberMeProcessingFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeProcessingFilter">
<programlisting language="xml"><![CDATA[
<bean id="rememberMeProcessingFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>
<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationProvider">
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>
]]>

View File

@ -32,7 +32,8 @@
<info><title>Configuration</title></info>
<para>A <literal>RunAsManager</literal> interface is provided by Spring Security:
<programlisting>
Authentication buildRunAs(Authentication authentication, Object object, List&lt;ConfigAttribute&gt; config);
Authentication buildRunAs(Authentication authentication, Object object,
List&lt;ConfigAttribute&gt; config);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
</programlisting>
@ -87,7 +88,8 @@
bean context with the same key:
<programlisting>
<![CDATA[
<bean id="runAsManager" class="org.springframework.security.access.intercept.RunAsManagerImpl">
<bean id="runAsManager"
class="org.springframework.security.access.intercept.RunAsManagerImpl">
<property name="key" value="my_run_as_password"/>
</bean>

View File

@ -76,7 +76,7 @@
<programlisting><![CDATA[
<bean id="bankManagerSecurity"
class="org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor">
class="org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="afterInvocationManager" ref="afterInvocationManager"/>
@ -115,7 +115,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
private AspectJSecurityInterceptor securityInterceptor;
pointcut domainObjectInstanceExecution(): target(PersistableEntity)
&amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);
&amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);
Object around(): domainObjectInstanceExecution() {
if (this.securityInterceptor == null) {
@ -162,8 +162,8 @@ public void afterPropertiesSet() throws Exception {
<programlisting><![CDATA[
<bean id="domainObjectInstanceSecurityAspect"
class="org.springframework.security.samples.aspectj.DomainObjectInstanceSecurityAspect"
factory-method="aspectOf">
class="org.springframework.security.samples.aspectj.DomainObjectInstanceSecurityAspect"
factory-method="aspectOf">
<property name="securityInterceptor" ref="aspectJSecurityInterceptor"/>
</bean>]]>
</programlisting>
@ -187,12 +187,12 @@ public void afterPropertiesSet() throws Exception {
<programlisting>
<![CDATA[
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/acegilogin.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
@ -291,7 +291,7 @@ public void afterPropertiesSet() throws Exception {
<programlisting><![CDATA[
<bean id="filterInvocationInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="runAsManager" ref="runAsManager"/>

View File

@ -1,9 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<book version="5.0" xml:id="spring-security-reference-guide" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
<info><title>Spring Security</title><subtitle>Reference Documentation</subtitle><author>
<personname>Ben Alex, Luke Taylor</personname>
</author>
<info><title>Spring Security</title><subtitle>Reference Documentation</subtitle><authorgroup>
<author>
<personname>Ben Alex</personname>
</author>
<author>
<personname>Luke Taylor</personname>
</author>
</authorgroup>
<productname>Spring Security</productname>
<releaseinfo>3.0.0.M1</releaseinfo>
</info>
<toc/>
@ -82,11 +88,13 @@
<part xml:id="overall-architecture">
<title>Overall Architecture</title>
<partintro>
<para>Like most software, Spring Security has certain central interfaces, classes and
conceptual abstractions that are commonly used throughout the framework. In this part of the
reference guide we will introduce Spring Security, before examining these central elements
that are necessary to successfully planning and executing a Spring Security
integration.</para>
<para>Once you are familiar with setting up and running some namespace-configuration based
applications, you may wish to develop more of an understanding of how the framework actually
works behind the namespace facade. Like most software, Spring Security has certain central
interfaces, classes and conceptual abstractions that are commonly used throughout the
framework. In this part of the reference guide we will look at some of these and see how
they work together to support authentication and access-control within Spring
Security.</para>
</partintro>
<xi:include href="technical-overview.xml"/>
<xi:include href="supporting-infrastructure.xml"/>

View File

@ -38,7 +38,8 @@
is shown below:</para>
<para><programlisting><![CDATA[
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="org/springframework/security/messages"/>
</bean>
]]></programlisting></para>
@ -91,16 +92,16 @@
<para>When using <literal>DelegatingFilterProxy</literal>, you will see
something like this in the web.xml file:
<programlisting>
&lt;filter&gt;
&lt;filter-name&gt;myFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
&lt;/filter&gt;
<programlisting><![CDATA[
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
&lt;filter-mapping&gt;
&lt;filter-name&gt;myFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>]]>
</programlisting>
Notice that the filter is actually a <literal>DelegatingFilterProxy</literal>,
@ -152,10 +153,16 @@
<para><programlisting><![CDATA[
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**"
filters="httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
<sec:filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
<sec:filter-chain pattern="/webServices/**" filters="
httpSessionContextIntegrationFilterWithASCFalse,
basicProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters="
httpSessionContextIntegrationFilterWithASCTrue,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
]]>
@ -335,8 +342,7 @@
in your JSP:
<programlisting>
&lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
</programlisting></para>
</programlisting></para>
</section>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/*
code highlight CSS resemblign the Eclipse IDE default color schema
@author Costin Leau
*/
.hl-keyword {
color: #7F0055;
font-weight: bold;
}
.hl-comment {
color: #3F5F5F;
font-style: italic;
}
.hl-multiline-comment {
color: #3F5FBF;
font-style: italic;
}
.hl-tag {
color: #3F7F7F;
}
.hl-attribute {
color: #7F007F;
}
.hl-value {
color: #2A00FF;
}
.hl-string {
color: #2A00FF;
}

View File

@ -0,0 +1,59 @@
@IMPORT url("highlight.css");
html {
padding: 0pt;
margin: 0pt;
}
body {
margin-left: 10%;
margin-right: 10%;
font-family: Arial, Sans-serif;
}
div {
margin: 0pt;
}
p {
text-align: justify;
}
hr {
border: 1px solid gray;
background: gray;
}
h1,h2,h3,h4 {
color: #234623;
font-family: Arial, Sans-serif;
}
pre {
line-height: 1.0;
color: black;
}
pre.programlisting {
font-size: 10pt;
padding: 7pt 3pt;
border: 1pt solid black;
background: #eeeeee;
clear: both;
}
div.table {
margin: 1em;
padding: 0.5em;
text-align: center;
}
div.table table {
display: table;
width: 100%;
}
div.table td {
padding-left: 7px;
padding-right: 7px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xslthl="http://xslthl.sf.net"
exclude-result-prefixes="xslthl"
version='1.0'>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/highlight.xsl"/>
<xsl:param name="chunk.section.depth">'5'</xsl:param>
<xsl:param name="use.id.as.filename">'1'</xsl:param>
<!-- Use code syntax highlighting -->
<xsl:param name="highlight.source">1</xsl:param>
<!-- Extensions -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<!-- Activate Graphics -->
<xsl:param name="admon.graphics" select="1"/>
<xsl:param name="admon.graphics.path">images/</xsl:param>
<xsl:param name="admon.graphics.extension">.gif</xsl:param>
<xsl:param name="callout.graphics" select="1" />
<xsl:param name="callout.defaultcolumn">120</xsl:param>
<xsl:param name="callout.graphics.path">images/callouts/</xsl:param>
<xsl:param name="callout.graphics.extension">.gif</xsl:param>
<xsl:param name="table.borders.with.css" select="1"/>
<xsl:param name="html.stylesheet">css/manual.css</xsl:param>
<xsl:param name="html.stylesheet.type">text/css</xsl:param>
<xsl:param name="generate.toc">book toc,title</xsl:param>
<xsl:param name="admonition.title.properties">text-align: left</xsl:param>
<!-- Leave image paths as relative when navigating XInclude -->
<xsl:param name="keep.relative.image.uris" select="1"/>
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel" select="1"/>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.autolabel.max.depth" select="2"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<xsl:param name="table.footnote.number.format" select="'1'"/>
<!-- Show only Sections up to level 2 in the TOCs -->
<xsl:param name="toc.section.depth">2</xsl:param>
<!-- Remove "Chapter" from the Chapter titles... -->
<xsl:param name="local.l10n.xml" select="document('')"/>
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
<l:l10n language="en">
<l:context name="title-numbered">
<l:template name="chapter" text="%n.&#160;%t"/>
<l:template name="section" text="%n&#160;%t"/>
</l:context>
</l:l10n>
</l:i18n>
<xsl:template match='xslthl:keyword' mode="xslthl">
<span class="hl-keyword"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:oneline-comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:multiline-comment' mode="xslthl">
<span class="hl-multiline-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:tag' mode="xslthl">
<span class="hl-tag"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:attribute' mode="xslthl">
<span class="hl-attribute"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:value' mode="xslthl">
<span class="hl-value"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:string' mode="xslthl">
<span class="hl-string"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<!-- Google Analytics -->
<xsl:template name="user.head.content">
<xsl:comment>Begin Google Analytics code</xsl:comment>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-2728886-3");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
</script>
<xsl:comment>End Google Analytics code</xsl:comment>
</xsl:template>
<!-- Loopfuse -->
<xsl:template name="user.footer.content">
<xsl:comment>Begin LoopFuse code</xsl:comment>
<script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript">
</script>
<script type="text/javascript">
_lf_cid = "LF_48be82fa";
_lf_remora();
</script>
<xsl:comment>End LoopFuse code</xsl:comment>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,501 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xslthl="http://xslthl.sf.net"
exclude-result-prefixes="xslthl"
version='1.0'>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/highlight.xsl"/>
<xsl:param name="admon.graphics">'1'</xsl:param>
<xsl:param name="admon.graphics.path">images/</xsl:param>
<xsl:param name="draft.watermark.image" select="'images/draft.png'"/>
<xsl:param name="paper.type" select="'A4'"/>
<xsl:param name="page.margin.top" select="'1cm'"/>
<xsl:param name="region.before.extent" select="'1cm'"/>
<xsl:param name="body.margin.top" select="'1.5cm'"/>
<xsl:param name="body.margin.bottom" select="'1.5cm'"/>
<xsl:param name="region.after.extent" select="'1cm'"/>
<xsl:param name="page.margin.bottom" select="'1cm'"/>
<xsl:param name="title.margin.left" select="'0cm'"/>
<!--###################################################
Header
################################################### -->
<!-- More space in the center header for long text -->
<xsl:attribute-set name="header.content.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$body.font.family"/>
</xsl:attribute>
<xsl:attribute name="margin-left">-5em</xsl:attribute>
<xsl:attribute name="margin-right">-5em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Table of Contents
################################################### -->
<xsl:param name="generate.toc">
book toc,title
</xsl:param>
<!--###################################################
Custom Header
################################################### -->
<xsl:template name="header.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
<xsl:variable name="Version">
<xsl:choose>
<xsl:when test="//productname">
<xsl:value-of select="//productname"/><xsl:text> </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>please define productname in your docbook file!</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$sequence='blank'">
<xsl:choose>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$pageclass='titlepage'">
</xsl:when>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--###################################################
Custom Footer
################################################### -->
<xsl:template name="footer.content">
<xsl:param name="pageclass" select="''"/>
<xsl:param name="sequence" select="''"/>
<xsl:param name="position" select="''"/>
<xsl:param name="gentext-key" select="''"/>
<xsl:variable name="Version">
<xsl:choose>
<xsl:when test="//releaseinfo">
<xsl:value-of select="//releaseinfo"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="Title">
<xsl:value-of select="//title"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$sequence='blank'">
<xsl:choose>
<xsl:when test="$double.sided != 0 and $position = 'left'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:when test="$double.sided = 0 and $position = 'center'">
</xsl:when>
<xsl:otherwise>
<fo:page-number/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$pageclass='titlepage'">
</xsl:when>
<xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$double.sided = 0 and $position='right'">
<fo:page-number/>
</xsl:when>
<xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:when test="$double.sided = 0 and $position='left'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:when test="$position='center'">
<xsl:value-of select="$Title"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="processing-instruction('hard-pagebreak')">
<fo:block break-before='page'/>
</xsl:template>
<!--###################################################
Extensions
################################################### -->
<!-- These extensions are required for table printing and other stuff
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<xsl:param name="fop.extensions">1</xsl:param>
-->
<!--###################################################
Paper & Page Size
################################################### -->
<!-- Paper type, no headers on blank pages, no double sided printing -->
<xsl:param name="double.sided">0</xsl:param>
<xsl:param name="headers.on.blank.pages">0</xsl:param>
<xsl:param name="footers.on.blank.pages">0</xsl:param>
<!--###################################################
Fonts & Styles
################################################### -->
<xsl:param name="hyphenate">false</xsl:param>
<!-- Default Font size -->
<xsl:param name="body.font.master">11</xsl:param>
<xsl:param name="body.font.small">8</xsl:param>
<!-- Line height in body text -->
<xsl:param name="line-height">1.4</xsl:param>
<!-- Chapter title size -->
<xsl:attribute-set name="chapter.titlepage.recto.style">
<xsl:attribute name="text-align">left</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.8"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
Let's remove it, so this sucker can use our attribute-set only... -->
<xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
xsl:use-attribute-sets="chapter.titlepage.recto.style">
<xsl:call-template name="component.title">
<xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
</xsl:call-template>
</fo:block>
</xsl:template>
<!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
<xsl:attribute-set name="section.title.level1.properties">
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.5"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level2.properties">
<xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.25"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level3.properties">
<xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!-- Use code syntax highlighting -->
<xsl:param name="highlight.source" select="1"/>
<xsl:param name="highlight.default.language" select="xml" />
<xsl:template match='xslthl:keyword'>
<fo:inline font-weight="bold" color="#7F0055"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:comment'>
<fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:oneline-comment'>
<fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:multiline-comment'>
<fo:inline font-style="italic" color="#3F5FBF"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:tag'>
<fo:inline color="#3F7F7F"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:attribute'>
<fo:inline color="#7F007F"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:value'>
<fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='xslthl:string'>
<fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline>
</xsl:template>
<!--###################################################
Tables
################################################### -->
<!-- Some padding inside tables -->
<xsl:attribute-set name="table.cell.padding">
<xsl:attribute name="padding-left">4pt</xsl:attribute>
<xsl:attribute name="padding-right">4pt</xsl:attribute>
<xsl:attribute name="padding-top">4pt</xsl:attribute>
<xsl:attribute name="padding-bottom">4pt</xsl:attribute>
</xsl:attribute-set>
<!-- Only hairlines as frame and cell borders in tables -->
<xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
<xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel" select="1"/>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.autolabel.max.depth" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<xsl:param name="table.footnote.number.format" select="'1'"/>
<!--###################################################
Programlistings
################################################### -->
<!-- Verbatim text formatting (programlistings) -->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.small * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="verbatim.properties">
<xsl:attribute name="space-before.minimum">1em</xsl:attribute>
<xsl:attribute name="space-before.optimum">1em</xsl:attribute>
<xsl:attribute name="space-before.maximum">1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
<xsl:attribute name="border-color">#444444</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">0.1pt</xsl:attribute>
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
<xsl:attribute name="padding-left">0.5em</xsl:attribute>
<xsl:attribute name="padding-right">0.5em</xsl:attribute>
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="margin-left">0.5em</xsl:attribute>
<xsl:attribute name="margin-right">0.5em</xsl:attribute>
</xsl:attribute-set>
<!-- Shade (background) programlistings -->
<xsl:param name="shade.verbatim">1</xsl:param>
<xsl:attribute-set name="shade.verbatim.style">
<xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="list.block.spacing">
<xsl:attribute name="space-before.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="example.properties">
<xsl:attribute name="space-before.minimum">0.5em</xsl:attribute>
<xsl:attribute name="space-before.optimum">0.5em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.5em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Title information for Figures, Examples etc.
################################################### -->
<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
<xsl:attribute name="font-weight">normal</xsl:attribute>
<xsl:attribute name="font-style">italic</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="hyphenate">false</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-before.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Callouts
################################################### -->
<!-- don't use images for callouts
<xsl:param name="callout.graphics">0</xsl:param>
<xsl:param name="callout.unicode">1</xsl:param>
-->
<!-- Place callout marks at this column in annotated areas
<xsl:param name="callout.defaultcolumn">90</xsl:param>
-->
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example after
equation before
table before
procedure before
</xsl:param>
<!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
<xsl:param name="variablelist.as.blocks">1</xsl:param>
<xsl:param name="body.start.indent">0pt</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">3</xsl:param>
<!-- Remove "Chapter" from the Chapter titles... -->
<xsl:param name="local.l10n.xml" select="document('')"/>
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
<l:l10n language="en">
<l:context name="title-numbered">
<l:template name="chapter" text="%n.&#160;%t"/>
<l:template name="section" text="%n&#160;%t"/>
</l:context>
<l:context name="title">
<l:template name="example" text="Example&#160;%n&#160;%t"/>
</l:context>
</l:l10n>
</l:i18n>
<!--###################################################
colored and hyphenated links
################################################### -->
<!--
<xsl:template match="ulink">
<fo:basic-link external-destination="{@url}"
xsl:use-attribute-sets="xref.properties"
text-decoration="underline"
color="blue">
<xsl:choose>
<xsl:when test="count(child::node())=0">
<xsl:value-of select="@url"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</fo:basic-link>
</xsl:template>
<xsl:template match="link">
<fo:basic-link internal-destination="{@linkend}"
xsl:use-attribute-sets="xref.properties"
text-decoration="underline"
color="blue">
<xsl:choose>
<xsl:when test="count(child::node())=0">
<xsl:value-of select="@linkend"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</fo:basic-link>
</xsl:template>
-->
</xsl:stylesheet>