Laravel Integration Guide

Complete guide for integrating Laravel applications with CAS SSO

Setup time: 5 minutes Difficulty: Easy Laravel 8+

1. Installation

Prerequisites: Laravel 8+ and PHP 8.0+

📦 CAS Laravel Client Package

Complete Laravel integration package with all necessary files, middleware, and configuration.

  • ✓ CAS Authentication Service
  • ✓ HMAC Signature Validation
  • ✓ Middleware Components
  • ✓ Configuration Files
  • ✓ Service Provider
  • ✓ Example Controllers
Download Package

v2.0 - Updated for new architecture

Installation Steps

1

Download and Extract Package

# Extract the downloaded package to your Laravel project
unzip one-system-client-package.zip -d temp-cas/
cp -r temp-cas/* your-laravel-project/
rm -rf temp-cas/
2

Register Service Provider

Add the CAS service provider to your config/app.php:

'providers' => [
    // Other providers...
    App\Providers\CasClientServiceProvider::class,
],
3

Publish Configuration

php artisan vendor:publish --tag=cas-client-config

2. Configuration

New Architecture: Our CAS system now uses modular Admin/User/Public separation with enhanced security features.

Configure your CAS client by updating the config/cas-client.php file:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | CAS Server Configuration - Updated Architecture
    |--------------------------------------------------------------------------
    */
    'server_url' => env('CAS_SERVER_URL', 'https://your-cas-server.com'),
    'client_id' => env('CAS_CLIENT_ID'),
    'client_secret' => env('CAS_CLIENT_SECRET'),
    
    /*
    |--------------------------------------------------------------------------
    | Enhanced Authentication Settings
    |--------------------------------------------------------------------------
    */
    'token_expiry' => env('CAS_TOKEN_EXPIRY', 3600), // 1 hour
    'signature_validation' => env('CAS_SIGNATURE_VALIDATION', true),
    'hmac_algorithm' => 'sha256', // HMAC-SHA256 for enhanced security
    
    /*
    |--------------------------------------------------------------------------
    | New Route Configuration - Organized Structure
    |--------------------------------------------------------------------------
    */
    'routes' => [
        'sso_token' => '/api/sso/token',           // Enhanced client credentials flow
        'sso_validate' => '/api/sso/validate',     // Token validation endpoint
        'callback' => '/auth/sso/callback',        // SSO callback handler
        'user_dashboard' => '/user/dashboard',     // User dashboard route
        'logout' => '/auth/logout',                // Logout endpoint
    ],
    
    /*
    |--------------------------------------------------------------------------
    | PostgreSQL Schema Configuration
    |--------------------------------------------------------------------------
    */
    'database' => [
        'connection' => env('CAS_DB_CONNECTION', 'cas_system'),
        'schemas' => [
            'admin' => 'cas_admin',
            'user' => 'cas_user', 
            'public' => 'cas_public',
            'audit' => 'cas_audit'
        ]
    ],
    
    /*
    |--------------------------------------------------------------------------
    | IP Whitelist & Security Settings
    |--------------------------------------------------------------------------
    */
    'security' => [
        'ip_whitelist_enabled' => env('CAS_IP_WHITELIST', true),
        'audit_logging' => env('CAS_AUDIT_LOGGING', true),
        'rate_limiting' => env('CAS_RATE_LIMITING', true),
    ]
];

Environment Variables - Updated

Add these variables to your .env file:

# CAS Configuration - Enhanced Architecture
CAS_SERVER_URL=https://your-cas-server.com
CAS_CLIENT_ID=your-client-id
CAS_CLIENT_SECRET=your-client-secret
CAS_TOKEN_EXPIRY=3600
CAS_SIGNATURE_VALIDATION=true

# Database Configuration
CAS_DB_CONNECTION=cas_system
CAS_DB_HOST=127.0.0.1
CAS_DB_PORT=5432
CAS_DB_DATABASE=cas_system
CAS_DB_USERNAME=cas_user
CAS_DB_PASSWORD=secure_password

# Security Settings
CAS_IP_WHITELIST=true
CAS_AUDIT_LOGGING=true
CAS_RATE_LIMITING=true

3. Middleware Setup

Register Middleware

Add the CAS middleware to your app/Http/Kernel.php:

protected $routeMiddleware = [
    // ... existing middleware
    'cas.auth' => \CasSystem\LaravelClient\Middleware\CasAuth::class,
    'cas.role' => \CasSystem\LaravelClient\Middleware\CasRole::class,
];

Custom Middleware (Manual Installation)

If you're using manual installation, create the middleware file:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Services\CAS\CasClient;

class CasAuth
{
    public function handle(Request $request, Closure $next)
    {
        $user = session('cas_user');
        $token = session('cas_token');
        
        if (!$user || !$token) {
            // Redirect to CAS login
            $loginUrl = CasClient::getLoginUrl($request->url());
            return redirect($loginUrl);
        }
        
        // Validate token if needed
        if (!CasClient::validateToken($token)) {
            session()->forget(['cas_user', 'cas_token']);
            $loginUrl = CasClient::getLoginUrl($request->url());
            return redirect($loginUrl);
        }
        
        return $next($request);
    }
}

4. Route Protection

Basic Route Protection

// In routes/web.php
Route::middleware(['cas.auth'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::get('/settings', [SettingsController::class, 'index']);
});

Role-Based Protection

// Protect routes with specific roles
Route::middleware(['cas.auth', 'cas.role:admin,manager'])->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
    Route::get('/reports', [ReportsController::class, 'index']);
});

// Single role protection
Route::middleware(['cas.auth', 'cas.role:admin'])->group(function () {
    Route::get('/admin/users', [AdminController::class, 'users']);
});

Authentication Routes

// Authentication routes (add these to your routes/web.php)
Route::get('/cas/login', function () {
    $returnUrl = request('return_url', route('dashboard'));
    $loginUrl = CasClient::getLoginUrl($returnUrl);
    return redirect($loginUrl);
})->name('cas.login');

Route::get('/cas/callback', function () {
    $token = request('token');
    $user = CasClient::validateToken($token);
    
    if ($user) {
        session(['cas_user' => $user, 'cas_token' => $token]);
        return redirect(request('return_url', route('dashboard')));
    }
    
    return redirect()->route('login')->with('error', 'Authentication failed');
})->name('cas.callback');

Route::get('/cas/logout', function () {
    session()->forget(['cas_user', 'cas_token']);
    return redirect('/');
})->name('cas.logout');

5. Code Examples

Controller Example

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use CasSystem\LaravelClient\Facades\CasClient;

class DashboardController extends Controller
{
    public function index()
    {
        $user = session('cas_user');
        $token = session('cas_token');
        
        // You can also get user info directly from CAS
        $userInfo = CasClient::getUserInfo($token);
        
        return view('dashboard', compact('user', 'userInfo'));
    }
    
    public function profile()
    {
        $user = session('cas_user');
        
        // Access user properties
        $username = $user['username'];
        $email = $user['email'];
        $role = $user['role'];
        $firstName = $user['first_name'];
        $lastName = $user['last_name'];
        
        return view('profile', compact('user'));
    }
}

Blade Template Example


@extends('layouts.app')

@section('content')
Dashboard
@if(session('cas_user'))

Welcome, {{ session('cas_user')['first_name'] }}!

Email: {{ session('cas_user')['email'] }}

Role: {{ session('cas_user')['role'] }}

Username: {{ session('cas_user')['username'] }}

@else

Please login to continue.

@endif
@endsection

Service Provider Example

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use CasSystem\LaravelClient\Services\CasClient;

class CasServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(CasClient::class, function ($app) {
            return new CasClient([
                'server_url' => config('cas.server_url'),
                'client_id' => config('cas.client_id'),
                'client_username' => config('cas.client_username'),
                'client_password' => config('cas.client_password'),
                'signature_secret' => config('cas.signature_secret'),
            ]);
        });
    }
}

6. Advanced Usage

Custom User Model

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class CasUser extends Authenticatable
{
    protected $fillable = [
        'username', 'email', 'first_name', 'last_name', 'role'
    ];
    
    public function getFullNameAttribute()
    {
        return $this->first_name . ' ' . $this->last_name;
    }
    
    public function isAdmin()
    {
        return $this->role === 'admin';
    }
    
    public function hasRole($role)
    {
        return $this->role === $role;
    }
}

Token Refresh

<?php

namespace App\Services;

use CasSystem\LaravelClient\Services\CasClient;

class TokenRefreshService
{
    public function refreshToken($currentToken)
    {
        try {
            $newToken = CasClient::refreshToken($currentToken);
            session(['cas_token' => $newToken]);
            return $newToken;
        } catch (\Exception $e) {
            // Token refresh failed, redirect to login
            session()->forget(['cas_user', 'cas_token']);
            throw $e;
        }
    }
}

API Integration

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use CasSystem\LaravelClient\Services\CasClient;

class AuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->only('username', 'password');
        
        try {
            $response = CasClient::authenticate($credentials);
            
            return response()->json([
                'token' => $response['token'],
                'user' => $response['user'],
                'expires_at' => $response['expires_at'],
            ]);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Authentication failed'], 401);
        }
    }
    
    public function validateToken(Request $request)
    {
        $token = $request->bearerToken();
        
        try {
            $user = CasClient::validateToken($token);
            return response()->json(['user' => $user]);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid token'], 401);
        }
    }
}

Troubleshooting

Common Issues

  • Authentication loops: Check your callback URL configuration
  • Token validation fails: Verify your signature secret
  • Session expires quickly: Increase session lifetime in config
  • CORS errors: Add your domain to CAS server's allowed origins