44 assert(
'is_array($info)');
45 assert(
'is_array($config)');
50 if (!isset(
$config[
'entityID'])) {
58 $this->entityId = $this->metadata->getString(
'entityID');
59 $this->idp = $this->metadata->getString(
'idp', NULL);
60 $this->discoURL = $this->metadata->getString(
'discoURL', NULL);
62 if (empty($this->discoURL) &&
SimpleSAML\Module::isModuleEnabled(
'discojuice')) {
109 assert(
'is_string($entityId)');
111 if ($this->idp !== NULL && $this->idp !==
$entityId) {
113 ' because it isn\'t a valid IdP for this SP.');
120 return $metadataHandler->getMetaDataConfig(
$entityId,
'saml20-idp-remote');
128 return $metadataHandler->getMetaDataConfig(
$entityId,
'shib13-idp-remote');
151 $ar = new \SimpleSAML\XML\Shib13\AuthnRequest();
152 $ar->setIssuer($this->entityId);
155 $ar->setRelayState(
$id);
157 $useArtifact = $idpMetadata->
getBoolean(
'saml1.useartifact', NULL);
158 if ($useArtifact === NULL) {
159 $useArtifact = $this->metadata->getBoolean(
'saml1.useartifact', FALSE);
171 ' from ' . var_export($this->entityId, TRUE) .
'.');
184 if (isset($state[
'saml:ProxyCount']) && $state[
'saml:ProxyCount'] < 0) {
187 new \
SimpleSAML\Module\saml\Error\ProxyCountExceeded(\
SAML2\Constants::STATUS_RESPONDER)
195 $ar->setAssertionConsumerServiceURL(ILIAS_HTTP_PATH .
'/Services/Saml/lib/saml2-acs.php/default-sp/' . CLIENT_ID);
198 if (isset($state[
'SimpleSAML_Auth_Source.ReturnURL'])) {
199 $ar->setRelayState($state[
'SimpleSAML_Auth_Source.ReturnURL']);
202 if (isset($state[
'saml:AuthnContextClassRef'])) {
205 if (isset($state[
'saml:AuthnContextComparison']) && in_array($state[
'AuthnContextComparison'],
array(
206 SAML2\Constants::COMPARISON_EXACT,
207 SAML2\Constants::COMPARISON_MINIMUM,
208 SAML2\Constants::COMPARISON_MAXIMUM,
209 SAML2\Constants::COMPARISON_BETTER,
211 $comp = $state[
'saml:AuthnContextComparison'];
213 $ar->setRequestedAuthnContext(
array(
'AuthnContextClassRef' => $accr,
'Comparison' => $comp));
216 if (isset($state[
'ForceAuthn'])) {
217 $ar->setForceAuthn((
bool)$state[
'ForceAuthn']);
220 if (isset($state[
'isPassive'])) {
221 $ar->setIsPassive((
bool)$state[
'isPassive']);
224 if (isset($state[
'saml:NameID'])) {
225 if (!is_array($state[
'saml:NameID']) && !is_a($state[
'saml:NameID'],
'\SAML2\XML\saml\NameID')) {
228 $ar->setNameId($state[
'saml:NameID']);
231 if (isset($state[
'saml:NameIDPolicy'])) {
232 if (is_string($state[
'saml:NameIDPolicy'])) {
234 'Format' => (
string)$state[
'saml:NameIDPolicy'],
235 'AllowCreate' => TRUE,
237 } elseif (is_array($state[
'saml:NameIDPolicy'])) {
238 $policy = $state[
'saml:NameIDPolicy'];
242 $ar->setNameIdPolicy($policy);
245 if (isset($state[
'saml:IDPList'])) {
246 $IDPList = $state[
'saml:IDPList'];
251 $ar->setIDPList(array_unique(array_merge($this->metadata->getArray(
'IDPList',
array()),
255 if (isset($state[
'saml:ProxyCount']) && $state[
'saml:ProxyCount'] !== null) {
256 $ar->setProxyCount($state[
'saml:ProxyCount']);
257 } elseif ($idpMetadata->
getInteger(
'ProxyCount', null) !== null) {
258 $ar->setProxyCount($idpMetadata->
getInteger(
'ProxyCount', null));
259 } elseif ($this->metadata->getInteger(
'ProxyCount', null) !== null) {
260 $ar->setProxyCount($this->metadata->getInteger(
'ProxyCount', null));
263 $requesterID =
array();
264 if (isset($state[
'saml:RequesterID'])) {
265 $requesterID = $state[
'saml:RequesterID'];
268 if (isset($state[
'core:SP'])) {
269 $requesterID[] = $state[
'core:SP'];
272 $ar->setRequesterID($requesterID);
274 if (isset($state[
'saml:Extensions'])) {
275 $ar->setExtensions($state[
'saml:Extensions']);
279 $state[
'ExpectedIssuer'] = $idpMetadata->
getString(
'entityid');
289 \
SAML2\Constants::BINDING_HOK_SSO)
293 \
SAML2\Constants::BINDING_HTTP_REDIRECT,
294 \
SAML2\Constants::BINDING_HTTP_POST)
297 $ar->setDestination(
$dst[
'Location']);
329 assert(
'is_string($idp)');
335 case 'shib13-idp-remote':
338 case 'saml20-idp-remote':
368 'entityID' => $this->entityId,
370 'returnIDParam' =>
'idpentityid' 373 if(isset($state[
'saml:IDPList'])) {
374 $params[
'IDPList'] = $state[
'saml:IDPList'];
377 if (isset($state[
'isPassive']) && $state[
'isPassive']) {
393 assert(
'is_array($state)');
400 if (isset(
$state[
'saml:idp'])) {
404 if (isset(
$state[
'saml:IDPList']) &&
sizeof(
$state[
'saml:IDPList']) > 0) {
407 $known_idps =
$mdh->getList();
408 $intersection = array_intersect(
$state[
'saml:IDPList'], array_keys($known_idps));
410 if (empty($intersection)) {
412 \
SAML2\Constants::STATUS_REQUESTER,
413 'None of the IdPs requested are supported by this proxy.' 417 if (!is_null(
$idp) && !in_array(
$idp, $intersection,
true)) {
419 \
SAML2\Constants::STATUS_REQUESTER,
420 'None of the IdPs requested are available to this proxy.' 424 if (is_null(
$idp) &&
sizeof($intersection) === 1) {
448 assert(
'is_array($state)');
452 foreach (
$data as $k => $v) {
457 if (isset($state[
'saml:IDPList']) &&
sizeof($state[
'saml:IDPList']) > 0 &&
458 !in_array($state[
'saml:sp:IdP'], $state[
'saml:IDPList'],
true))
468 $known_idps =
$mdh->getList();
469 $intersection = array_intersect($state[
'saml:IDPList'], array_keys($known_idps));
471 if (empty($intersection)) {
473 \
SAML2\Constants::STATUS_REQUESTER,
474 'None of the IdPs requested are supported by this proxy.' 482 if (!is_null($this->idp) && !in_array($this->idp, $intersection,
true)) {
484 \
SAML2\Constants::STATUS_REQUESTER,
485 'None of the IdPs requested are available to this proxy.' 494 "Reauthentication after logout is needed. The IdP '${state['saml:sp:IdP']}' is not in the IDPList ".
495 "provided by the Service Provider '${state['core:SP']}'." 498 $state[
'saml:sp:IdPMetadata'] = $this->
getIdPMetadata($state[
'saml:sp:IdP']);
500 self::askForIdPChange($state);
523 assert(
'array_key_exists("saml:sp:IdPMetadata", $state)');
524 assert(
'array_key_exists("saml:sp:AuthId", $state)');
525 assert(
'array_key_exists("core:IdP", $state)');
526 assert(
'array_key_exists("SPMetadata", $state)');
528 if (isset($state[
'isPassive']) && (
bool)$state[
'isPassive']) {
552 if (isset($state[
'Responder'])) {
553 $state[
'saml:proxy:reauthLogout:PrevResponder'] = $state[
'Responder'];
555 $state[
'Responder'] =
array(
'sspmod_saml_Auth_Source_SP',
'reauthPostLogout');
558 $idp->handleLogoutRequest($state, null);
569 assert(
'isset($state["ReturnCallback"])');
573 $authId = $state[
'saml:sp:AuthId'];
577 call_user_func($state[
'ReturnCallback'], $state);
591 assert(
'isset($state["saml:sp:AuthId"])');
595 if (isset($state[
'saml:proxy:reauthLogout:PrevResponder'])) {
596 $state[
'Responder'] = $state[
'saml:proxy:reauthLogout:PrevResponder'];
602 $sp->authenticate($state);
613 assert(
'is_array($state)');
614 assert(
'array_key_exists("saml:logout:IdP", $state)');
615 assert(
'array_key_exists("saml:logout:NameID", $state)');
616 assert(
'array_key_exists("saml:logout:SessionIndex", $state)');
620 $idp = $state[
'saml:logout:IdP'];
621 $nameId = $state[
'saml:logout:NameID'];
627 \
SAML2\Constants::BINDING_HTTP_REDIRECT,
628 \
SAML2\Constants::BINDING_HTTP_POST), FALSE);
642 $encryptNameId = $this->metadata->getBoolean(
'nameid.encryption', FALSE);
661 assert(
'is_array($state)');
662 assert(
'array_key_exists("saml:logout:Type", $state)');
664 $logoutType = $state[
'saml:logout:Type'];
665 switch ($logoutType) {
687 assert(
'is_string($idp)');
688 assert(
'array_key_exists("LogoutState", $state)');
689 assert(
'array_key_exists("saml:logout:Type", $state["LogoutState"])');
693 $spMetadataArray = $this->metadata->toArray();
697 $state[
'saml:sp:IdP'] =
$idp;
698 $state[
'PersistentAuthData'][] =
'saml:sp:IdP';
700 $authProcState =
array(
701 'saml:sp:IdP' => $idp,
702 'saml:sp:State' => $state,
703 'ReturnCall' =>
array(
'sspmod_saml_Auth_Source_SP',
'onProcessingCompleted'),
705 'Attributes' => $attributes,
706 'Destination' => $spMetadataArray,
707 'Source' => $idpMetadataArray,
710 if (isset($state[
'saml:sp:NameID'])) {
711 $authProcState[
'saml:sp:NameID'] = $state[
'saml:sp:NameID'];
713 if (isset($state[
'saml:sp:SessionIndex'])) {
714 $authProcState[
'saml:sp:SessionIndex'] = $state[
'saml:sp:SessionIndex'];
718 $pc->processState($authProcState);
720 self::onProcessingCompleted($authProcState);
730 assert(
'is_string($idpEntityId)');
750 assert(
'is_string($authId)');
751 assert(
'is_string($redirectTo)');
766 assert(
'array_key_exists("saml:sp:IdP", $authProcState)');
767 assert(
'array_key_exists("saml:sp:State", $authProcState)');
768 assert(
'array_key_exists("Attributes", $authProcState)');
770 $idp = $authProcState[
'saml:sp:IdP'];
771 $state = $authProcState[
'saml:sp:State'];
780 $source->addLogoutCallback($idp, $state);
782 $state[
'Attributes'] = $authProcState[
'Attributes'];
784 if (isset($state[
'saml:sp:isUnsolicited']) && (
bool)$state[
'saml:sp:isUnsolicited']) {
785 if (!empty($state[
'saml:sp:RelayState'])) {
786 $redirectTo = $state[
'saml:sp:RelayState'];
788 $redirectTo =
$source->getMetadata()->getString(
'RelayState',
'/');
790 self::handleUnsolicitedAuth(
$sourceId, $state, $redirectTo);
const BINDING_HOK_SSO
The URN for the Holder-of-Key Web Browser SSO Profile binding.
startDisco(array $state)
Start an IdP discovery service operation.
static askForIdPChange(array &$state)
Ask the user to log out before being able to log in again with a different identity provider...
if(!isset($_REQUEST['ReturnTo'])) $returnTo
static getByState(array &$state)
Retrieve the IdP "owning" the state.
getArray($name, $default=self::REQUIRED_OPTION)
This function retrieves an array configuration option.
static arrayize($data, $index=0)
Put a non-array variable into an array.
callLogoutCallback($assoc)
Call a logout callback based on association.
static throwException($state, SimpleSAML_Error_Exception $exception)
Throw exception to the state exception handler.
static getBinding($urn)
Retrieve a binding with the given URN.
getEntityId()
Retrieve the entity id of this SP.
if(!array_key_exists('StateId', $_REQUEST)) $id
static redirectTrustedURL($url, $parameters=array())
This function redirects to the specified URL without performing any security checks.
static reauthPostLogin(array $state)
Complete login operation after re-authenticating the user on another IdP.
static buildLogoutRequest(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata)
Build a logout request based on information in the metadata.
static buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata)
Build an authentication request based on information in the metadata.
static reauthLogout(array $state)
Log the user out before logging in again.
getMetadataURL()
Retrieve the URL to the metadata of this SP.
static redirectUntrustedURL($url, $parameters=array())
This function redirects to the specified URL after performing the appropriate security checks on it...
reauthenticate(array &$state)
Re-authenticate an user.
Class SimpleSAML_Error_NoPassive.
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
authenticate(&$state)
Start login.
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Attribute-related utility methods.
if(!array_key_exists(sspmod_authfacebook_Auth_Source_Facebook::AUTHID, $state)) $sourceId
static onProcessingCompleted(array $authProcState)
Called when we have completed the procssing chain.
logout(&$state)
Start logout operation.
getDefaultEndpoint($endpointType, array $bindings=null, $default=self::REQUIRED_OPTION)
Find the default endpoint of the given type.
const COMPARISON_EXACT
Request Authentication Context Comparison indicating that the resulting authentication context in the...
__construct($info, $config)
Constructor for SAML SP authentication source.
startSSO($idp, array $state)
Send a SSO request to an IdP.
sendSAML2AuthnRequest(array &$state, \SAML2\Binding $binding, \SAML2\AuthnRequest $ar)
Function to actually send the authentication request.
getIdPMetadata($entityId)
Retrieve the metadata of an IdP.
handleResponse(array $state, $idp, array $attributes)
Handle a response from a SSO operation.
getBoolean($name, $default=self::REQUIRED_OPTION)
This function retrieves a boolean configuration option.
Create styles array
The data for the language used.
startSLO2(&$state)
Start a SAML 2 logout operation.
getInteger($name, $default=self::REQUIRED_OPTION)
This function retrieves an integer configuration option.
static getEncryptionKey(SimpleSAML_Configuration $metadata)
Retrieve the encryption key for the given entity.
getMetadata()
Retrieve the metadata of this SP.
static getPersistentAuthData(array $state)
Get the persistent authentication state from the state array.
static handleUnsolicitedAuth($authId, array $state, $redirectTo)
Handle an unsolicited login operations.
getString($name, $default=self::REQUIRED_OPTION)
This function retrieves a string configuration option.
static completeAuth(&$state)
Complete authentication.
handleLogout($idpEntityId)
Handle a logout request from an IdP.
static getById($authId, $type=null)
Retrieve authentication source.
startSSO2(SimpleSAML_Configuration $idpMetadata, array $state)
Send a SAML2 SSO request to an IdP.
static getSessionFromRequest()
Retrieves the current session.
static loadFromArray($config, $location='[ARRAY]', $instance=null)
Loads a configuration from the given array.
static saveState(&$state, $stage, $rawId=false)
Save the state.
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
startSSO1(SimpleSAML_Configuration $idpMetadata, array $state)
Send a SAML1 SSO request to an IdP.