Re-instate the CAS integration sequence description in the CAS chapter, with corrections (and minus proxying).

This commit is contained in:
Luke Taylor 2011-01-18 16:50:18 +00:00
parent 2eefbf3a23
commit afd586c96e
2 changed files with 105 additions and 152 deletions

View File

@ -17,34 +17,30 @@
<title>How CAS Works</title> <title>How CAS Works</title>
</info> </info>
<para>Whilst the CAS web site contains documents that detail the architecture of CAS, we <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we
present the general overview again here within the context of Spring Security. Spring present the general overview again here within the context of Spring Security. Spring Security
Security 3.0 supports CAS 3. At the time of writing, the CAS server was at version 3.0 supports CAS 3. At the time of writing, the CAS server was at version 3.4.</para>
3.3.</para>
<para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is <para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is
simply a standard WAR file, so there isn't anything difficult about setting up your simply a standard WAR file, so there isn't anything difficult about setting up your
server. Inside the WAR file you will customise the login and other single sign on pages server. Inside the WAR file you will customise the login and other single sign on pages
displayed to users.</para> displayed to users.</para>
<para>When deploying a CAS 3.3 server, you will also need to specify an <para>When deploying a CAS 3.4 server, you will also need to specify an
<literal>AuthenticationHandler</literal> in the <literal>AuthenticationHandler</literal> in the
<filename>deployerConfigContext.xml</filename> included with CAS. The <filename>deployerConfigContext.xml</filename> included with CAS. The
<literal>AuthenticationHandler</literal> has a simple method that returns a boolean as <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as to
to whether a given set of Credentials is valid. Your whether a given set of Credentials is valid. Your <literal>AuthenticationHandler</literal>
<literal>AuthenticationHandler</literal> implementation will need to link into some type implementation will need to link into some type of backend authentication repository, such as
of backend authentication repository, such as an LDAP server or database. CAS itself an LDAP server or database. CAS itself includes numerous
includes numerous <literal>AuthenticationHandler</literal>s out of the box to assist <literal>AuthenticationHandler</literal>s out of the box to assist with this. When you
with this. When you download and deploy the server war file, it is set up to download and deploy the server war file, it is set up to successfully authenticate users who
successfully authenticate users who enter a password matching their username, which is enter a password matching their username, which is useful for testing.</para>
useful for testing.</para>
<para>Apart from the CAS server itself, the other key players are of course the secure web <para>Apart from the CAS server itself, the other key players are of course the secure web
applications deployed throughout your enterprise. These web applications are known as applications deployed throughout your enterprise. These web applications are known as
"services". There are two types of services: standard services and proxy services. A "services". There are two types of services: standard services and proxy services. A proxy
proxy service is able to request resources from other services on behalf of the user. service is able to request resources from other services on behalf of the user.</para>
This will be explained more fully later.</para>
<!--
<section xml:id="cas-sequence"> <section xml:id="cas-sequence">
<title>Spring Security and CAS Interaction Sequence</title> <title>Spring Security and CAS Interaction Sequence</title>
TODO: Needs reviewed
<para>The basic interaction between a web browser, CAS server and a <para>The basic interaction between a web browser, CAS server and a
Spring Security-secured service is as follows:</para> Spring Security-secured service is as follows:</para>
@ -58,25 +54,22 @@
<para>The user eventually requests a page that is either secure or <para>The user eventually requests a page that is either secure or
one of the beans it uses is secure. Spring Security's one of the beans it uses is secure. Spring Security's
<classname>ExceptionTranslationFilter</classname> will detect the <classname>ExceptionTranslationFilter</classname> will detect the
<literal>AuthenticationException</literal>.</para> <classname>AccessDeniedException</classname> or <classname>AuthenticationException</classname>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Because the user's <interfacename>Authentication</interfacename> object <para>Because the user's <interfacename>Authentication</interfacename> object (or lack
(or lack thereof) caused an thereof) caused an <classname>AuthenticationException</classname>, the
<literal>AuthenticationException</literal>, the <classname>ExceptionTranslationFilter</classname> will call the configured
<classname>ExceptionTranslationFilter</classname> will call the <interfacename>AuthenticationEntryPoint</interfacename>. If using CAS, this will be
configured <interfacename>AuthenticationEntryPoint</interfacename>. If using the <classname>CasAuthenticationEntryPoint</classname> class.</para>
CAS, this will be the
<literal>CasProcessingFilterEntryPoint</literal> class.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The <literal>CasProcessingFilterEntry</literal> point will <para>The <classname>CasAuthenticationEntryPoint</classname> will redirect the user's browser
redirect the user's browser to the CAS server. It will also to the CAS server. It will also indicate a <literal>service</literal> parameter, which
indicate a <literal>service</literal> parameter, which is the is the callback URL for the Spring Security service (your application). For example, the
callback URL for Spring Security service. For example, the URL to URL to which the browser is redirected might be
which the browser is redirected might be
<literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check</literal>.</para> <literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check</literal>.</para>
</listitem> </listitem>
@ -86,8 +79,8 @@
session cookie which indicates they've previously logged on, they session cookie which indicates they've previously logged on, they
will not be prompted to login again (there is an exception to this will not be prompted to login again (there is an exception to this
procedure, which we'll cover later). CAS will use the procedure, which we'll cover later). CAS will use the
<literal>PasswordHandler</literal> (or <interfacename>PasswordHandler</interfacename> (or
<literal>AuthenticationHandler</literal> if using CAS 3.0) <interfacename>AuthenticationHandler</interfacename> if using CAS 3.0)
discussed above to decide whether the username and password is discussed above to decide whether the username and password is
valid.</para> valid.</para>
</listitem> </listitem>
@ -102,78 +95,68 @@
</listitem> </listitem>
<listitem> <listitem>
<para>Back in the service web application, the <para>Back in the service web application, the <classname>CasAuthenticationFilter</classname> is
<literal>CasProcessingFilter</literal> is always listening for always listening for requests to <literal>/j_spring_cas_security_check</literal> (this
requests to <literal>/j_spring_cas_security_check</literal> (this is configurable, but we'll use the defaults in this introduction). The processing filter
is configurable, but we'll use the defaults in this introduction). will construct a <classname>UsernamePasswordAuthenticationToken</classname> representing the
The processing filter will construct a service ticket. The principal will be equal to
<literal>UsernamePasswordAuthenticationToken</literal> <literal>CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER</literal>, whilst the credentials
representing the service ticket. The principal will be equal to will be the service ticket opaque value. This authentication request will then be handed
<literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>, to the configured <interfacename>AuthenticationManager</interfacename>.</para>
whilst the credentials will be the service ticket opaque value.
This authentication request will then be handed to the configured
<interfacename>AuthenticationManager</interfacename>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The <interfacename>AuthenticationManager</interfacename> implementation <para>The <interfacename>AuthenticationManager</interfacename> implementation
will be the <literal>ProviderManager</literal>, which is in turn will be the <classname>ProviderManager</classname>, which is in turn
configured with the <literal>CasAuthenticationProvider</literal>. configured with the <classname>CasAuthenticationProvider</classname>.
The <literal>CasAuthenticationProvider</literal> only responds to The <classname>CasAuthenticationProvider</classname> only responds to
<literal>UsernamePasswordAuthenticationToken</literal>s containing <classname>UsernamePasswordAuthenticationToken</classname>s containing
the CAS-specific principal (such as the CAS-specific principal (such as
<literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>) <literal>CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER</literal>)
and <literal>CasAuthenticationToken</literal>s (discussed and <classname>CasAuthenticationToken</classname>s (discussed
later).</para> later).</para>
</listitem> </listitem>
<listitem> <listitem>
<para><literal>CasAuthenticationProvider</literal> will validate <para><classname>CasAuthenticationProvider</classname> will validate the service ticket using a
the service ticket using a <literal>TicketValidator</literal> <interfacename>TicketValidator</interfacename> implementation. This will typically be a
implementation. Spring Security includes one implementation, the <classname>Cas20ServiceTicketValidator</classname> ticket which is one of the classes
<literal>CasProxyTicketValidator</literal>. This implementation a included in the CAS client library. The <classname>Cas20ServiceTicketValidator</classname>
ticket validation class included in the CAS client library. The makes an HTTPS request to the CAS server in order to validate the service ticket. <!-- It
<literal>CasProxyTicketValidator</literal> makes an HTTPS request may also include a proxy callback URL, which is included in this example:
to the CAS server in order to validate the service ticket. The <literal>https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check&amp;ticket=ST-0-ER94xMJmn6pha35CQRoZ&amp;pgtUrl=https://server3.company.com/webapp/casProxy/receptor</literal>.
<literal>CasProxyTicketValidator</literal> may also include a In this case a <classname>Cas20ProxyTicketValidator</classname> should be used as the
proxy callback URL, which is included in this example: validator.--></para>
<literal>https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_spring_cas_security_check&amp;ticket=ST-0-ER94xMJmn6pha35CQRoZ&amp;pgtUrl=https://server3.company.com/webapp/casProxy/receptor</literal>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Back on the CAS server, the proxy validation request will be <para>Back on the CAS server, the validation request will be
received. If the presented service ticket matches the service URL received. If the presented service ticket matches the service URL
the ticket was issued to, CAS will provide an affirmative response the ticket was issued to, CAS will provide an affirmative response
in XML indicating the username. If any proxy was involved in the in XML indicating the username. <!-- If any proxy was involved in the
authentication (discussed below), the list of proxies is also authentication (discussed below), the list of proxies is also
included in the XML response.</para> included in the XML response.--></para>
</listitem> </listitem>
<!--
<listitem> <listitem>
<para>[OPTIONAL] If the request to the CAS validation service <para>[OPTIONAL] If the request to the CAS validation service included the proxy callback
included the proxy callback URL (in the <literal>pgtUrl</literal> URL (in the <literal>pgtUrl</literal> parameter), CAS will include a
parameter), CAS will include a <literal>pgtIou</literal> string in <literal>pgtIou</literal> string in the XML response. This <literal>pgtIou</literal>
the XML response. This <literal>pgtIou</literal> represents a represents a proxy-granting ticket IOU. The CAS server will then create its own HTTPS
proxy-granting ticket IOU. The CAS server will then create its own connection back to the <literal>pgtUrl</literal>. This is to mutually authenticate the
HTTPS connection back to the <literal>pgtUrl</literal>. This is to CAS server and the claimed service URL. The HTTPS connection will be used to send a
mutually authenticate the CAS server and the claimed service URL. proxy granting ticket to the original web application. For example,
The HTTPS connection will be used to send a proxy granting ticket <literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.</para>
to the original web application. For example,
<literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.
We suggest you use CAS' <literal>ProxyTicketReceptor</literal>
servlet to receive these proxy-granting tickets, if they are
required.</para>
</listitem> </listitem>
-->
<listitem> <listitem>
<para>The <literal>CasProxyTicketValidator</literal> will parse <para>The <classname>Cas20TicketValidator</classname> will parse the XML received from the
the XML received from the CAS server. It will return to the CAS server. It will return to the <classname>CasAuthenticationProvider</classname> a
<literal>CasAuthenticationProvider</literal> a <literal>TicketResponse</literal>, which includes the username (mandatory). <!--, proxy list
<literal>TicketResponse</literal>, which includes the username (if any were involved), and proxy-granting ticket IOU (if the proxy callback was
(mandatory), proxy list (if any were involved), and proxy-granting requested). --></para>
ticket IOU (if the proxy callback was requested).</para>
</listitem> </listitem>
<!--
<listitem> <listitem>
<para>Next <literal>CasAuthenticationProvider</literal> will call <para>Next <literal>CasAuthenticationProvider</literal> will call
a configured <literal>CasProxyDecider</literal>. The a configured <literal>CasProxyDecider</literal>. The
@ -187,64 +170,39 @@
which allows a <literal>List</literal> of trusted proxies to be which allows a <literal>List</literal> of trusted proxies to be
provided.</para> provided.</para>
</listitem> </listitem>
-->
<listitem> <listitem>
<para><literal>CasAuthenticationProvider</literal> will next <para><classname>CasAuthenticationProvider</classname> will next
request a <literal>CasAuthoritiesPopulator</literal> to advise the request a <interfacename>AuthenticationUserDetailsService</interfacename> to load the
<interfacename>GrantedAuthority</interfacename> objects that apply to the user <interfacename>GrantedAuthority</interfacename> objects that apply to the user
contained in the <literal>TicketResponse</literal>. Spring contained in the <interfacename>Assertion</interfacename>.</para>
Security includes a <literal>DaoCasAuthoritiesPopulator</literal>
which simply uses the <interfacename>UserDetailsService</interfacename>
infrastructure to find the <interfacename>UserDetails</interfacename> and
their associated <interfacename>GrantedAuthority</interfacename>s. Note that
the password and enabled/disabled status of
<interfacename>UserDetails</interfacename> returned by the
<interfacename>UserDetailsService</interfacename> are ignored, as the CAS
server is responsible for authentication decisions.
<literal>DaoCasAuthoritiesPopulator</literal> is only concerned
with retrieving the <interfacename>GrantedAuthority</interfacename>s.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>If there were no problems, <para>If there were no problems,
<literal>CasAuthenticationProvider</literal> constructs a <classname>CasAuthenticationProvider</classname> constructs a
<literal>CasAuthenticationToken</literal> including the details <classname>CasAuthenticationToken</classname> including the details
contained in the <literal>TicketResponse</literal> and the contained in the <interfacename>TicketResponse</interfacename> and the
<interfacename>GrantedAuthority</interfacename>s. The <interfacename>GrantedAuthority</interfacename>s.</para>
<literal>CasAuthenticationToken</literal> contains the hash of a
key, so that the <literal>CasAuthenticationProvider</literal>
knows it created it.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Control then returns to <para>Control then returns to
<literal>CasProcessingFilter</literal>, which places the created <classname>CasAuthenticationFilter</classname>, which places the created
<literal>CasAuthenticationToken</literal> into the <classname>CasAuthenticationToken</classname> in the security context.</para>
<literal>HttpSession</literal> attribute named
<literal>HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY</literal>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The user's browser is redirected to the original page that <para>The user's browser is redirected to the original page that
caused the <literal>AuthenticationException</literal>.</para> caused the <classname>AuthenticationException</classname> (or a
</listitem> <link xlink:href="#form-login-flow-handling">custom destination</link> depending on
the configuration).</para>
<listitem>
<para>As the <interfacename>Authentication</interfacename> object is now in
the well-known location, it is handled like any other
authentication approach. Usually the
<classname>HttpSessionContextIntegrationFilter</classname> will be
used to associate the <interfacename>Authentication</interfacename> object
with the <classname>SecurityContextHolder</classname> for the duration
of each request.</para>
</listitem> </listitem>
</orderedlist> </orderedlist>
<para>It's good that you're still here! It might sound involved, but <para>It's good that you're still here! Let's now look at how this is configured</para>
you can relax as Spring Security classes hide much of the complexity.
Let's now look at how this is configured</para>
</section> </section>
-->
</section> </section>
<section xml:id="cas-client"> <section xml:id="cas-client">
<info> <info>
@ -325,13 +283,16 @@
<security:user name="joe" password="joe" authorities="ROLE_USER" /> <security:user name="joe" password="joe" authorities="ROLE_USER" />
... ...
</security:user-service>]]> </security:user-service>]]>
</programlisting> The </programlisting> The <classname>CasAuthenticationProvider</classname> uses a
<classname>CasAuthenticationProvider</classname> uses a
<interfacename>UserDetailsService</interfacename> instance to load the authorities for a <interfacename>UserDetailsService</interfacename> instance to load the authorities for a
user, once they have been authentiated by CAS. We've shown a simple in-memory setup user, once they have been authenticated by CAS. We've shown a simple in-memory setup
here. </para> here. </para>
<para>The beans are all reasonable self-explanatory if you refer back to the "How CAS Works" <para>The beans are all reasonably self-explanatory if you refer back to the
section.</para> <quote>How CAS Works</quote> section.</para>
<para>This completes the configuration of CAS. If you haven't made any
mistakes, your web application should happily work within the
framework of CAS single sign on. No other parts of Spring Security
need to be concerned about the fact CAS handled authentication.</para>
</section> </section>
<!-- <!--
<para>Note the <literal>CasProxyTicketValidator</literal> has a <para>Note the <literal>CasProxyTicketValidator</literal> has a
@ -358,39 +319,33 @@
</programlisting></para> </programlisting></para>
<para>This completes the configuration of CAS. If you haven't made any
mistakes, your web application should happily work within the
framework of CAS single sign on. No other parts of Spring Security
need to be concerned about the fact CAS handled authentication.</para>
<para>There is also a <literal>contacts-cas.war</literal> file in the
sample applications directory. This sample application uses the above
settings and can be deployed to see CAS in operation</para>
</section> </section>
-->
<!--
<section xml:id="cas-advanced"> <section xml:id="cas-advanced">
<info><title>Advanced Issues</title></info> <info><title>Advanced Issues</title></info>
<para>The <literal>CasAuthenticationProvider</literal> distinguishes <para>The <classname>CasAuthenticationProvider</classname> distinguishes
between stateful and stateless clients. A stateful client is between stateful and stateless clients. A stateful client is
considered any that originates via the considered any that originates via the
<literal>CasProcessingFilter</literal>. A stateless client is any that <classname>CasAuthenticationFilter</classname>. A stateless client is any that
presents an authentication request via the presents an authentication request via the
<literal>UsernamePasswordAuthenticationToken</literal> with a <literal>UsernamePasswordAuthenticationToken</literal> with a
principal equal to principal equal to
<literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>.</para> <literal>CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER</literal>.</para>
<para>Stateless clients are likely to be via remoting protocols such <para>Stateless clients are likely to be via remoting protocols such
as Hessian and Burlap. The <literal>BasicProcessingFilter</literal> is as Hessian and Burlap. The <classname>BasicAuthenticationFilter</classname> is
still used in this case, but the remoting protocol client is expected still used in this case, but the remoting protocol client is expected
to present a username equal to the static string above, and a password to present a username equal to the static string above, and a password
equal to a CAS service ticket. Clients should acquire a CAS service equal to a CAS service ticket. Clients should acquire a CAS service
ticket directly from the CAS server.</para> ticket directly from the CAS server.</para>
<para>Because remoting protocols have no way of presenting themselves <para>Because remoting protocols have no way of presenting themselves
within the context of an <literal>HttpSession</literal>, it isn't within the context of an <classname>HttpSession</classname>, it isn't
possible to rely on the <literal>HttpSession</literal>'s possible to rely on the default practice of storing the security context in the
<literal>HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY</literal> session between requests.
attribute to locate the <literal>CasAuthenticationToken</literal>. attribute to locate the <literal>CasAuthenticationToken</literal>.
Furthermore, because the CAS server invalidates a service ticket after Furthermore, because the CAS server invalidates a service ticket after
it has been validated by the <literal>TicketValidator</literal>, it has been validated by the <literal>TicketValidator</literal>,
@ -408,7 +363,7 @@
<literal>CasAuthenticationProvider</literal> uses a <literal>CasAuthenticationProvider</literal> uses a
<literal>StatelessTicketCache</literal>. This is used solely for <literal>StatelessTicketCache</literal>. This is used solely for
requests with a principal equal to requests with a principal equal to
<literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>. What <literal>CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER</literal>. What
happens is the <literal>CasAuthenticationProvider</literal> will store happens is the <literal>CasAuthenticationProvider</literal> will store
the resulting <literal>CasAuthenticationToken</literal> in the the resulting <literal>CasAuthenticationToken</literal> in the
<literal>StatelessTicketCache</literal>, keyed on the service ticket. <literal>StatelessTicketCache</literal>, keyed on the service ticket.

View File

@ -125,9 +125,7 @@ Success! Your web filters appear to be properly configured!
<link xlink:href="#get-source">the introduction</link>. You'll find the relevant files <link xlink:href="#get-source">the introduction</link>. You'll find the relevant files
under the <filename>sample/cas</filename> directory. There's also a under the <filename>sample/cas</filename> directory. There's also a
<filename>Readme.txt</filename> file in there which explains how to run both the server <filename>Readme.txt</filename> file in there which explains how to run both the server
and the client directly from the source tree, complete with SSL support. You have to and the client directly from the source tree, complete with SSL support.</para>
download the CAS Server web application (a war file) from the CAS site and drop it into
the <filename>samples/cas/server</filename> directory. </para>
</section> </section>
<section xml:id="jaas-sample"> <section xml:id="jaas-sample">
<title>JAAS Sample</title> <title>JAAS Sample</title>