This bundle provides a CAS authentication client for Symfony 5.4+, wrapping the phpCAS library from Apereo (https://www.apereo.org/projects/cas).
- PHP 7.4 or greater
- Symfony 5.4 or greater
- Require the bundle using Composer:
composer require univlorraine/symfony-cas-bundle
- Declare the bundle in Symfony Kernel if it's not already in (should be added automatically). In config/bundles.php:
<?php
return [
...
UnivLorraine\Bundle\SymfonyCasBundle\UnivLorraineSymfonyCasBundle::class => ['all' => true],
...
];
Create the config file config/packages/univ_lorraine_symfony_cas.yaml, and add these settings:
univ_lorraine_symfony_cas:
cas_url: my-cas-server-url.domain.tld # required
cas_context: ~ # optional (eg: /cas)
cas_port: 443 # optional (default: 443)
cas_service_base_url: https://yourapp.domain.com # required
cas_ca_cert: ~ # optional
cas_login_redirect: / # optional (default: /)
cas_logout_redirect: ~ # optional (must be a public area)
cas_version: "3.0" # optional (default: 2.0)
public_access_regex : ~ # a regex that match publicly accessible URLs but give user if authenticated
- cas_url: CAS server url (HTTP(S) scheme is not required).
- cas_context: possible additional path to access CAS Server if not root (eg: my-cas.cas.com/cas).
- cas_port: server port. If not set, the bundle will use default 443 port.
- cas_service_base_url: Url of the running app
- cas_ca_cert: path to the SSL CA Certificate.
- cas_login_redirect: the path the user will be redirected to after he logged in successfully. (It is only triggered when the user goes through the /login url, otherwise he will be automatically redirected to the url he requested, after he logged in).
- cas_logout_redirect: the path or url the user will be redirected to after he logged out. If not set, the user will be redirected to the CAS Server success logout page.
- cas_version: the version of the CAS Server used.
- public_access_regex: a regex with public_access URls declared in security.yaml for which you want to retrieve the user (if authenticated)
The bundle provides 2 routes :
- /login
- /logout
For adding these routes to your app, create the file config/routes/univ_lorraine_symfony_cas.yaml, and add these settings:
_symfony_cas:
resource: '@UnivLorraineSymfonyCasBundle/Resources/config/routes.xml'
prefix: /auth-cas
Feel free to use a different name as prefix, just remember it for the next security part.
Update the security config file config/packages/security.yaml.
- Enable custom authenticator:
security:
enable_authenticator_manager: true
...
- Create / update your secure area to use CAS authentication:
security:
...
firewalls:
...
secure:
pattern: ^/secure
provider: #feel free to use the User provider of your choice
security: true
custom_authenticators:
- univ_lorraine_symfony_cas.authenticator
...
main:
lazy: true
...
- Create public access for the login route (if behind secure area):
security:
...
access_control:
- { path: ^/auth-cas/login$, roles: PUBLIC_ACCESS }
...
This bundle is configured to logout from Symfony AND from the CAS.
The CAS Server can return additional attributes in addition to the main attributes (uid). When the user is authenticated, it is possible to get these attributes through the security token of Symfony:
use Symfony\Bundle\SecurityBundle\Security;
public function myFunction (Security $security) {
$user_attributes = $security->getToken()->getAttributes();
}
The bundle triggers an event (named univ_lorraine_symfony_cas.authentication_failure) during authentication failure, with 2 different error codes:
- 403 FORBIDDEN : when the user provider cannot find the authenticated user
- 401 UNAUTHORIZED: when an error occurs during the CAS authentication
You can use this event to customize the error pages.
- Create an Event Listener (eg: src/Event/AuthenticationFailureListener.php):
<?php
namespace App\Event;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use UnivLorraine\Bundle\SymfonyCasBundle\Event\CASAuthenticationFailureEvent;
class AuthenticationFailureListener {
private Router $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function onAuthenticationFailureResponse(CASAuthenticationFailureEvent $event): void
{
switch ($event->getResponse()->getStatusCode()) {
case Response::HTTP_UNAUTHORIZED:
$event->setResponse(new RedirectResponse($this->router->generate('auth_fail')));
break;
case Response::HTTP_FORBIDDEN:
$event->setResponse(new RedirectResponse($this->router->generate('access_denied')));
break;
}
}
}
- Register your listener in the services. In config/services.yaml:
...
services:
...
App\Event\AuthenticationFailureListener:
tags:
- { name: kernel.event_listener, event: univ_lorraine_symfony_cas.authentication_failure, method: onAuthenticationFailureResponse }
arguments: [ '@router' ]
See the LICENSE file for copyrights and limitations (CeCILL 2.1).