Revision: 2278
Author: [email protected]
Date: Tue May 4 04:05:44 2010
Log: Scoping for authsources. Includes support for IDPList, ProxyCount,
AuthenticatingAuthority and RequesterID.
http://code.google.com/p/simplesamlphp/source/detail?r=2278
Modified:
/trunk/docs/simplesamlphp-sp-api.txt
/trunk/lib/SAML2/Assertion.php
/trunk/lib/SAML2/AuthnRequest.php
/trunk/lib/SAML2/Const.php
/trunk/lib/SimpleSAML/IdP.php
/trunk/modules/saml/docs/sp.txt
/trunk/modules/saml/lib/Auth/Source/SP.php
/trunk/modules/saml/lib/IdP/SAML2.php
/trunk/modules/saml/www/sp/saml2-acs.php
/trunk/modules/saml2/lib/Error.php
=======================================
--- /trunk/docs/simplesamlphp-sp-api.txt Mon Mar 8 04:41:15 2010
+++ /trunk/docs/simplesamlphp-sp-api.txt Tue May 4 04:05:44 2010
@@ -105,7 +105,7 @@
# Send a passive authentication request.
$auth->login(array(
- 'saml:IsPassive' => TRUE,
+ 'isPassive' => TRUE,
'ErrorURL' => 'https://.../error_handler.php',
));
=======================================
--- /trunk/lib/SAML2/Assertion.php Fri Mar 5 07:12:33 2010
+++ /trunk/lib/SAML2/Assertion.php Tue May 4 04:05:44 2010
@@ -131,6 +131,13 @@
*/
private $authnContext;
+ /**
+ * The list of AuthenticatingAuthorities for this assertion.
+ *
+ * @var array
+ */
+ private $AuthenticatingAuthority;
+
/**
* The attributes, as an associative array.
@@ -192,6 +199,7 @@
$this->attributes = array();
$this->nameFormat = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
$this->certificates = array();
+ $this->AuthenticatingAuthority = array();
if ($xml === NULL) {
return;
@@ -416,6 +424,8 @@
} else {
$this->authnContext = trim($accr[0]->textContent);
}
+
+ $this->AuthenticatingAuthority =
SAML2_Utils::extractStrings($ac, './saml_assertion:AuthenticatingAuthority');
}
@@ -872,6 +882,29 @@
$this->authnContext = $authnContext;
}
+
+
+ /**
+ * Retrieve the AuthenticatingAuthority.
+ *
+ *
+ * @return array
+ */
+ public function getAuthenticatingAuthority() {
+
+ return $this->AuthenticatingAuthority;
+ }
+
+
+ /**
+ * Set the AuthenticatingAuthority
+ *
+ *
+ * @param array.
+ */
+ public function setAuthenticatingAuthority($AuthenticatingAuthority) {
+ $this->AuthenticatingAuthority = $AuthenticatingAuthority;
+ }
/**
@@ -1105,6 +1138,7 @@
$as->appendChild($ac);
SAML2_Utils::addString($ac,
SAML2_Const::NS_SAML, 'saml:AuthnContextClassRef', $this->authnContext);
+ SAML2_Utils::addStrings($ac,
SAML2_Const::NS_SAML, 'saml:AuthenticatingAuthority', false,
$this->AuthenticatingAuthority);
}
=======================================
--- /trunk/lib/SAML2/AuthnRequest.php Fri Mar 5 07:12:21 2010
+++ /trunk/lib/SAML2/AuthnRequest.php Tue May 4 04:05:44 2010
@@ -37,6 +37,21 @@
*/
private $IDPList = array();
+ /**
+ * The ProxyCount in this request's scoping element
+ *
+ * @var int
+ */
+ private $ProxyCount = null;
+
+ /**
+ * The RequesterID list in this request's scoping element
+ *
+ * @var array
+ */
+
+ private $RequesterID = array();
+
/**
* The URL of the asertion consumer service where the response should be
delivered.
*
@@ -128,13 +143,27 @@
$this->requestedAuthnContext = $rac;
}
- $idpEntries =
SAML2_Utils::xpQuery($xml, './saml_protocol:Scoping/saml_protocol:IDPList/saml_protocol:IDPEntry');
-
- foreach($idpEntries as $idpEntry) {
- if (!$idpEntry->hasAttribute('ProviderID')) {
- throw new Exception("Could not get ProviderID from Scoping/IDPEntry
element in AuthnRequest object");
- }
- $this->IDPList[] =
$idpEntry->getAttribute('ProviderID');
+ $scoping = SAML2_Utils::xpQuery($xml,
'./saml_protocol:Scoping');
+ if (!empty($scoping)) {
+ $scoping =$scoping[0];
+
+ if ($scoping->hasAttribute('ProxyCount')) {
+ $this->ProxyCount =
(int)$scoping->getAttribute('ProxyCount');
+ }
+ $idpEntries =
SAML2_Utils::xpQuery($scoping, './saml_protocol:IDPList/saml_protocol:IDPEntry');
+
+ foreach($idpEntries as $idpEntry) {
+ if (!$idpEntry->hasAttribute('ProviderID')) {
+ throw new Exception("Could not get ProviderID from Scoping/IDPEntry
element in AuthnRequest object");
+ }
+ $this->IDPList[] =
$idpEntry->getAttribute('ProviderID');
+ }
+
+ $requesterIDs =
SAML2_Utils::xpQuery($scoping, './saml_protocol:RequesterID');
+ foreach ($requesterIDs as $requesterID) {
+ $this->RequesterID[] =
trim($requesterID->textContent);
+ }
+
}
}
@@ -234,6 +263,22 @@
return $this->IDPList;
}
+ public function setProxyCount($ProxyCount) {
+ assert('is_int($ProxyCount)');
+ $this->ProxyCount = $ProxyCount;
+ }
+
+ public function getProxyCount() {
+ return $this->ProxyCount;
+ }
+
+ public function setRequesterID(array $RequesterID) {
+ $this->RequesterID = $RequesterID;
+ }
+
+ public function getRequesterID() {
+ return $this->RequesterID;
+ }
/**
* Retrieve the value of the AssertionConsumerServiceURL attribute.
@@ -352,16 +397,25 @@
}
}
- if (count($this->IDPList) > 0) {
+
+ if ($this->ProxyCount !== null || count($this->IDPList) > 0 ||
count($this->RequesterID) > 0) {
$scoping =
$this->document->createElementNS(SAML2_Const::NS_SAMLP, 'Scoping');
- $idplist =
$this->document->createElementNS(SAML2_Const::NS_SAMLP, 'IDPList');
- foreach ($this->IDPList as $provider) {
- $idpEntry =
$this->document->createElementNS(SAML2_Const::NS_SAMLP, 'IDPEntry');
- $idpEntry->setAttribute('ProviderID',
$provider);
- $idplist->appendChild($idpEntry);
- }
- $scoping->appendChild($idplist);
- $root->appendChild($scoping);
+ if ($this->ProxyCount !== null) {
+ $scoping->setAttribute('ProxyCount',
$this->ProxyCount);
+ }
+ if (count($this->IDPList) > 0) {
+ $idplist =
$this->document->createElementNS(SAML2_Const::NS_SAMLP, 'IDPList');
+ foreach ($this->IDPList as $provider) {
+ $idpEntry =
$this->document->createElementNS(SAML2_Const::NS_SAMLP, 'IDPEntry');
+ $idpEntry->setAttribute('ProviderID',
$provider);
+ $idplist->appendChild($idpEntry);
+ }
+ $scoping->appendChild($idplist);
+ $root->appendChild($scoping);
+ }
+ if (count($this->RequesterID) > 0) {
+ SAML2_Utils::addStrings($scoping,
SAML2_Const::NS_SAMLP, 'RequesterID', FALSE, $this->RequesterID);
+ }
}
return $root;
=======================================
--- /trunk/lib/SAML2/Const.php Fri Mar 5 07:11:27 2010
+++ /trunk/lib/SAML2/Const.php Tue May 4 04:05:44 2010
@@ -135,6 +135,12 @@
*/
const STATUS_PARTIAL_LOGOUT
= 'urn:oasis:names:tc:SAML:2.0:status:PartialLogout';
+ /**
+ * Second-level status code for ProxyCountExceeded.
+ */
+ const STATUS_PROXY_COUNT_EXCEEDED
= 'urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded';
+
+
}
?>
=======================================
--- /trunk/lib/SimpleSAML/IdP.php Wed Apr 28 01:16:14 2010
+++ /trunk/lib/SimpleSAML/IdP.php Tue May 4 04:05:44 2010
@@ -393,6 +393,8 @@
if (isset($state['ForceAuthn']) && (bool)$state['ForceAuthn']) {
/* Force authentication is in effect. */
$needAuth = TRUE;
+ } elseif (isset($state['saml:IDPList']) &&
sizeof($state['saml:IDPList']) > 0) {
+ $needAuth = TRUE;
} else {
$needAuth = !$this->isAuthenticated();
}
=======================================
--- /trunk/modules/saml/docs/sp.txt Thu Mar 18 06:10:18 2010
+++ /trunk/modules/saml/docs/sp.txt Tue May 4 04:05:44 2010
@@ -22,7 +22,7 @@
: *Note*: SAML 2 specific.
-`saml:ForceAuthn`
+`ForceAuthnn`
: Force authentication allows you to force re-authentication of users
even if the user has a SSO session at the IdP.
: *Note*: SAML 2 specific.
@@ -30,7 +30,7 @@
`saml:idp`
: The entity ID of the IdP we should send an authentication request to.
-`saml:IsPassive`
+`isPassive`
: Send a passive authentication request.
: *Note*: SAML 2 specific.
=======================================
--- /trunk/modules/saml/lib/Auth/Source/SP.php Fri Mar 19 00:57:53 2010
+++ /trunk/modules/saml/lib/Auth/Source/SP.php Tue May 4 04:05:44 2010
@@ -175,6 +175,10 @@
* @param array $state The state array for the current authentication.
*/
private function startSSO2(SimpleSAML_Configuration $idpMetadata, array
$state) {
+
+ if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount']
< 0) {
+ SimpleSAML_Auth_State::throwException($state, new
SimpleSAML_Error_ProxyCountExceeded("ProxyCountExceeded"));
+ }
$ar = sspmod_saml2_Message::buildAuthnRequest($this->metadata,
$idpMetadata);
@@ -190,12 +194,12 @@
$ar->setRequestedAuthnContext(array('AuthnContextClassRef'
=> $accr));
}
- if (isset($state['saml:ForceAuthn'])) {
- $ar->setForceAuthn((bool)$state['saml:ForceAuthn']);
+ if (isset($state['ForceAuthnn'])) {
+ $ar->setForceAuthn((bool)$state['ForceAuthn']);
}
- if (isset($state['saml:IsPassive'])) {
- $ar->setIsPassive((bool)$state['saml:IsPassive']);
+ if (isset($state['isPassive'])) {
+ $ar->setIsPassive((bool)$state['isPassive']);
}
if (isset($state['saml:NameIDPolicy'])) {
@@ -205,12 +209,37 @@
));
}
-
+ if (isset($state['saml:IDPList'])) {
+ $IDPList = $state['saml:IDPList'];
+ }
+
+
$ar->setIDPList(array_unique(array_merge($this->metadata->getArray('IDPList',
array()),
+
$idpMetadata->getArray('IDPList', array()),
+
(array) $IDPList)));
+
+ if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !==
null) {
+ $ar->setProxyCount($state['saml:ProxyCount']);
+ } elseif ($idpMetadata->getInteger('ProxyCount', null) !==
null) {
+
$ar->setProxyCount($idpMetadata->getInteger('ProxyCount', null));
+ } elseif ($this->metadata->getInteger('ProxyCount', null) !==
null) {
+
$ar->setProxyCount($this->metadata->getInteger('ProxyCount', null));
+ }
+
+ $requesterID = array();
+ if (isset($state['saml:RequesterID'])) {
+ $requesterID = $state['saml:RequesterID'];
+ }
+
+ if (isset($state['core:SP'])) {
+ $requesterID[] = $state['core:SP'];
+ }
+
+ $ar->setRequesterID($requesterID);
+
$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso',
TRUE);
$ar->setId($id);
SimpleSAML_Logger::debug('Sending SAML 2 AuthnRequest to ' .
var_export($idpMetadata->getString('entityid'), TRUE));
-
$b = new SAML2_HTTPRedirect();
$b->setDestination(sspmod_SAML2_Message::getDebugDestination());
$b->send($ar);
@@ -290,6 +319,10 @@
if (isset($state['saml:idp'])) {
$idp = (string)$state['saml:idp'];
}
+
+ if ($idp === NULL && isset($state['saml:IDPList']) &&
sizeof($state['saml:IDPList']) == 1) {
+ $idp = $state['saml:IDPList'][0];
+ }
if ($idp === NULL) {
$this->startDisco($state);
@@ -374,7 +407,7 @@
assert('is_string($idp)');
assert('array_key_exists("LogoutState", $state)');
assert('array_key_exists("saml:logout:Type",
$state["LogoutState"])');
-
+
$idpMetadata = $this->getIdpMetadata($idp);
$spMetadataArray = $this->metadata->toArray();
=======================================
--- /trunk/modules/saml/lib/IdP/SAML2.php Tue Apr 20 05:51:38 2010
+++ /trunk/modules/saml/lib/IdP/SAML2.php Tue May 4 04:05:44 2010
@@ -48,6 +48,10 @@
$assertion = sspmod_saml2_Message::buildAssertion($idpMetadata,
$spMetadata, $attributes, $consumerURL);
$assertion->setInResponseTo($requestId);
+
+ if (isset($state['saml:AuthenticatingAuthority'])) {
+
$assertion->setAuthenticatingAuthority($state['saml:AuthenticatingAuthority']);
+ }
/* Create the session association (for logout). */
$association = array(
@@ -242,6 +246,9 @@
$requestId = $request->getId();
$IDPList = $request->getIDPList();
+ $ProxyCount = $request->getProxyCount();
+ if ($ProxyCount !== null) $ProxyCount--;
+ $RequesterID = $request->getRequesterID();
$forceAuthn = $request->getForceAuthn();
$isPassive = $request->getIsPassive();
$consumerURL =
$request->getAssertionConsumerServiceURL();
@@ -285,6 +292,7 @@
}
$IDPList = array_unique(array_merge($IDPList,
$spMetadata->getArrayizeString('IDPList', array())));
+ if ($ProxyCount == null) $ProxyCount =
$spMetadata->getInteger('ProxyCount', null);
if (!$forceAuthn) {
$forceAuthn = $spMetadata->getBoolean('ForceAuthn',
FALSE);
@@ -311,7 +319,9 @@
'saml:RelayState' => $relayState,
'saml:RequestId' => $requestId,
'saml:IDPList' => $IDPList,
- 'ForceAuthn' => $forceAuthn,
+ 'saml:ProxyCount' => $ProxyCount,
+ 'saml:RequesterID' => $RequesterID,
+ 'ForceAuthnn' => $forceAuthn,
'isPassive' => $isPassive,
'saml:ConsumerURL' => $consumerURL,
'saml:Binding' => $protocolBinding,
=======================================
--- /trunk/modules/saml/www/sp/saml2-acs.php Thu Feb 11 05:45:40 2010
+++ /trunk/modules/saml/www/sp/saml2-acs.php Tue May 4 04:05:44 2010
@@ -31,7 +31,6 @@
'saml:sp:RelayState' => $response->getRelayState(),
);
}
-
$idp = $response->getIssuer();
if ($idp === NULL) {
@@ -63,6 +62,9 @@
'saml:logout:SessionIndex' => $sessionIndex,
);
$state['LogoutState'] = $logoutState;
+$state['saml:AuthenticatingAuthority'] =
$assertion->getAuthenticatingAuthority();
+$state['saml:AuthenticatingAuthority'][] = $idp;
+$state['PersistentAuthData'][] = 'saml:AuthenticatingAuthority';
$source->handleResponse($state, $idp, $assertion->getAttributes());
assert('FALSE');
=======================================
--- /trunk/modules/saml2/lib/Error.php Mon Aug 3 05:44:26 2009
+++ /trunk/modules/saml2/lib/Error.php Tue May 4 04:05:44 2010
@@ -112,6 +112,13 @@
$exception->getMessage(),
$exception
);
+ } elseif ($exception instanceof
SimpleSAML_Error_ProxyCountExceeded) {
+ $e = new self(
+ SAML2_Const::STATUS_RESPONDER,
+ SAML2_Const::STATUS_PROXY_COUNT_EXCEEDED,
+ $exception->getMessage(),
+ $exception
+ );
} else {
$e = new self(
--
You received this message because you are subscribed to the Google Groups
"simpleSAMLphp commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/simplesamlphp-commits?hl=en.