X Tutup
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions modules/core/docs/authproc_attributelimit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ metadata. The configuration is a list of attributes that should be allowed. In c
release some specific values, make the name of the attribute the key of the array, and its value an array with all the
different values allowed for it.

You may need to send special bilateral, or local attributes to a set of SPs that are not specified in SP's metadata.
In this case you can list the SPs then add the name of the attributes to send these SPs, or you can list the attributes and then specify the SPs to send them.
Find the examples below.

Examples
--------

Expand Down Expand Up @@ -91,3 +95,22 @@ values ever reach the service providers. Bear in mind that this configuration ca
'affiliate',
),
),

Send attributes to an SP that are not specified in the SPs metadata.

'authproc' => array(
50 => 'core:AttributeLimit',
'allowedAttributes' => array(),
'bilateralSPs' => array(
'entityid1' => array(
'mail',
'local-mail'
)
),
'bilateralAttributes' => array(
'localFooId' => array(
'entityid1',
'entityid2'
)
)
),
244 changes: 148 additions & 96 deletions modules/core/lib/Auth/Process/AttributeLimit.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,124 +4,176 @@
* A filter for limiting which attributes are passed on.
*
* @author Olav Morken, UNINETT AS.
* @author Kristóf Bajnok, NIIF
* @author Tamás Frank, NIIF
* @author Gyula Szabó, NIIF
* @package SimpleSAMLphp
*/
class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_ProcessingFilter {

/**
* List of attributes which this filter will allow through.
*/
private $allowedAttributes = array();


/**
* Whether the 'attributes' option in the metadata takes precedence.
*
* @var bool
*/
private $isDefault = FALSE;


/**
* Initialize this filter.
*
* @param array $config Configuration information about this filter.
* @param mixed $reserved For future use
/**
* List of attributes which this filter will allow through.
*/
private $allowedAttributes = array();

/**
* Array of sp attributes arrays which this filter will allow through.
*/
private $bilateralSPs = array();

/**
* Array of attribute sps arrays which this filter will allow through.
*/
private $bilateralAttributes = array();

/**
* Whether the 'attributes' option in the metadata takes precedence.
*
* @var bool
*/
private $isDefault = false;


/**
* Initialize this filter.
*
* @param array $config Configuration information about this filter.
* @param mixed $reserved For future use
* @throws SimpleSAML_Error_Exception If invalid configuration is found.
*/
public function __construct($config, $reserved) {
parent::__construct($config, $reserved);

assert('is_array($config)');

foreach ($config as $index => $value) {
if ($index === 'default') {
$this->isDefault = (bool)$value;
} elseif (is_int($index)) {
if (!is_string($value)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid attribute name: ' .
var_export($value, TRUE));
}
$this->allowedAttributes[] = $value;
*/
public function __construct($config, $reserved)
{
parent::__construct($config, $reserved);

assert('is_array($config)');

foreach ($config as $index => $value) {
if ($index === 'default') {
$this->isDefault = (bool)$value;
} elseif (is_int($index)) {
if (!is_string($value)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid attribute name: ' .
var_export($value, true));
}
$this->allowedAttributes[] = $value;
} elseif ($index === 'bilateralSPs') {
if (! is_array($value)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid option bilateralSPs: must be specified in an array: ' . var_export($index, true));
}
foreach ($value as $valuearray) {
if (! is_array($valuearray)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: An invalid value in option bilateralSPs: must be specified in an array: ' . var_export($value, true));
}
}
$this->bilateralSPs = $value;
} elseif ($index === 'bilateralAttributes') {
if (! is_array($value)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid option bilateralAttributes: must be specified in an array: ' . var_export($index, true));
}
foreach ($value as $valuearray) {
if (! is_array($valuearray)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: An invalid value in option bilateralAttributes: must be specified in an array: ' . var_export($value, true));
}
}
$this->bilateralAttributes = $value;
} elseif (is_string($index)) {
if (!is_array($value)) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($index, TRUE) .
throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($index, true) .
' must be specified in an array.');
}
$this->allowedAttributes[$index] = $value;
} else {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid option: ' . var_export($index, TRUE));
}
}
}


/**
* Get list of allowed from the SP/IdP config.
*
* @param array &$request The current request.
* @return array|NULL Array with attribute names, or NULL if no limit is placed.
*/
private static function getSPIdPAllowed(array &$request) {

if (array_key_exists('attributes', $request['Destination'])) {
// SP Config
return $request['Destination']['attributes'];
}
if (array_key_exists('attributes', $request['Source'])) {
// IdP Config
return $request['Source']['attributes'];
}
return NULL;
}


/**
* Apply filter to remove attributes.
*
* Removes all attributes which aren't one of the allowed attributes.
*
* @param array &$request The current request
} else {
throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid option: ' . var_export($index, true));
}
}
}


/**
* Get list of allowed from the SP/IdP config.
*
* @param array &$request The current request.
* @return array|NULL Array with attribute names, or NULL if no limit is placed.
*/
private static function getSPIdPAllowed(array &$request)
{

if (array_key_exists('attributes', $request['Destination'])) {
// SP Config
return $request['Destination']['attributes'];
}
if (array_key_exists('attributes', $request['Source'])) {
// IdP Config
return $request['Source']['attributes'];
}
return null;
}


/**
* Apply filter to remove attributes.
*
* Removes all attributes which aren't one of the allowed attributes.
*
* @param array &$request The current request
* @throws SimpleSAML_Error_Exception If invalid configuration is found.
*/
public function process(&$request) {
assert('is_array($request)');
assert('array_key_exists("Attributes", $request)');

if ($this->isDefault) {
$allowedAttributes = self::getSPIdPAllowed($request);
if ($allowedAttributes === NULL) {
$allowedAttributes = $this->allowedAttributes;
}
} elseif (!empty($this->allowedAttributes)) {
$allowedAttributes = $this->allowedAttributes;
} else {
$allowedAttributes = self::getSPIdPAllowed($request);
if ($allowedAttributes === NULL) {
return; /* No limit on attributes. */
}
}

$attributes =& $request['Attributes'];

foreach ($attributes as $name => $values) {
if (!in_array($name, $allowedAttributes, TRUE)) {
*/
public function process(&$request)
{
assert('is_array($request)');
assert('array_key_exists("Attributes", $request)');

if ($this->isDefault) {
$allowedAttributes = self::getSPIdPAllowed($request);
if ($allowedAttributes === null) {
$allowedAttributes = $this->allowedAttributes;
}
} elseif (!empty($this->allowedAttributes)) {
$allowedAttributes = $this->allowedAttributes;
} else {
$allowedAttributes = self::getSPIdPAllowed($request);
if ($allowedAttributes === null) {
return; /* No limit on attributes. */
}
}

$attributes =& $request['Attributes'];

if (!empty($this->bilateralSPs) || !empty($this->bilateralAttributes)) {
$entityid = $request['Destination']['entityid'];
}

foreach ($attributes as $name => $values) {
if (!in_array($name, $allowedAttributes, true)) {
// the attribute name is not in the array of allowed attributes
if (array_key_exists($name, $allowedAttributes)) {
// but it is an index of the array
if (!is_array($allowedAttributes[$name])) {
throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($name, TRUE) .
throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($name, true) .
' must be specified in an array.');
}
$attributes[$name] = array_intersect($attributes[$name], $allowedAttributes[$name]);
if (!empty($attributes[$name])) {
continue;
}
}
if (!empty($this->bilateralSPs)) {
if (array_key_exists($entityid, $this->bilateralSPs)
&& in_array($name, $this->bilateralSPs[$entityid])
) {
continue;
}
}
if (!empty($this->bilateralAttributes)) {
if (array_key_exists($name, $this->bilateralAttributes)
&& in_array($entityid, $this->bilateralAttributes[$name])
) {
continue;
}
}
unset($attributes[$name]);
}
}

}
}
}

}
}
Loading
X Tutup