Skip to content
Snippets Groups Projects

added whitelisting to ProxyFilter

Merged Pavel Břoušek requested to merge github/fork/melanger/whitelistProxyFilter into master
2 files
+ 66
25
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -9,9 +9,10 @@ use SimpleSAML\Configuration;
/**
* Class sspmod_perun_Auth_Process_ProxyFilter
*
* This filter allows to disable nested filter for particular SP
* or for users with one of (black)listed attribute values.
* When any of the values matches, the nested filter is NOT run.
* This filter allows to disable/enable nested filter for particular SP
* or for users with one of (black/white)listed attribute values.
* Based on the mode of operation, the nested filter
* IS (whitelist) or IS NOT (blacklist) run when any of the attribute values matches.
* SPs are defined by theirs entityID in property 'filterSPs'.
* User attributes are defined as a map 'attrName'=>['value1','value2']
* in property 'filterAttributes'.
@@ -30,17 +31,33 @@ use SimpleSAML\Configuration;
* 'class' => 'perun:NestedFilter',
* // ...
* ],
* ]
* ],
* 20 => [
* 'class' => 'perun:ProxyFilter',
* 'mode' => 'whitelist',
* 'filterSPs' => ['enableSpEntityId01', 'enableSpEntityId02'],
* 'config' => [
* 'class' => 'perun:NestedFilter',
* // ...
* ],
* ],
*
* @author Ondrej Velisek <ondrejvelisek@gmail.com>
*/
class ProxyFilter extends \SimpleSAML\Auth\ProcessingFilter
{
public const MODE_BLACKLIST = 'blacklist';
public const MODE_WHITELIST = 'whitelist';
public const MODES = [
self::MODE_BLACKLIST,
self::MODE_WHITELIST,
];
private $config;
private $nestedClass;
private $filterSPs;
private $filterAttributes;
private $mode;
private $reserved;
public function __construct($config, $reserved)
@@ -53,6 +70,7 @@ class ProxyFilter extends \SimpleSAML\Auth\ProcessingFilter
unset($this->config['class']);
$this->filterSPs = $conf->getArray('filterSPs', []);
$this->filterAttributes = $conf->getArray('filterAttributes', []);
$this->mode = $conf->getValueValidate('mode', self::MODES, self::MODE_BLACKLIST);
$this->reserved = (array)$reserved;
}
@@ -61,42 +79,63 @@ class ProxyFilter extends \SimpleSAML\Auth\ProcessingFilter
{
assert(is_array($request));
foreach ($this->filterAttributes as $attr => $values) {
if (!isset($request['Attributes'][$attr]) || !is_array($request['Attributes'][$attr])) {
continue;
}
foreach ($values as $value) {
if (in_array($value, $request['Attributes'][$attr])) {
Logger::info(
sprintf(
'perun.ProxyFilter: Filtering out filter %s because %s contains %s',
$this->nestedClass,
$attr,
$value
)
);
$default = $this->mode === self::MODE_BLACKLIST;
$shouldRun = $this->shouldRunForSP($request['Destination']['entityid'], $default);
if ($shouldRun === $default) {
$shouldRun = $this->shouldRunForAttribute($request['Attributes'], $default);
}
return;
}
}
if ($shouldRun) {
$this->runAuthProcFilter($request);
}
}
private function shouldRunForSP($currentSp, $default)
{
foreach ($this->filterSPs as $sp) {
$currentSp = $request['Destination']['entityid'];
if ($sp === $currentSp) {
$shouldRun = !$default;
Logger::info(
sprintf(
'perun.ProxyFilter: Filtering out filter %s for SP %s',
'perun.ProxyFilter: %s filter %s for SP %s',
$shouldRun ? 'Running' : 'Filtering out',
$this->nestedClass,
$currentSp
)
);
return $shouldRun;
}
}
return $default;
}
return;
private function shouldRunForAttribute($attributes, $default)
{
foreach ($this->filterAttributes as $attr => $values) {
if (isset($attributes[$attr]) && is_array($attributes[$attr])) {
foreach ($values as $value) {
if (in_array($value, $attributes[$attr])) {
$shouldRun = !$default;
Logger::info(
sprintf(
'perun.ProxyFilter: %s filter %s because %s contains %s',
$shouldRun ? 'Running' : 'Filtering out',
$this->nestedClass,
$attr,
$value
)
);
return $shouldRun;
}
}
}
}
return $default;
}
list($module, $simpleClass) = explode(":", $this->nestedClass);
private function runAuthProcFilter(&$request)
{
list($module, $simpleClass) = explode(':', $this->nestedClass);
$className = '\SimpleSAML\Module\\' . $module . '\Auth\Process\\' . $simpleClass;
$authFilter = new $className($this->config, $this->reserved);
$authFilter->process($request);
Loading