Installation
composer require ecphp/cas-bundle
Add to config/bundles.php:
return [
// ...
Ecphp\CasBundle\EcphpCasBundle::class => ['all' => true],
];
Configuration
Update config/packages/ecphp_cas.yaml:
ecphp_cas:
client:
cas_server_url: 'https://your-cas-server/cas'
authentication_url: '/cas/login'
validation_url: '/cas/serviceValidate'
logout_url: '/cas/logout'
user:
class: App\Entity\User
property: username
First Use Case Secure a route with CAS authentication:
# config/packages/security.yaml
security:
firewalls:
main:
pattern: ^/
cas:
entry_point: cas_authentication_entry_point
provider: cas_user_provider
config/packages/ecphp_cas.yaml (core settings)src/Security/CasUserProvider.php (custom user mapping)src/Security/CasAuthenticationEntryPoint.php (custom entry point)// In a controller or event subscriber
use Ecphp\CasBundle\Security\CasUserProvider;
// Fetch authenticated user
$user = $this->get('security.token_storage')->getToken()->getUser();
if ($user instanceof CasUserInterface) {
$casUser = $this->get(CasUserProvider::class)->loadUserByUsername($user->getUsername());
// Custom logic with CAS attributes
}
Access CAS-provided attributes:
$attributes = $user->getAttributes();
$email = $attributes->get('email') ?? null;
Extend CasUserProvider to map CAS responses to your user model:
use Ecphp\CasBundle\Security\CasUserProvider as BaseCasUserProvider;
class CustomCasUserProvider extends BaseCasUserProvider
{
public function loadUserByUsername($username)
{
$casUser = parent::loadUserByUsername($username);
$user = $this->userRepository->findOneBy(['username' => $username]);
if (!$user) {
$user = $this->userRepository->createNew();
$user->setUsername($username);
$user->setEmail($casUser->getAttributes()->get('email'));
$this->userRepository->save($user);
}
return $user;
}
}
# config/packages/security.yaml
security:
firewalls:
main:
pattern: ^/
cas:
logout:
invalidate_session: true
post_logout_redirect: /logout-success
cas_authenticator in your firewall configuration.UserCheckerInterface for post-authentication checks:
public function checkPostAuth(UserInterface $user)
{
if (!$user->hasAttribute('isActive')) {
throw new DisabledException('Account is disabled.');
}
}
// In a voter
public function vote(TokenInterface $token, $object, array $attributes)
{
$user = $token->getUser();
$requiredRole = $attributes[0];
if ($user->getAttributes()->has('roles')) {
$userRoles = $user->getAttributes()->get('roles');
return in_array($requiredRole, $userRoles, true);
}
return false;
}
Enable debug mode in config/packages/ecphp_cas.yaml:
ecphp_cas:
debug: true
CORS Issues with CAS Server
# config/packages/ecphp_cas.yaml
ecphp_cas:
client:
allowed_origins: ['https://your-frontend.com']
Attribute Parsing Failures
CasUser::getAttributes() to handle custom formats:
public function getAttributes()
{
if ($this->attributes === null) {
$this->attributes = new AttributesCollection(
json_decode($this->rawAttributes, true)
);
}
return $this->attributes;
}
Session Fixation
# config/packages/security.yaml
security:
firewalls:
main:
cas:
regenerate_session: true
Proxy Server Issues
trusted_proxies is configured:
# config/packages/framework.yaml
framework:
trusted_proxies:
- 192.168.0.0/16
Enable Verbose Logging
# config/packages/ecphp_cas.yaml
ecphp_cas:
debug: true
logging:
level: debug
Inspect CAS Responses
serviceValidate POST request.Test with a Mock CAS Server
URL Paths Must Match Exactly
authentication_url, validation_url, and logout_url match your CAS server’s endpoints exactly (including trailing slashes).HTTPS Requirements
# config/packages/framework.yaml
framework:
router:
http_port: 80
https_port: 443
redirect_http_to_https: true
User Provider Overrides
CasUserProvider, ensure your custom provider is registered as a service:
# config/services.yaml
services:
App\Security\CustomCasUserProvider:
tags: ['security.user_provider']
Custom Attribute Handlers
Ecphp\CasBundle\Security\AttributeHandlerInterface to transform raw attributes:
class CustomAttributeHandler implements AttributeHandlerInterface
{
public function handle(array $attributes, UserInterface $user)
{
$attributes['normalized_email'] = strtolower($attributes['email'] ?? '');
return $attributes;
}
}
Register in config/packages/ecphp_cas.yaml:
ecphp_cas:
attribute_handlers:
- App\Security\CustomAttributeHandler
Event Listeners
use Ecphp\CasBundle\Event\CasEvents;
use Symfony\Component\EventDispatcher\GenericEvent;
$dispatcher->addListener(CasEvents::AUTHENTICATION_SUCCESS, function (GenericEvent $event) {
$user = $event->getSubject();
// Custom logic on successful auth
});
Custom Entry Point
use Ecphp\CasBundle\Security\CasAuthenticationEntryPoint;
class CustomCasEntryPoint extends CasAuthenticationEntryPoint
{
public function start(Request $request = null, ?string $message = null)
{
return new RedirectResponse('/custom-cas-login');
}
}
Register in config/packages/security.yaml:
security:
firewalls:
main:
cas:
entry_point: custom_cas_entry_point
How can I help you explore Laravel packages today?