diff --git a/modules/saml/docs/nameid.txt b/modules/saml/docs/nameid.txt index 5da34e0f8e2dd22b39695d5ce39810823f337b90..fc5072f696ed22f19940bc02c7e18625c25868d4 100644 --- a/modules/saml/docs/nameid.txt +++ b/modules/saml/docs/nameid.txt @@ -69,13 +69,25 @@ This filter generates and stores a persistent NameID in a SQL datastore. To use this filter, simpleSAMLphp must be configured to use a SQL datastore. See the `store.type` configuration option in `config.php`. -This filter will only create new NameIDs when the SP specifies `AllowCreate="true"` in the authentication request. - ### Options `attribute` : The name of the attribute we should use as the unique user ID. +`allowUnspecified` +: Whether a persistent NameID should be created if the SP does not specify any NameID format in the request. + The default is `FALSE`. + +`allowDifferent` +: Whether a persistent NameID should be created if there are only other NameID formats specified in the request or the SP's metadata. + The default is `FALSE`. + +`alwaysCreate` +: Whether to ignore an explicit `AllowCreate="false"` in the authentication request's NameIDPolicy. + The default is `FALSE`, which will only create new NameIDs when the SP specifies `AllowCreate="true"` in the authentication request. + +Setting both `allowUnspecified` and `alwaysCreate` to `TRUE` causes `saml:SQLPersistentNameID` to behave like `saml:PersistentNameID` (and other NameID generation filters), at the expense of creating unnecessary entries in the SQL datastore. + `saml:PersistentNameID2TargetedID` ---------------------------------- diff --git a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php index 767aec324cf8c5bee6d82cee812113e6daec5bd4..7b220f637b3dcc9a06dfba637991b2790f55a2d3 100644 --- a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php +++ b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php @@ -14,6 +14,27 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI */ private $attribute; + /** + * Whether we should create a persistent NameID if not explicitly requested (as saml:PersistentNameID does). + * + * @var boolean + */ + private $allowUnspecified; + + /** + * Whether we should create a persistent NameID if a different format is requested. + * + * @var boolean + */ + private $allowDifferent; + + /** + * Whether we should ignore allowCreate in the NameID policy + * + * @var boolean + */ + private $alwaysCreate; + /** * Initialize this filter, parse configuration. @@ -31,6 +52,24 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI throw new SimpleSAML_Error_Exception('PersistentNameID: Missing required option \'attribute\'.'); } $this->attribute = $config['attribute']; + + if (isset($config['allowUnspecified'])) { + $this->allowUnspecified = (bool)$config['allowUnspecified']; + } else { + $this->allowUnspecified = FALSE; + } + + if (isset($config['allowDifferent'])) { + $this->allowDifferent = (bool)$config['allowDifferent']; + } else { + $this->allowDifferent = FALSE; + } + + if (isset($config['alwaysCreate'])) { + $this->alwaysCreate = (bool)$config['alwaysCreate']; + } else { + $this->alwaysCreate = FALSE; + } } @@ -41,11 +80,17 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI */ protected function getValue(array &$state) { - if (!isset($state['saml:NameIDFormat']) || $state['saml:NameIDFormat'] !== $this->format) { + if (!isset($state['saml:NameIDFormat']) && !$this->allowUnspecified) { SimpleSAML_Logger::debug('SQLPersistentNameID: Request did not specify persistent NameID format - not generating persistent NameID.'); return NULL; } + $validNameIdFormats = @array_filter(array($state['saml:NameIDFormat'], $state['SPMetadata']['NameIDPolicy'], $state['SPMetadata']['NameIDFormat'])); + if (count($validNameIdFormats) && !in_array($this->format, $validNameIdFormats) && !$this->allowDifferent) { + SimpleSAML_Logger::debug('SQLPersistentNameID: SP expects different NameID format (' . implode(', ', $validNameIdFormats) . ') - not generating persistent NameID.'); + return NULL; + } + if (!isset($state['Destination']['entityid'])) { SimpleSAML_Logger::warning('SQLPersistentNameID: No SP entity ID - not generating persistent NameID.'); return NULL; @@ -76,7 +121,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI return $value; } - if (!isset($state['saml:AllowCreate']) || !$state['saml:AllowCreate']) { + if ((!isset($state['saml:AllowCreate']) || !$state['saml:AllowCreate']) && !$this->alwaysCreate) { SimpleSAML_Logger::warning('SQLPersistentNameID: Did not find persistent NameID for user, and not allowed to create new NameID.'); throw new sspmod_saml_Error(SAML2_Const::STATUS_RESPONDER, 'urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy'); }