Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Auth_Adapter_Cas Component Proposal

Proposed Component Name Zend_Auth_Adapter_Cas
Developer Notes
Proposers Jeremy Postlethwaite
Revision 1.0 - 11 May 2009: Ready for community review
1.1 - 30 Jul 2009: Moved to ready for recommendation
1.2 - 31 Jul 2009: Added standalone use case for inclusion in non-MVC environments
1.3 - 16 Dec 2009: CAS authentication adapter revised and checked into the incubator (wiki revision: 19)

Table of Contents

1. Overview

Zend_Auth_Adapter_Cas is authentication adapter for CAS (Central Authentication Service) single-sign on protocol.

Central Authentication Service project, more commonly referred to as CAS. CAS is an authentication system originally created by Yale University to provide a trusted way for an application to authenticate a user.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component will implement Zend_Auth_Adapter_Interface.
  • This component will authenticate CAS ticket against CAS server.
  • This component will return Zend_Auth_Result::SUCCESS when CAS ticket is valid.
  • This component will return Zend_Auth_Result::FAILURE when CAS ticket is invalid.
  • This component must support optional SSL / TLS encrypted transport.
  • This component will not handle user redirects.
  • This component will not save any data.

4. Dependencies on Other Framework Components

  • Zend_Http_Client
  • simplexml_load_string with support for namespaces:

5. Theory of Operation

CAS authentication is typically handled by a remote server.

6. Milestones / Tasks

This CAS authentication adapter is capable of working with CAS versions 1, 2 and 3

  • Milestone 1: [DONE] Initial proposal published for review.
  • Milestone 2: [DONE] Working prototype and some examples.
  • Milestone 3: [DONE] Working prototype checked into the incubator supporting use cases.
  • Milestone 4: Unit tests exist, work, and are checked into SVN.
  • Milestone 5: Initial documentation exists.

7. Class Index

  • Zend_Auth_Adapter_Cas

8. Use Cases

UC-01 in MVC

Load parameters from Zend_Config:


or load directly:

Authenticate in an action

UC-02 in non-MVC

Standalone instance for non-MVC environments

9. Class Skeletons



Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jan 07, 2009

    <p>I'd definitely have interest in using this.  Our university beginning to embrace CAS for web app authentication.  I'm currently using the PEAR CAS library, but having CAS integrated into ZF would be great!</p>

  2. Feb 12, 2009

    <p>Hi Teemu,<br />
    Is it fair to believe this code is only in the proposal stage, and is not at all ready for production use?</p>

    <p> Just wondering... as we'd like to use it, but as per <a class="external-link" href=""></a> it looks like development didn't yet progress.</p>

    <p>Thanks,<br />

  3. Feb 12, 2009

    <p>I note <a class="external-link" href=""></a>, which could be a duplicate.</p>

  4. Apr 02, 2009

    <p>This proposal seems stuck...I've created an implementation and example file, but can't modify this proposal.</p>

  5. May 11, 2009

    <p>I updated this page to include a functional class which I have in use at UC Davis <a class="external-link" href=""></a></p>

    <p>This class should be interoperable with CAS 1, 2 and 3.</p>

  6. Jul 02, 2009


    <p>What's involved with getting this into the release version?</p>

    <p>I've got it running in a test environment with no problems so far.</p>

    <p>Thanks!<br />

    1. Jul 04, 2009

      <p>We just need to get more people to test it and make sure it works.</p>

      <p>I am glad to hear that it is working just fine.</p>

      <p>Just curious, what version of CAS are you using?</p>

      <p>I am using it on CAS version 3.</p>



      1. Jul 06, 2009

        <p>Hi, Jeremy:</p>

        <p>My systems folk tell me we're running 3 as well.</p>

        <p>Thanks!<br />

  7. Jul 30, 2009

    <p>I moved this into Ready for Recommendation to get this into the code base.</p>

  8. Jul 31, 2009

    <p>Hi, Jeremy:</p>

    <p>Great! Let me know if there's anything I can do to help.</p>


  9. Jul 31, 2009

    <p>I added a standalone version to this script for people who like to use only the Zend_Auth_Adapter_Cas class and not the MVC features of Zend.</p>

    <p>All one needs to do is take "UC-02 in non-MVC," save it as a single web page and edit your CAS configuration:</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    $config = array(
    'hostname' => '',
    'port' => 443,
    'path' => 'cas/',

    <p>I have set this up so you need the following directory structure:</p>

    <ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[



    <p>You will need the entire Zend Library, I have just shown where to put your key files.</p>

    <p>The class Zend_Auth_Adapter_Cas would be set in the folder:</p>


    <p>The UC-02 web page would be put into:</p>


  10. Aug 20, 2009

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Acceptance</ac:parameter><ac:rich-text-body>
    <p>This proposal is accepted for immediate development in the standard incubator, with the following requirements:</p>

    <li>Coding standards:
    <li>getLogin/LogoutURL methods: URL -> Url</li>
    <li>Design issues:
    <li>Add getters for all setters; use getters internally in all methods. This offers better encapsulation.</li>
    <li>Don't access superglobals directly when possible; these values should be passed in.
    <li>Add methods:
    <li>Allow passing each of these via constructor:
    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    $adapter = new Zend_Auth_Adapter_Cas(array(
    'selfUrl' => $request->getRequestUri(),
    'queryParams' => $request->getQuery(),
    // ...
    <li>Only if the values are not passed, should they be retrieved from the relevant superglobal</li>

  11. Sep 29, 2009

    <p>I have committed the adapter to the incubator.</p>

    <p>I will begin working on Matthew's suggested changes.</p>

  12. Dec 16, 2009

    <p>I have updated the CAS authentication module.</p>

  13. Apr 06, 2010

    <p>Jeremy, thanks for your work on this adapter so far, I just started playing with it (talking to a RubyCAS server).</p>

    <p>Things seem to work well, but following the use case above left me a little bit short when first implementing, so I wanted to mention what I had to do so it can either be documented, or perhaps something altered so it functions as the use case demonstrates.</p>

    <p>calling ->hasTicket() after being redirected from the CAS login URL would just result in an endless redirect loop for me (the CAS server is correctly appending the ticket to the GET param "ticket").</p>

    <p>In my controller plugin (preDispatch) I had to add the following calls before the ->hasTicket() call in order to get this to work as expected:</p>

    <p>$adapter->setQueryParams($request->getQuery());<br />

    <p>This would then correctly populate the adapter with the right session ticket from the query string, and then store it in the protected _ticket property, thus stopping the endless redirect.</p>

    1. Feb 10, 2011

      <p>Thanks for the notes Jay. I had the same problem and adding those two lines seems to have fixed things. It seems these should be added to the use case example(s) above. Or am I doing something incorrectly?</p>

  14. Apr 27, 2010

    <p>Hi All,</p>

    <p>Am I correct in assuming that the working code for this proposal in only available via cut/paste from this proposal page? I brief look in SVN (<a class="external-link" href=""></a>) does not reveal the code for this proposal, even though it was granted incubator acceptance.</p>

    <p>Could someone point me in the right direction for where this code is being stored please?</p>

    <p>Thanks, Andrew</p>

  15. Apr 27, 2010

    <p>Andrew, It's in the incubator currently.</p>

    <p><a class="external-link" href=""></a></p>


  16. Apr 28, 2010

    <p>Cheers Jay</p>

  17. Sep 09, 2010

    <p>Hi all,</p>

    <p>unfortunatly i cant create an issue for this incubator component. Its not listed in the Issuetracker.</p>

    <p>I use this component instead of phpCAS, and it works really well. But there is one thing i missed so far. I need to have access to the full xml-response from the server. In my case the server sends additional authentication information within the response XML. So I modified getResponseBody():</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    protected function getResponseBody($body) {
    $xml = simplexml_load_string($body, 'SimpleXMLElement', 0, $this->_xmlNameSpace);


    Unknown macro: { return get_object_vars($xml->authenticationSuccess); }

    else {

    <p>and authenticate():</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    public function authenticate()
    if($result = $this->validateTicket($this->getTicket(), $this->getService()))

    Unknown macro: { return new Zend_Auth_Result(Zend_Auth_Result}


    Unknown macro: { return new Zend_Auth_Result(Zend_Auth_Result}

    <p>Thus the whole behavior is the same except that every node from the response is also in the $messages from Zend_Auth_Result.</p>

    <p>Will you consider this change?</p>

    <p>Thanks,<br />
    Markus </p>

    1. Sep 09, 2010

      <p>Hi, Markus:</p>

      <p>Will your changes break existing instances?</p>

      <p>Thanks,<br />

    2. Sep 20, 2010

      <p>Hi Markus,</p>

      <p>I am glad you are getting good use out of the adapter.</p>

      <p>I committed your suggestion as it did not break backwards compatibility.</p>

      <p>I am sure others may want the full response as well.</p>

      <p>Thanks for your input!</p>


  18. Sep 10, 2010

    <p>Hi Greg,</p>

    <p>no, i dont think so. In the end, the only difference is that Zend_Auth_Result has $messages even if the result is SUCCESS.</p>

    <p>Thanks,<br />

    1. Sep 10, 2010

      <p>Hi, Markus:</p>

      <p>Then I'm all for it!</p>

      <p>I vote yes.</p>

      <p>Thanks!<br />

  19. Sep 10, 2010

    <p>I can test this out next week (Sept 13th - 17th).</p>

    <p>I also need to finish the unit tests so I can get this checked in.</p>

    <p>If anyone has any thoughts about the unit tests, please let me know.</p>



    1. Sep 10, 2010

      <p>Hi, Jeremy:</p>

      <p>I'm a total novice with unit testing in general, so I'm probably not much help. But I'll do what I can. What do you need?</p>

      <p>Thanks!<br />

      1. Sep 10, 2010

        <p>We need to have all of our test cases setup:</p>

        <ul class="alternate">
        <li>CAS server is unavailable</li>
        <li>CAS authentication succeeded</li>
        <li>CAS authentication failed</li>
        <li>CAS returns bad xml</li>
        <li>CAS returns wrong information</li>
        <li>Any authentication tests required by Zend_Auth_Adapter</li>

        <p>The tests will eventually end up here:</p>

        <p><a class="external-link" href=""></a></p>

  20. Oct 13, 2010

    <p>This adapter is affected by the PHP bug:</p>

    <p><a class="external-link" href=""></a></p>

    1. Oct 29, 2010

      <p>Jeremy,<br />
      Does this bug effect PHP 5.3.2? I recently included your Cas.php code, followed your direction, but kept getting a redirect loop. So then I added Jay Klehr's suggestion, but when it returns the following error messages:</p>

      <p>[0] => Authentication failed: Failed to connect to server<br />
      [1] => Unable to Connect to ssl:// Error #0:</p>

      <p>This only happens when it is trying to validate the ticket. The class is able to redirect me successfully to my CAS server, but once I authenticate, it chokes on the ticket validation. Is there any workaround? Or am I doing something wrong. Here is my casAction() for reference:</p>

      <p><a href=""></a></p>

      <p>Perhaps I'm using it incorrectly.</p>

      <p>Thank you,<br />

      1. Oct 29, 2010

        <p>Hi Henry,</p>

        <p>I have not coded a work around yet. At my university (UC Davis), we have a test environment that is using a self-signed certificate. </p>

        <p>The test environment is not affected by the PHP bug. The production server is identical with an SSL certificate from Geotrust. I get the same error:</p>

        <p>Unable to Connect to ssl://...</p>

        <p>There are a few recommendations in the bug report:</p>

        <p><a class="external-link" href=""></a></p>

        <p>I have not had a chance to check if I can pass options to Zend_Http_Client to workaround the error.</p>

        <p>Someone changed the default ciphers:</p>

        <p>'ciphers' => 'ALL:!AES:!3DES:!RC4:@STRENGTH', // OK:LOW</p>

        <p>when using:</p>


        <p>Zend_Http_Client is not using that method, so I am not sure if I can do something similar.</p>

        1. Oct 29, 2010


          <p>I fixed the code. Here is the patch file. Essentially I changed the adapter from Socket to Curl and that did the trick. Perhaps we can make the adapter a Zend_Auth_Cas configuration option? Or just replace the Socket adapter overall? Will that break backwards compatibility? What are your thoughts?</p>


          <p>Index: library/Zend/Auth/Adapter/Cas.php<br />
          ===================================================================<br />
          — library/Zend/Auth/Adapter/Cas.php (revision 23274)<br />
          +++ library/Zend/Auth/Adapter/Cas.php (working copy)<br />
          @@ -689,7 +689,10 @@<br />
          require_once 'Zend/Http/Client.php';</p>

          <p>try {<br />

          • $client = new Zend_Http_Client($this->getValidationURL());<br />
            + $config = array(<br />
            + 'adapter' => 'Zend_Http_Client_Adapter_Curl',<br />
            + );<br />
            + $client = new Zend_Http_Client($this->getValidationURL(), $config);</p>

          <p>$client->setParameterGet($this->getValidationParams($ticket, $service));</p>

          1. Oct 29, 2010

            <p>Thanks Henry,</p>

            <p>I will try this out next week. If all goes well, I will put it in the incubator.</p>

            1. Nov 02, 2010

              <p>I am putting in code to use different client adapters with options.</p>

              <p>For example, I need to specify a Certificate Authority file to be able to use cURL.</p>

  21. Nov 03, 2010

    <p>I checked in a new revision with the ability to specify an adapter with Zend_Http_Client.</p>

    <p>Here is the latest file in the incubator:</p>

    <p><a class="external-link" href=""></a></p>

    <p>This is revision: 23291</p>

    <p>Please see:</p>

    <p>Use cases: UC-01 in MVC, at the top of the page, for details on how to specify the client adapter: Zend_Http_Client_Adapter_Curl</p>

    1. Nov 04, 2010

      <p>Works like a charm!!!! For sake of yet another use case, I'll share my code below.</p>

      <p>Here is my sample page:
      <a class="external-link" href=""></a></p>

      <p>Here is my sample config file:</p>

      <p>[cas]<br />
      hostname =<br />
      port = 443<br />
      path = "cas"<br />
      clientAdapter.adapter = "Zend_Http_Client_Adapter_Curl"</p>

      <p>Finally, here is the actual call to grab the auth adapter:</p>

      <p>$options = new Zend_Config_Ini(APPLICATION_PATH . '/configs/config.ini');<br />
      $adapter = new Zend_Auth_Adapter_Cas($options->cas->toArray());</p>

      <p>Can't get any easier, now to move the code from incubator to production so I don't have to have two separate "svn:externals" in my subversion working copy <ac:emoticon ac:name="smile" /></p>

      <p>Thank you Jeremy!!!</p>