manual reorganization
|
@ -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>
|
||||
|
|
|
@ -70,7 +70,8 @@
|
|||
<interfacename>AccessDecisionManager</interfacename> interface contains three
|
||||
methods:
|
||||
<programlisting>
|
||||
void decide(Authentication authentication, Object secureObject, List<ConfigAttribute> config) throws AccessDeniedException;
|
||||
void decide(Authentication authentication, Object secureObject,
|
||||
List<ConfigAttribute> 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>
|
||||
|
|
|
@ -27,17 +27,17 @@
|
|||
<literal>BasicProcessingFilter</literal> and its required
|
||||
collaborator:</para>
|
||||
|
||||
<para><programlisting language="xml">
|
||||
<bean id="basicProcessingFilter" class="org.springframework.security.web.authentication.www.BasicProcessingFilter">
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
<property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationEntryPoint"
|
||||
class="org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint">
|
||||
<property name="realmName"><value>Name Of Your Realm</value></property>
|
||||
</bean>
|
||||
|
||||
<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>
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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><intercept-url></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
|
||||
|
|
|
@ -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><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><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>
|
||||
<listener>
|
||||
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
|
||||
</listener>
|
||||
<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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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 <form-login> 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>
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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><user-service></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"/>
|
||||
...
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
]]>
|
||||
|
|
|
@ -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<ConfigAttribute> config);
|
||||
Authentication buildRunAs(Authentication authentication, Object object,
|
||||
List<ConfigAttribute> 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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
&& execution(public * *(..)) && !within(DomainObjectInstanceSecurityAspect);
|
||||
&& execution(public * *(..)) && !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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
<filter>
|
||||
<filter-name>myFilter</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
</filter>
|
||||
<programlisting><![CDATA[
|
||||
<filter>
|
||||
<filter-name>myFilter</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>myFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
<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>
|
||||
<%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %>
|
||||
|
||||
</programlisting></para>
|
||||
</programlisting></para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Before Width: | Height: | Size: 10 KiB |
|
@ -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. %t"/>
|
||||
<l:template name="section" text="%n %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>
|
|
@ -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. %t"/>
|
||||
<l:template name="section" text="%n %t"/>
|
||||
</l:context>
|
||||
<l:context name="title">
|
||||
<l:template name="example" text="Example %n %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>
|