SEC-1718: Update documentation and sample application to demonstrate how to use a PGT to authenticate to stateless services using a PT

This commit is contained in:
Rob Winch
2011-04-16 19:03:18 -05:00
parent abfa558c3c
commit 01fb4bdb6d
11 changed files with 256 additions and 21 deletions

View File

@@ -125,8 +125,8 @@
included in the CAS client library. In the event the application needs to validate proxy tickets, the
<classname>Cas20ProxyTicketValidator</classname> is used. The
<interfacename>TicketValidator</interfacename> makes an HTTPS request to the CAS server in order to
validate the service ticket. <!-- It may also include a proxy callback URL, which is included in this example:
<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>.-->
validate the service ticket. It may also include a proxy callback URL, which is included in this example:
<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/j_spring_cas_security_proxyreceptor</literal>.
</para>
</listitem>
@@ -134,11 +134,11 @@
<para>Back on the CAS server, the validation request will be
received. If the presented service ticket matches the service URL
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
included in the XML response.--></para>
included in the XML response.</para>
</listitem>
<!--
<listitem>
<para>[OPTIONAL] If the request to the CAS validation service included the proxy callback
URL (in the <literal>pgtUrl</literal> parameter), CAS will include a
@@ -147,17 +147,17 @@
connection back to the <literal>pgtUrl</literal>. This is to mutually authenticate the
CAS server and the claimed service URL. The HTTPS connection will be used to send a
proxy granting ticket 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>.</para>
<literal>https://server3.company.com/webapp/j_spring_cas_security_proxyreceptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.</para>
</listitem>
-->
<listitem>
<para>The <classname>Cas20TicketValidator</classname> will parse the XML received from the
CAS server. It will return to the <classname>CasAuthenticationProvider</classname> a
<literal>TicketResponse</literal>, which includes the username (mandatory). <!--, proxy list
<literal>TicketResponse</literal>, which includes the username (mandatory), proxy list
(if any were involved), and proxy-granting ticket IOU (if the proxy callback was
requested). --></para>
requested).</para>
</listitem>
<!--
<listitem>
<para>Next <literal>CasAuthenticationProvider</literal> will call
a configured <literal>CasProxyDecider</literal>. The
@@ -171,7 +171,7 @@
which allows a <literal>List</literal> of trusted proxies to be
provided.</para>
</listitem>
-->
<listitem>
<para><classname>CasAuthenticationProvider</classname> will next
request a <interfacename>AuthenticationUserDetailsService</interfacename> to load the
@@ -219,9 +219,9 @@
<info>
<title>Service Ticket Authentication</title>
</info>
<para>This section describes how to setup Spring Security to authenticate Service Tickets. You will need
to add a <classname>ServiceProperties</classname> bean to your application context. This represents
your CAS service:</para>
<para>This section describes how to setup Spring Security to authenticate Service Tickets. Often times
this is all a web application requires. You will need to add a <classname>ServiceProperties</classname>
bean to your application context. This represents your CAS service:</para>
<para> <programlisting language="xml"><![CDATA[
<bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
@@ -384,6 +384,89 @@
when an <interfacename>HttpSession</interfacename> expires, the mapping used for single logout is
removed.</para>
</section>
<section xml:id="cas-pt-client">
<info>
<title>Authenticating to a Stateless Service with CAS</title>
</info>
<para>This section describes how to authenticate to a service using CAS. In other words,
this section discusses how to setup a client that uses a service that authenticates with
CAS. The next section describes how to setup a stateless service to Authenticate
using CAS.</para>
<section xml:id="cas-pt-client-config">
<info>
<title>Configuring CAS to Obtain Proxy Granting Tickets</title>
</info>
<para>In order to authenticate to a stateless service, the application needs to obtain a proxy granting ticket
(PGT). This section describes how to configure Spring Security to obtain a PGT building upon then
<link xlink:href="cas-st">Service Ticket Authentication</link> configuration.</para>
<para>The first step is to include a <classname>ProxyGrantingTicketStorage</classname> in your Spring Security
configuration. This is used to store PGT's that are obtained by the
<classname>CasAuthenticationFilter</classname> so that they can be used to obtain proxy tickets. An example
configuration is shown below <programlisting language="xml"><![CDATA[
<!--
NOTE: In a real application you should not use an in memory implementation. You will also want
to ensure to clean up expired tickets by calling ProxyGrantingTicketStorage.cleanup()
-->
<bean id="pgtStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl"/>
]]></programlisting></para>
<para>The next step is to update the <classname>CasAuthenticationProvider</classname> to be able to obtain proxy
tickets. To do this replace the <classname>Cas20ServiceTicketValidator</classname> with a
<classname>Cas20ProxyTicketValidator</classname>. The <literal>proxyCallbackUrl</literal> should be set to
a URL that the application will receive PGT's at. Last, the configuration should also reference the
<classname>ProxyGrantingTicketStorage</classname> so it can use a PGT to obtain proxy tickets.
You can find an example of the configuration changes that should be made below.
<programlisting language="xml"><![CDATA[
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
...
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
<constructor-arg value="https://localhost:9443/cas"/>
<property name="proxyCallbackUrl"
value="https://localhost:8443/cas-sample/j_spring_cas_security_proxyreceptor"/>
<property name="proxyGrantingTicketStorage" ref="pgtStorage"/>
</bean>
</property>
</bean>
]]></programlisting></para>
<para>The last step is to update the <classname>CasAuthenticationFilter</classname> to accept PGT and to store them
in the <classname>ProxyGrantingTicketStorage</classname>. It is important the the <literal>proxyReceptorUrl</literal>
matches the <literal>proxyCallbackUrl</literal> of the <classname>Cas20ProxyTicketValidator</classname>. An example
configuration is shown below.
<programlisting language="xml"><![CDATA[
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
...
<property name="proxyGrantingTicketStorage" ref="pgtStorage"/>
<property name="proxyReceptorUrl" value="/j_spring_cas_security_proxyreceptor"/>
</bean>
]]></programlisting></para>
</section>
<section xml:id="cas-pt-client-sample">
<info>
<title>Calling a Stateless Service Using a Proxy Ticket</title>
</info>
<para>Now that Spring Security obtains PGTs, you can use them to create proxy tickets which can be used to authenticate
to a stateless service. The <link xlink:href="#cas-sample">CAS sample application</link> contains a working example in
the <classname>ProxyTicketSampleServlet</classname>. Example code can be found below:
<programlisting language="xml"><![CDATA[
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// NOTE: The CasAuthenticationToken can also be obtained using
// SecurityContextHolder.getContext().getAuthentication()
final CasAuthenticationToken token = (CasAuthenticationToken) request.getUserPrincipal();
// proxyTicket could be reused to make calls to to the CAS service even if the target url differs
final String proxyTicket = token.getAssertion().getPrincipal().getProxyTicketFor(targetUrl);
// Make a remote call using the proxy ticket
final String serviceUrl = targetUrl+"?ticket="+URLEncoder.encode(proxyTicket, "UTF-8");
String proxyResponse = CommonUtils.getResponseFromServer(serviceUrl, "UTF-8");
...
}
]]></programlisting></para>
</section>
</section>
<section xml:id="cas-pt">
<info>
<title>Proxy Ticket Authentication</title>