Install the Bundle
composer require dsi-iepg/cas-connection
Configure the Bundle
Add to config/bundles.php:
return [
// ...
Iepg\Bundle\Cas\CasConnectionBundle::class => ['all' => true],
];
Set CAS Environment Variables
Add to .env:
CAS_HOST=your-cas-server.com
CAS_PORT=443
Create a CAS-Compatible User Entity
Generate a User entity with a login field (no password):
php bin/console make:user
UseryesloginnoRun Migrations
php bin/console make:migration
php bin/console doctrine:migrations:migrate
First Test
Access your app’s login route (e.g., /login). The bundle should redirect to the CAS server for authentication.
/login → redirected to CAS server.User record with the CAS-provided login, and logs them in.User Authentication Flow
Iepg\Bundle\Cas\Security\CASAuthenticator if custom logic is needed (e.g., role assignment).// src/Security/CustomCASAuthenticator.php
namespace App\Security;
use Iepg\Bundle\Cas\Security\CASAuthenticator as BaseAuthenticator;
class CustomCASAuthenticator extends BaseAuthenticator {
public function getUserRoles($login) {
// Fetch roles from a service or DB
return ['ROLE_USER', 'ROLE_ADMIN']; // Example
}
}
config/packages/security.yaml:
security:
firewalls:
main:
authenticator: App\Security\CustomCASAuthenticator
User Entity Customization
User entity to add CAS-specific fields (e.g., casAttributes):
// src/Entity/User.php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class User {
// ...
#[ORM\Column(type: 'json', nullable: true)]
private ?array $casAttributes = [];
public function setCasAttributes(array $attributes): self {
$this->casAttributes = $attributes;
return $this;
}
}
// In CustomCASAuthenticator
public function getUser($credentials, UserProviderInterface $userProvider) {
$user = parent::getUser($credentials, $userProvider);
$user->setCasAttributes($this->fetchCasAttributesFromServer());
return $user;
}
Multi-Tenant or Role-Based Access
USER/ADMIN roles to gate routes:
# config/routes.yaml
admin:
path: /admin
controller: App\Controller\AdminController::index
roles: ROLE_ADMIN
// In CustomCASAuthenticator
public function getUserRoles($login) {
$casAttributes = $this->fetchCasAttributes($login);
return $casAttributes['groups'] ?? ['ROLE_USER'];
}
Logout Handling
// In CustomCASAuthenticator
public function onLogoutSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response {
// Add custom logout logic (e.g., invalidate sessions)
return parent::onLogoutSuccess($request, $token, $firewallName);
}
security.yaml to configure firewalls, access control, and providers.https://your-app.com/login_check).login attribute in the CAS response (required by the bundle).php-cas library to mock CAS responses in PHPUnit tests:
// tests/Functional/CASAuthTest.php
use PHP_CAS;
public function testCasLogin() {
PHP_CAS::setServer('https://test-cas.com');
PHP_CAS::setNoCasServerValidation();
// Test login flow
}
# config/packages/cas.yaml
parameters:
cas_host: '%env(CAS_HOST)%'
cas_port: '%env(int:CAS_PORT)%'
Missing login Field
login field in the User entity. If omitted, authentication will fail silently.User entity with the login property or manually add it.CAS Server Mismatch
CAS_HOST or CAS_PORT are misconfigured, the bundle will throw a RuntimeException.CAS_DEBUG=true
Certificate Validation Issues
CAS_CA=true but the certificate is invalid, the bundle will fail with a PHP_CAS_Exception.CAS_CA_PATH) or disable validation in development:
CAS_CA=false # Only for testing!
Role Assignment Conflicts
USER and ADMIN roles. Overriding these without updating the authenticator can cause role mismatches.Session Fixation
stateless: true or session fixation protection:
# config/packages/security.yaml
firewalls:
main:
stateless: true
CSRF Token Mismatch
_csrf_token in the session.# config/packages/security.yaml
firewalls:
main:
form_login:
csrf_token_generator: security.csrf.token_manager
Enable CAS Debug Mode
Add to .env:
CAS_DEBUG=true
This logs CAS requests/responses to var/log/dev.log.
Inspect the CAS Response Dump the CAS ticket or attributes in the authenticator:
// In CustomCASAuthenticator
public function getUser($credentials, UserProviderInterface $userProvider) {
dump($credentials); // Shows CAS response data
// ...
}
Validate CAS Server
Test the CAS server independently using php-cas:
use PHP_CAS;
PHP_CAS::client(CAS_VERSION_2_0, 'your-app.com', 443, 'cas-server.com');
if (PHP_CAS::isAuthenticated()) {
echo "Authenticated as: " . PHP_CAS::getUser();
}
Check Doctrine Events
Listen for prePersist/preUpdate on the User entity to debug CAS attribute mapping:
// src/EventListener/UserListener.php
namespace App\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
class UserListener {
public function prePersist(User $user, LifecycleEventArgs $args) {
dump($user->getCasAttributes());
}
}
Register the listener in services.yaml:
services:
App\EventListener\UserListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
UserProvider to fetch users from an external source (e.g., LDAPHow can I help you explore Laravel packages today?