17 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_sp.inc';
40 protected $authSource;
49 $this->authSource = $authSource;
50 parent::__construct($authSource);
73 public function login(array $params = array()) {
75 if (array_key_exists(
'KeepPost', $params)) {
76 $keepPost = (bool)$params[
'KeepPost'];
81 if (array_key_exists(
'ReturnTo', $params)) {
82 $returnTo = (string)$params[
'ReturnTo'];
83 }
else if (array_key_exists(
'ReturnCallback', $params)) {
84 $returnTo = (array)$params[
'ReturnCallback'];
86 $returnTo = current_url();
89 if (is_string($returnTo) && $keepPost && $_SERVER[
'REQUEST_METHOD'] ===
'POST') {
90 $returnTo = SimpleSAML_Utilities::createPostRedirectLink($returnTo, $_POST);
93 if (array_key_exists(
'ErrorURL', $params)) {
94 $errorURL = (string)$params[
'ErrorURL'];
100 if (!isset($params[SimpleSAML_Auth_State::RESTART]) && is_string($returnTo)) {
105 $restartURL = $this->getLoginURL($returnTo);
106 $params[SimpleSAML_Auth_State::RESTART] = $restartURL;
109 $authId = $this->authSource;
111 $state = array_merge($params, array(
112 'SimpleSAML_Auth_Default.id' => $authId,
113 'SimpleSAML_Auth_Default.Return' => $returnTo,
114 'SimpleSAML_Auth_Default.ErrorURL' => $errorURL,
115 'LoginCompletedHandler' => array(
'SimpleSAML_Auth_Default',
'loginCompleted'),
116 'LogoutCallback' => array(get_class(),
'logoutCallback'),
117 'LogoutCallbackState' => array(
118 'SimpleSAML_Auth_Default.logoutSource' => $authId,
123 if ($errorURL !== NULL) {
124 $state[SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL] = $errorURL;
127 $config = SimpleSAML_Configuration::getConfig(
'authsources.php');
128 $authConfig = $config->getArray($authId, NULL);
133 throw new Exception(
'Invalid authentication source: ' . $authId);
137 $as->authenticate($state);
138 }
catch (SimpleSAML_Error_Exception $e) {
139 SimpleSAML_Auth_State::throwException($state, $e);
140 }
catch (Exception $e) {
141 $e =
new SimpleSAML_Error_UnserializableException($e);
142 SimpleSAML_Auth_State::throwException($state, $e);
145 SimpleSAML_Auth_Default::loginCompleted($state);
171 assert(
'is_array($params) || is_string($params) || is_null($params)');
173 if (empty($params)) {
174 $params = current_url();
177 if (is_string($params)) {
179 'ReturnTo' => $params,
185 assert(
'is_array($params)');
186 assert(
'isset($params["ReturnTo"]) || isset($params["ReturnCallback"])');
188 if (isset($params[
'ReturnStateParam']) || isset($params[
'ReturnStateStage'])) {
189 assert(
'isset($params["ReturnStateParam"]) && isset($params["ReturnStateStage"])');
192 $session = SimpleSAML_Session::getInstance();
193 if ($session->isValid($this->authSource)) {
194 $state = $session->getAuthData($this->authSource,
'LogoutState');
195 if ($state !== NULL) {
196 $params = array_merge($state, $params);
199 $session->doLogout($this->authSource);
201 $params[
'LogoutCompletedHandler'] = array(get_class(),
'logoutCompleted');
203 $authId = $this->authSource;
204 $config = SimpleSAML_Configuration::getConfig(
'authsources.php');
205 $authConfig = $config->getArray($authId, NULL);
211 $as->logout($params);
215 self::logoutCompleted($params);
232 $sourceId = $this->authSource;
234 $config = SimpleSAML_Configuration::getInstance();
236 $authConfig = SimpleSAML_Configuration::getConfig(
'authsources.php');
237 $authConfig = $authConfig->getArray($sourceId, NULL);
240 if ($source === NULL) {
241 throw new SimpleSAML_Error_NotFound(
'Could not find authentication source with id ' . $sourceId);
244 if (!($source instanceof sspmod_saml_Auth_Source_SP)) {
245 throw new SimpleSAML_Error_NotFound(
'Source isn\'t a SAML SP: ' . var_export($sourceId, TRUE));
248 $entityId = $source->getEntityId();
249 $spconfig = $source->getMetadata();
251 $metaArray20 = array(
252 'AssertionConsumerService' => $acs_url,
253 'SingleLogoutService' => $sls_url,
256 $ed =
new SAML2_XML_md_EntityDescriptor();
257 $ed->entityID = $entityId;
259 $sp =
new SAML2_XML_md_SPSSODescriptor();
260 $ed->RoleDescriptor[] = $sp;
261 $sp->protocolSupportEnumeration = array(
262 'urn:oasis:names:tc:SAML:1.1:protocol',
263 'urn:oasis:names:tc:SAML:2.0:protocol'
266 $slo =
new SAML2_XML_md_EndpointType();
267 $slo->Binding = SAML2_Const::BINDING_HTTP_REDIRECT;
268 $slo->Location = $sls_url;
269 $sp->SingleLogoutService[] = $slo;
271 $store = SimpleSAML_Store::getInstance();
272 if ($store instanceof SimpleSAML_Store_SQL) {
274 $slo =
new SAML2_XML_md_EndpointType();
275 $slo->Binding = SAML2_Const::BINDING_SOAP;
276 $slo->Location = $sls_url;
277 $sp->SingleLogoutService[] = $slo;
280 $assertionsconsumerservicesdefault = array(
281 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
282 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post',
283 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
284 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01',
285 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser',
288 $assertionsconsumerservices = $spconfig->getArray(
'acs.Bindings', $assertionsconsumerservicesdefault);
291 foreach ($assertionsconsumerservices as $services) {
293 $acs =
new SAML2_XML_md_IndexedEndpointType();
294 $acs->index = $index;
296 case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST':
297 $acs->Binding = SAML2_Const::BINDING_HTTP_POST;
298 $acs->Location = $acs_url;
300 case 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post':
301 $acs->Binding =
'urn:oasis:names:tc:SAML:1.0:profiles:browser-post';
302 $acs->Location = $acs_url;
304 case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact':
305 $acs->Binding =
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact';
306 $acs->Location = $acs_url;
308 case 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01':
309 $acs->Binding =
'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01';
310 $acs->Location = $acs_url;
312 case 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser':
313 $acs->Binding =
'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser';
314 $acs->ProtocolBinding = SAML2_Const::BINDING_HTTP_POST;
315 $acs->Location = $acs_url;
318 $sp->AssertionConsumerService[] = $acs;
324 $certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig, FALSE,
'new_');
325 if ($certInfo !== NULL && array_key_exists(
'certData', $certInfo)) {
328 $certData = $certInfo[
'certData'];
329 $kd = SAML2_Utils::createKeyDescriptor($certData);
330 $kd->use =
'signing';
331 $sp->KeyDescriptor[] = $kd;
333 $kd = SAML2_Utils::createKeyDescriptor($certData);
334 $kd->use =
'encryption';
335 $sp->KeyDescriptor[] = $kd;
338 'type' =>
'X509Certificate',
340 'encryption' => TRUE,
341 'X509Certificate' => $certInfo[
'certData'],
347 $certInfo = SimpleSAML_Utilities::loadPublicKey($spconfig);
348 if ($certInfo !== NULL && array_key_exists(
'certData', $certInfo)) {
349 $certData = $certInfo[
'certData'];
350 $kd = SAML2_Utils::createKeyDescriptor($certData);
351 $kd->use =
'signing';
352 $sp->KeyDescriptor[] = $kd;
356 $kd = SAML2_Utils::createKeyDescriptor($certData);
357 $kd->use =
'encryption';
358 $sp->KeyDescriptor[] = $kd;
362 'type' =>
'X509Certificate',
364 'encryption' => ($hasNewCert ? FALSE : TRUE),
365 'X509Certificate' => $certInfo[
'certData'],
371 $name = $spconfig->getLocalizedString(
'name', NULL);
372 $attributes = $spconfig->getArray(
'attributes', array());
374 if ($name !== NULL && !empty($attributes)) {
376 $attributesrequired = $spconfig->getArray(
'attributes.required', array());
379 $acs =
new SAML2_XML_md_AttributeConsumingService();
380 $sp->AttributeConsumingService[] = $acs;
383 $acs->ServiceName = $name;
385 $description = $spconfig->getLocalizedString(
'description', NULL);
386 if ($description !== NULL) {
387 $acs->ServiceDescription = $description;
390 $nameFormat = $spconfig->getString(
'attributes.NameFormat', NULL);
391 foreach ($attributes as $attribute) {
392 $a =
new SAML2_XML_md_RequestedAttribute();
393 $a->Name = $attribute;
394 $a->NameFormat = $nameFormat;
396 if (in_array($attribute, $attributesrequired))
397 $a->isRequired =
true;
399 $acs->RequestedAttribute[] = $a;
402 $metaArray20[
'name'] = $name;
403 if ($description !== NULL) {
404 $metaArray20[
'description'] = $description;
407 $metaArray20[
'attributes'] = $attributes;
408 if ($nameFormat !== NULL) {
409 $metaArray20[
'attributes.NameFormat'] = $nameFormat;
414 $orgName = $spconfig->getLocalizedString(
'OrganizationName', NULL);
415 if ($orgName !== NULL) {
416 $o =
new SAML2_XML_md_Organization();
417 $o->OrganizationName = $orgName;
419 $o->OrganizationDisplayName = $spconfig->getLocalizedString(
'OrganizationDisplayName', NULL);
420 if ($o->OrganizationDisplayName === NULL) {
421 $o->OrganizationDisplayName = $orgName;
424 $o->OrganizationURL = $spconfig->getLocalizedString(
'OrganizationURL', NULL);
425 if ($o->OrganizationURL === NULL) {
426 throw new SimpleSAML_Error_Exception(
'If OrganizationName is set, OrganizationURL must also be set.');
429 $ed->Organization = $o;
431 $metaArray20[
'OrganizationName'] = $orgName;
432 $metaArray20[
'OrganizationDisplayName'] = $o->OrganizationDisplayName;
433 $metaArray20[
'OrganizationURL'] = $o->OrganizationURL;
436 $c =
new SAML2_XML_md_ContactPerson();
437 $c->contactType =
'technical';
439 $email = $config->getString(
'technicalcontact_email', NULL);
440 if ($email !== NULL) {
441 $c->EmailAddress = array($email);
444 $name = $config->getString(
'technicalcontact_name', NULL);
445 if ($name === NULL) {
447 } elseif (preg_match(
'@^(.*?)\s*,\s*(.*)$@D', $name, $matches)) {
448 $c->SurName = $matches[1];
449 $c->GivenName = $matches[2];
450 } elseif (preg_match(
'@^(.*?)\s+(.*)$@D', $name, $matches)) {
451 $c->GivenName = $matches[1];
452 $c->SurName = $matches[2];
454 $c->GivenName = $name;
456 $ed->ContactPerson[] = $c;
459 SimpleSAML_Utilities::formatDOMElement($xml);
460 $xml = $xml->ownerDocument->saveXML($xml);
462 if (count($keys) === 1) {
463 $metaArray20[
'certData'] = $keys[0][
'X509Certificate'];
464 } elseif (count($keys) > 1) {
465 $metaArray20[
'keys'] = $keys;
469 $xml = SimpleSAML_Metadata_Signer::sign($xml, $sp,
'SAML 2 SP');