Symfony CAS Client

How to integrate CAS in symfony 1.X

To secure a symfony application, there are two possibilities.

  1. You want to secure only somes pages, or even to be able to acces the same page been authenticated or not.
  2. You want to completely secure the access, and refuse anybody that are not logged in.

According to your needs, just follow the appropriate howto: 

1. Partially secure an application

To partially secure an application, just use the symfony plugin sfCASPlugin. Downloadable here: http://www.symfony-project.org/plugins/sfCasPlugin

2. Completely secure an application

To CASify a Symfonyapplication, first install phpCAS.  Then, in your application's lib folder, create sfCASRequiredFilter.class.php with this:

<?php
class sfCASRequiredFilter extends sfSecurityFilter
{
  public function execute ($filterChain)
  {
    if ($this->isFirstCall()) {
        require_once('phpCAS/CAS.php');
        // phpCAS::setDebug();

        phpCAS::client(CAS_VERSION_2_0,$this->getParameter('server_domain'), $this->getParameter('server_port'), $this->getParameter('server_path'));

        $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} about to force auth');
        phpCAS::forceAuthentication();
        $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} auth is good');

        $this->getContext()->getUser()->setAuthenticated(true);
        $this->getContext()->getUser()->setAttribute('username', phpCAS::getUser(), 'cas');
        $this->getContext()->getUser()->addCredential('username_'.phpCAS::getUser());
    }

    # if not initially authorized, sfBasicSecurityFilter sets $controller->forward(sfConfig::get('sf_login_module'), sfConfig::get('sf_login_action'));
    # so we re-dispatch since we are already authorized
    # copied from sfFrontWebController's dispatch()
    $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} configs are ' . sfConfig::get('sf_login_module') . '/' . sfConfig::get('sf_login_action'));
    if ($this->getContext()->getModuleName() == sfConfig::get('sf_login_module')
            && $this->getContext()->getActionName() == sfConfig::get('sf_login_action')) {

        $request    = $this->getContext()->getRequest();
        $moduleName = $request->getParameter('module');
        $actionName = $request->getParameter('action');
        $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} forwarding to ' . $moduleName . '/' . $actionName);
        $this->getContext()->getController()->forward($moduleName, $actionName);
    }

    // Execute next filter in the chain
    $filterChain->execute();
  }
}
?>





 Then in your app's config/filters.yml we need to add and configure this CAS filter.  In filters.yml before the 'security' filter, add the following (using the appropriate params for the CAS server you authenticate to):

cas_required:
  class: sfCASRequiredFilter
  param:
    # https://auth.mydomain.edu/cas/
    server_domain: auth.mydomain.edu
    server_port: 443
    server_path: cas

 In config/security.yml we enter the following

# for all modules
default:
  # require authentication, which our CAS filter will provide
  is_secure: on
  # allow only 3 specific users
  # double brackets means "or", single brackets means "and"
  credentials: [[username_d0501175, username_j0121968, username_l0004709]]

# need this to prevent infinite internal forwarding (don't have to be secured to see the "you need to be secured" page)
login:
  is_secure: off
secure:
  is_secure: off

 In config/settings.yml make sure that use_security is not set to off.  The default is on, which is good.

Finally, the secureSuccess.php template is used when authorization is not given (the user authenticates, but is not in our list of users).  However the symfony packaged secureSuccess.php says login required, instead of permissions required (which doesn't make sense.. it seems like they got secureSuccess.php and loginSuccess.php reversed).  Anyway, you'll want to customize secureSuccess.php so that when unauthorized users reach it they see your logo not symfony's logo.  To do that, go to your app's modules/ folder.  Create a default/ folder if one doesn't exist, and within that a templates/ folder.  Then create a secureSuccess.php in it.  You can use $PEAR_HOME/data/symfony/modules/default/templates/loginSuccess.php as a base if you want.

To access a user name in your code:

$this->getContext()->getUser()->getAttribute('username', null, 'cas');