Skip to content

Commit

Permalink
Merge pull request #13 from subfission/xmas-update
Browse files Browse the repository at this point in the history
Xmas update
  • Loading branch information
subfission committed Dec 29, 2015
2 parents 25519bc + 1907d36 commit 6e4b5c7
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 292 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/bootstrap/compiled.php
.env.*.php
.env.php
/tests/CASAuthTest.php
/build
.idea
/composer.lock
/vendor
39 changes: 26 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
# CAS
Simple CAS Authentication for Laravel 5
Simple CAS Authentication for Laravel 5+

This branch is dedicated for PHP7 development as the project will be moving toward that direction. This version
uses the latest phpCAS and supports verbose logging.

This version is a highly modified version of "xavrsl/cas" with specific priority on simplicity and functionality with
Laravel 5. If you are familiar with "xavrsl/cas", then you will find this version very easy to utilize. This package
was built for my neccessity but can be easily used for anyone requiring CAS in Laravel 5.
Laravel 5+. While this will likely still work with older versions, they are untested. This package was built for my
necessity but can be easily used for anyone requiring CAS in Laravel 5. This package is different in mindset as the
goal in this project is to be as minimal as possible while offering as much flexibility as needed.

## Updates
### Added
- Custom SSO Cookie Names
- Middleware for Authentication
- Middleware for redirecting Authenticated Users

### Removed
- CAS SSO Proxy Services
- Multiple CAS connections
* Session handling has been removed from CAS Manager and is moved strictly into the middleware
* You can now leverage the CAS sessions instead of relying on Laravel sessions
* More security fixes
* Cleaner codebase
* Backwards compatible (for the most part)
* More configuration options in the config file available
* Masquerading as a user now supported
* Tested with PHP7


## Installation

Require this package using composer in your Laravel 5 directory :

$ composer require "subfission/cas": "dev-master"
$ composer require "subfission/cas": "dev-cas-php7"

After updating composer, add the ServiceProvider to the providers array in app/config/app.php

Expand All @@ -42,7 +48,7 @@ Configuration
==
Edit the cas.php configuration file after you publish it, with your server's settings.

Configuration should be pretty straightforward for anyone who's ever used the PHPCas client.
Read the comments in the config file for further help.

Usage
==
Expand All @@ -66,6 +72,13 @@ Route::get('/auth/logout', function()
});
```

Then get the current user id this way :
Then get the current user id in one of these ways :

Cas::getCurrentUser();
Cas::user()

Once a user has CAS authenticated, you can also retrieve the user from the session to be used for authorization or
secondary authentication like this :
```php
$user = session('cas_user')
```
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@
"require": {
"php": ">=5.5.0",
"illuminate/support": "5.x",
"jasig/phpcas": "1.3.3"
"jasig/phpcas": "1.3.4"
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"autoload": {
"psr-4": {
"Subfission\\Cas\\": "src/Subfission/Cas/"
}
},
"autoload-dev": {
"psr-4": {
"Subfission\\Cas\\Tests\\": "tests"
}
}
}
29 changes: 29 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="League Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="tap" target="build/report.tap"/>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-html" target="build/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build/coverage.txt"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>
147 changes: 116 additions & 31 deletions src/Subfission/Cas/CasManager.php
Original file line number Diff line number Diff line change
@@ -1,65 +1,150 @@
<?php namespace Subfission\Cas;

use Illuminate\Auth\AuthManager;
use phpCAS;

class CasManager {
class CasManager
{

protected $config;

var $config;
/**
* The active connection instance.
*
* @var string
* @param array $config
*/
protected $connections;
public function __construct(array $config)
{
$this->parseConfig($config);
if ($this->config[ 'cas_debug' ] === true) {
phpCAS::setDebug();
} else {
phpCAS::setDebug($this->config[ 'cas_debug' ]);
}

phpCAS::setVerbose($this->config[ 'cas_verbose_errors' ]);

session_name($this->config[ 'cas_session_name' ]);

$this->configureCas($this->config[ 'cas_proxy' ] ? 'proxy' : 'client');

$this->configureCasValidation();

// set login and logout URLs of the CAS server
phpCAS::setServerLoginURL($this->config[ 'cas_login_url' ]);
phpCAS::setServerLogoutURL($this->config[ 'cas_logout_url' ]);
}

/**
* @var \Illuminate\Auth\AuthManager
* Configure CAS Client|Proxy
* @param $method
*/
private $auth;
protected function configureCas($method = 'client')
{
$server_version = $this->config[ 'cas_enable_saml' ] ? SAML_VERSION_1_1 : CAS_VERSION_2_0;
phpCAS::$method($server_version, $this->config[ 'cas_hostname' ], (int)$this->config[ 'cas_port' ],
$this->config[ 'cas_uri' ], $this->config[ 'cas_control_session' ]);

if ($this->config[ 'cas_enable_saml' ]) {
// Handle SAML logout requests that emanate from the CAS host exclusively.
// Failure to restrict SAML logout requests to authorized hosts could
// allow denial of service attacks where at the least the server is
// tied up parsing bogus XML messages.
phpCAS::handleLogoutRequests(true, explode(',', $this->config[ 'cas_real_hosts' ]));
}
}

/**
* Maintain backwards compatibility with config file
* @param array $config
*/
public function __construct()
protected function parseConfig(array $config)
{
$this->config = config('cas');
$this->auth = app('auth');

$defaults = [
'cas_hostname' => '',
'cas_session_name' => 'CASAuth',
'cas_control_session' => false,
'cas_port' => 443,
'cas_uri' => '/cas',
'cas_validation' => '',
'cas_cert' => '',
'cas_proxy' => false,
'cas_validate_cn' => true,
'cas_login_url' => '',
'cas_logout_url' => 'https://cas.myuniv.edu/cas/logout?service=',
'cas_redirect_path' => 'home',
'cas_enable_saml' => true,
'cas_debug' => false,
'cas_verbose_errors' => false,
'cas_masquerade' => ''
];

$this->config = array_merge($defaults, $config);
}

/**
* Get a Cas connection instance.
* Configure SSL Validation
*
* @param string $name
* @return app\Cas\Directory
* Having some kind of server cert validation in production
* is highly recommended.
*/
public function connection()
protected function configureCasValidation()
{
if ( ! isset($this->connections) )
{
$this->connections = $this->createConnection();
if ($this->config[ 'cas_validation' ] == 'ca' || $this->config[ 'cas_validation' ] == 'self') {
phpCAS::setCasServerCACert($this->config[ 'cas_cert' ], $this->config[ 'cas_validate_cn' ]);
} else {
phpCAS::setNoCasServerValidation();
}

return $this->connections;
}

/**
* Create the given connection by name.
* Authenticates the user based on the current request.
*
* @return app\Cas\Sso
* @return bool
*/
protected function createConnection()
public function authenticate()
{
return new Sso($this->config, $this->auth);
return $this->config[ 'cas_masquerade' ] ? true : phpCAS::forceAuthentication();
}

/**
* Dynamically pass methods to the default connection.
*
* @param string $method
* @param array $parameters
* Retrieve authenticated credentials
* @return string
*/
public function user()
{
return $this->config[ 'cas_masquerade' ] ? : phpCAS::getUser();
}

public function getCurrentUser()
{
return $this->user();
}

public function logout($params)
{
if (phpCAS::isSessionAuthenticated()) {
phpCAS::logout($params);
}
}

/**
* Get the attributes for for the currently connected user. This method
* can only be called after authenticate() or an error wil be thrown.
* @return mixed
*/
public function __call($method, $parameters)
public function getAttributes()
{
return call_user_func_array(array($this->connection(), $method), $parameters);
// We don't error check because phpCAS has it's own error handling
return $this->config[ 'cas_masquerade' ] ? null : phpCAS::getAttributes();
}

/**
* Checks to see is user is authenticated
*
* @return bool
*/
public function isAuthenticated()
{
return phpCAS::isAuthenticated();
}

}
80 changes: 41 additions & 39 deletions src/Subfission/Cas/CasServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,48 @@

use Illuminate\Support\ServiceProvider;

class CasServiceProvider extends ServiceProvider {
class CasServiceProvider extends ServiceProvider
{

/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;

/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../../config/config.php' => config_path('cas.php'),
]);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bindShared('cas', function()
{
return new CasManager();
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('cas');
}
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__ . '/../../config/config.php' => config_path('cas.php'),
]);
}

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bindShared('cas', function () {
return new CasManager(config('cas'));
});
}

/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('cas');
}

}
Loading

0 comments on commit 6e4b5c7

Please sign in to comment.