21        assert(isset(
$state[
'Attributes']));
 
   22        assert(isset(
$state[
'SPMetadata']));
 
   23        assert(isset(
$state[
'saml:ConsumerURL']));
 
   24        assert(array_key_exists(
'saml:RequestId', 
$state)); 
 
   25        assert(array_key_exists(
'saml:RelayState', 
$state)); 
 
   36        $requestId = 
$state[
'saml:RequestId'];
 
   38        $consumerURL = 
$state[
'saml:ConsumerURL'];
 
   39        $protocolBinding = 
$state[
'saml:Binding'];
 
   47        if (isset(
$state[
'saml:AuthenticatingAuthority'])) {
 
   48            $assertion->setAuthenticatingAuthority(
$state[
'saml:AuthenticatingAuthority']);
 
   54            'Handler'           => 
'sspmod_saml_IdP_SAML2',
 
   55            'Expires'           => $assertion->getSessionNotOnOrAfter(),
 
   57            'saml:NameID'       => 
$state[
'saml:idp:NameID'],
 
   58            'saml:SessionIndex' => $assertion->getSessionIndex(),
 
   66        $ar->setInResponseTo($requestId);
 
   68        $ar->setAssertions(array($assertion));
 
   76            'protocol'    => 
'saml2',
 
   78        if (isset(
$state[
'saml:AuthnRequestReceivedAt'])) {
 
   79            $statsData[
'logintime'] = microtime(
true) - 
$state[
'saml:AuthnRequestReceivedAt'];
 
   98        assert(isset(
$state[
'SPMetadata']));
 
   99        assert(isset(
$state[
'saml:ConsumerURL']));
 
  100        assert(array_key_exists(
'saml:RequestId', 
$state)); 
 
  101        assert(array_key_exists(
'saml:RelayState', 
$state)); 
 
  110        $requestId = 
$state[
'saml:RequestId'];
 
  112        $consumerURL = 
$state[
'saml:ConsumerURL'];
 
  113        $protocolBinding = 
$state[
'saml:Binding'];
 
  125        $ar->setInResponseTo($requestId);
 
  129            'Code'    => $error->getStatus(),
 
  130            'SubCode' => $error->getSubStatus(),
 
  131            'Message' => $error->getStatusMessage(),
 
  133        $ar->setStatus($status);
 
  138            'protocol'    => 
'saml2',
 
  141        if (isset(
$state[
'saml:AuthnRequestReceivedAt'])) {
 
  142            $statsData[
'logintime'] = microtime(
true) - 
$state[
'saml:AuthnRequestReceivedAt'];
 
  163        array $supportedBindings,
 
  165        $AssertionConsumerServiceURL,
 
  167        $AssertionConsumerServiceIndex
 
  169        assert(is_string($AssertionConsumerServiceURL) || $AssertionConsumerServiceURL === 
null);
 
  170        assert(is_string($ProtocolBinding) || $ProtocolBinding === 
null);
 
  171        assert(is_int($AssertionConsumerServiceIndex) || $AssertionConsumerServiceIndex === 
null);
 
  180        $firstNotFalse = 
null;
 
  182        foreach (
$spMetadata->getEndpoints(
'AssertionConsumerService') as $ep) {
 
  183            if ($AssertionConsumerServiceURL !== 
null && $ep[
'Location'] !== $AssertionConsumerServiceURL) {
 
  186            if ($ProtocolBinding !== 
null && $ep[
'Binding'] !== $ProtocolBinding) {
 
  189            if ($AssertionConsumerServiceIndex !== 
null && $ep[
'index'] !== $AssertionConsumerServiceIndex) {
 
  193            if (!in_array($ep[
'Binding'], $supportedBindings, 
true)) {
 
  200            if (array_key_exists(
'isDefault', $ep)) {
 
  201                if ($ep[
'isDefault'] === 
true) {
 
  206                if ($firstFalse === 
null) {
 
  211                if ($firstNotFalse === 
null) {
 
  213                    $firstNotFalse = $ep;
 
  218        if ($firstNotFalse !== 
null) {
 
  219            return $firstNotFalse;
 
  220        } elseif ($firstFalse !== 
null) {
 
  225        if ($AssertionConsumerServiceURL !== 
null) {
 
  228        if ($ProtocolBinding !== 
null) {
 
  231        if ($AssertionConsumerServiceIndex !== 
null) {
 
  233                'AssertionConsumerServiceIndex: '.var_export($AssertionConsumerServiceIndex, 
true)
 
  238        return $spMetadata->getDefaultEndpoint(
'AssertionConsumerService', $supportedBindings);
 
  254        $supportedBindings = array(\
SAML2\Constants::BINDING_HTTP_POST);
 
  255        if (
$idpMetadata->getBoolean(
'saml20.sendartifact', 
false)) {
 
  258        if (
$idpMetadata->getBoolean(
'saml20.hok.assertion', 
false)) {
 
  265        if (isset($_REQUEST[
'spentityid'])) {
 
  268            if (isset($_REQUEST[
'cookieTime'])) {
 
  269                $cookieTime = (int) $_REQUEST[
'cookieTime'];
 
  270                if ($cookieTime + 5 > time()) {
 
  282            if (isset($_REQUEST[
'RelayState'])) {
 
  288            if (isset($_REQUEST[
'binding'])) {
 
  289                $protocolBinding = (string) $_REQUEST[
'binding'];
 
  291                $protocolBinding = 
null;
 
  294            if (isset($_REQUEST[
'NameIDFormat'])) {
 
  295                $nameIDFormat = (string) $_REQUEST[
'NameIDFormat'];
 
  297                $nameIDFormat = 
null;
 
  307            $consumerIndex = 
null;
 
  310            $authnContext = 
null;
 
  316                'SAML2.0 - IdP.SSOService: IdP initiated authentication: '.var_export(
$spEntityId, 
true)
 
  324                    'Message received on authentication request endpoint wasn\'t an authentication request.' 
  331                    'Received message on authentication request endpoint without issuer.' 
  342            $ProxyCount = 
$request->getProxyCount();
 
  343            if ($ProxyCount !== 
null) {
 
  346            $RequesterID = 
$request->getRequesterID();
 
  347            $forceAuthn = 
$request->getForceAuthn();
 
  348            $isPassive = 
$request->getIsPassive();
 
  349            $consumerURL = 
$request->getAssertionConsumerServiceURL();
 
  350            $protocolBinding = 
$request->getProtocolBinding();
 
  351            $consumerIndex = 
$request->getAssertionConsumerServiceIndex();
 
  352            $extensions = 
$request->getExtensions();
 
  353            $authnContext = 
$request->getRequestedAuthnContext();
 
  355            $nameIdPolicy = 
$request->getNameIdPolicy();
 
  356            if (isset($nameIdPolicy[
'Format'])) {
 
  357                $nameIDFormat = $nameIdPolicy[
'Format'];
 
  359                $nameIDFormat = 
null;
 
  361            if (isset($nameIdPolicy[
'AllowCreate'])) {
 
  362                $allowCreate = $nameIdPolicy[
'AllowCreate'];
 
  364                $allowCreate = 
false;
 
  370                'SAML2.0 - IdP.SSOService: incoming authentication request: '.var_export(
$spEntityId, 
true)
 
  377            'forceAuthn'  => $forceAuthn,
 
  378            'isPassive'   => $isPassive,
 
  379            'protocol'    => 
'saml2',
 
  380            'idpInit'     => $idpInit,
 
  391        $IDPList = array_unique(array_merge($IDPList, 
$spMetadata->getArrayizeString(
'IDPList', array())));
 
  392        if ($ProxyCount === 
null) {
 
  393            $ProxyCount = 
$spMetadata->getInteger(
'ProxyCount', 
null);
 
  397            $forceAuthn = 
$spMetadata->getBoolean(
'ForceAuthn', 
false);
 
  400        $sessionLostParams = array(
 
  402            'cookieTime' => time(),
 
  408        $sessionLostURL = \SimpleSAML\Utils\HTTP::addURLParameters(
 
  414            'Responder'                                   => array(
'sspmod_saml_IdP_SAML2', 
'sendResponse'),
 
  420            'saml:RequestId'              => $requestId,
 
  421            'saml:IDPList'                => $IDPList,
 
  422            'saml:ProxyCount'             => $ProxyCount,
 
  423            'saml:RequesterID'            => $RequesterID,
 
  424            'ForceAuthn'                  => $forceAuthn,
 
  425            'isPassive'                   => $isPassive,
 
  426            'saml:ConsumerURL'            => $acsEndpoint[
'Location'],
 
  427            'saml:Binding'                => $acsEndpoint[
'Binding'],
 
  428            'saml:NameIDFormat'           => $nameIDFormat,
 
  429            'saml:AllowCreate'            => $allowCreate,
 
  430            'saml:Extensions'             => $extensions,
 
  431            'saml:AuthnRequestReceivedAt' => microtime(
true),
 
  432            'saml:RequestedAuthnContext'  => $authnContext,
 
  478            'SingleLogoutService',
 
  480                \
SAML2\Constants::BINDING_HTTP_REDIRECT,
 
  481                \
SAML2\Constants::BINDING_HTTP_POST
 
  486        $lr->setDestination(
$dst[
'Location']);
 
  500        assert(isset(
$state[
'saml:SPEntityId']));
 
  501        assert(isset(
$state[
'saml:RequestId']));
 
  502        assert(array_key_exists(
'saml:RelayState', 
$state)); 
 
  511        $lr->setInResponseTo(
$state[
'saml:RequestId']);
 
  512        $lr->setRelayState(
$state[
'saml:RelayState']);
 
  514        if (isset(
$state[
'core:Failed']) && 
$state[
'core:Failed']) {
 
  516            $lr->setStatus(array(
 
  517                'Code'    => \
SAML2\Constants::STATUS_SUCCESS,
 
  518                'SubCode' => \
SAML2\Constants::STATUS_PARTIAL_LOGOUT,
 
  529            'partial'     => $partial
 
  532            'SingleLogoutService',
 
  534                \
SAML2\Constants::BINDING_HTTP_REDIRECT,
 
  535                \
SAML2\Constants::BINDING_HTTP_POST
 
  539        if (isset(
$dst[
'ResponseLocation'])) {
 
  581                $statsData[
'error'] = 
$message->getStatus();
 
  608                'Responder'       => array(
'sspmod_saml_IdP_SAML2', 
'sendLogoutResponse'),
 
  610                'saml:RelayState' => 
$message->getRelayState(),
 
  611                'saml:RequestId'  => 
$message->getId(),
 
  642            \
SAML2\Constants::BINDING_HTTP_REDIRECT,
 
  643            \
SAML2\Constants::BINDING_HTTP_POST
 
  647        if (
$dst[
'Binding'] === \
SAML2\Constants::BINDING_HTTP_POST) {
 
  656        $lr->setDestination(
$dst[
'Location']);
 
  658        $binding = new \SAML2\HTTPRedirect();
 
  676        } 
catch (Exception $e) {
 
  697        $attribute = 
$spMetadata->getString(
'simplesaml.nameidattribute', 
null);
 
  698        if ($attribute === 
null) {
 
  699            $attribute = 
$idpMetadata->getString(
'simplesaml.nameidattribute', 
null);
 
  700            if ($attribute === 
null) {
 
  701                if (!isset(
$state[
'UserID'])) {
 
  705                $attributeValue = 
$state[
'UserID'];
 
  711                $uidData = 
'uidhashbase'.$secretSalt;
 
  714                $uidData .= strlen($attributeValue).
':'.$attributeValue;
 
  715                $uidData .= $secretSalt;
 
  717                return hash(
'sha1', $uidData);
 
  724                ' in the attributes of the user.');
 
  749        $base64Attributes = 
$spMetadata->getBoolean(
'base64attributes', 
null);
 
  750        if ($base64Attributes === 
null) {
 
  751            $base64Attributes = 
$idpMetadata->getBoolean(
'base64attributes', 
false);
 
  754        if ($base64Attributes) {
 
  755            $defaultEncoding = 
'base64';
 
  757            $defaultEncoding = 
'string';
 
  760        $srcEncodings = 
$idpMetadata->getArray(
'attributeencodings', array());
 
  761        $dstEncodings = 
$spMetadata->getArray(
'attributeencodings', array());
 
  767        $encodings = array_merge($srcEncodings, $dstEncodings);
 
  772            if (array_key_exists(
$name, $encodings)) {
 
  773                $encoding = $encodings[
$name];
 
  775                $encoding = $defaultEncoding;
 
  780                if ($value === 
null) {
 
  786                if ($value instanceof DOMNodeList) {
 
  787                    $attrval = new \SAML2\XML\saml\AttributeValue($value->item(0)->parentNode);
 
  792                        $value = (string) $attrval;
 
  795                        $value = base64_encode((
string) $attrval);
 
  798                        if (is_string($value)) {
 
  800                            $value = $doc->firstChild->childNodes;
 
  802                        assert($value instanceof DOMNodeList || $value instanceof \
SAML2\XML\saml\NameID);
 
  806                            var_export(
$name, 
true).
': '.var_export($encoding, 
true));
 
  850        return 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic';
 
  870        assert(isset(
$state[
'Attributes']));
 
  871        assert(isset(
$state[
'saml:ConsumerURL']));
 
  875        $signAssertion = 
$spMetadata->getBoolean(
'saml20.sign.assertion', 
null);
 
  876        if ($signAssertion === 
null) {
 
  877            $signAssertion = 
$idpMetadata->getBoolean(
'saml20.sign.assertion', 
true);
 
  882        $a = new \SAML2\Assertion();
 
  883        if ($signAssertion) {
 
  888        $a->setValidAudiences(array(
$spMetadata->getString(
'entityid')));
 
  890        $a->setNotBefore($now - 30);
 
  898        if (isset(
$state[
'saml:AuthnContextClassRef'])) {
 
  899            $a->setAuthnContextClassRef(
$state[
'saml:AuthnContextClassRef']);
 
  900        } elseif (\
SimpleSAML\Utils\HTTP::isHTTPS()) {
 
  901            $a->setAuthnContextClassRef(\
SAML2\Constants::AC_PASSWORD_PROTECTED_TRANSPORT);
 
  903            $a->setAuthnContext(\
SAML2\Constants::AC_PASSWORD);
 
  906        $sessionStart = $now;
 
  907        if (isset(
$state[
'AuthnInstant'])) {
 
  908            $a->setAuthnInstant(
$state[
'AuthnInstant']);
 
  909            $sessionStart = 
$state[
'AuthnInstant'];
 
  912        $sessionLifetime = 
$config->getInteger(
'session.duration', 8 * 60 * 60);
 
  913        $a->setSessionNotOnOrAfter($sessionStart + $sessionLifetime);
 
  915        $a->setSessionIndex(
SimpleSAML\Utils\Random::generateID());
 
  917        $sc = new \SAML2\XML\saml\SubjectConfirmation();
 
  920        $sc->SubjectConfirmationData->Recipient = 
$state[
'saml:ConsumerURL'];
 
  921        $sc->SubjectConfirmationData->InResponseTo = 
$state[
'saml:RequestId'];
 
  924        $hokAssertion = 
null;
 
  925        if (
$state[
'saml:Binding'] === \
SAML2\Constants::BINDING_HOK_SSO) {
 
  926            $hokAssertion = 
true;
 
  928        if ($hokAssertion === 
null) {
 
  929            $hokAssertion = 
$idpMetadata->getBoolean(
'saml20.hok.assertion', 
false);
 
  936                if (isset(
$_SERVER[
'SSL_CLIENT_CERT']) && !empty(
$_SERVER[
'SSL_CLIENT_CERT'])) {
 
  938                    $clientCert = 
$_SERVER[
'SSL_CLIENT_CERT'];
 
  939                    $pattern = 
'/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m';
 
  940                    if (preg_match($pattern, $clientCert, $matches)) {
 
  942                        $x509Certificate = new \SAML2\XML\ds\X509Certificate();
 
  943                        $x509Certificate->certificate = str_replace(array(
"\r", 
"\n", 
" "), 
'', $matches[1]);
 
  945                        $x509Data = new \SAML2\XML\ds\X509Data();
 
  946                        $x509Data->data[] = $x509Certificate;
 
  948                        $keyInfo = new \SAML2\XML\ds\KeyInfo();
 
  949                        $keyInfo->info[] = $x509Data;
 
  951                        $sc->SubjectConfirmationData->info[] = $keyInfo;
 
  954                            'Error creating HoK assertion: No valid client certificate provided during TLS handshake '.
 
  960                        'Error creating HoK assertion: No client certificate provided during TLS handshake with IdP' 
  965                    'Error creating HoK assertion: No HTTPS connection to IdP, but required for Holder-of-Key SSO' 
  972        $a->setSubjectConfirmation(array(
$sc));
 
  975        if (
$spMetadata->getBoolean(
'simplesaml.attributes', 
true)) {
 
  983        if (isset(
$state[
'saml:NameIDFormat'])) {
 
 1001            $spNameQualifier = 
$spMetadata->getString(
'SPNameQualifier', 
null);
 
 1002            if ($spNameQualifier === 
null) {
 
 1003                $spNameQualifier = 
$spMetadata->getString(
'entityid');
 
 1020            $nameId = new \SAML2\XML\saml\NameID();
 
 1023            $nameId->SPNameQualifier = $spNameQualifier;
 
 1059        \
SAML2\Assertion $assertion
 
 1062        $encryptAssertion = 
$spMetadata->getBoolean(
'assertion.encryption', 
null);
 
 1063        if ($encryptAssertion === 
null) {
 
 1064            $encryptAssertion = 
$idpMetadata->getBoolean(
'assertion.encryption', 
false);
 
 1066        if (!$encryptAssertion) {
 
 1072        $sharedKey = 
$spMetadata->getString(
'sharedkey', 
null);
 
 1073        if ($sharedKey !== 
null) {
 
 1075            $key->loadKey($sharedKey);
 
 1078            if (!empty(
$keys)) {
 
 1080                switch (
$key[
'type']) {
 
 1081                    case 'X509Certificate':
 
 1082                        $pemKey = 
"-----BEGIN CERTIFICATE-----\n".
 
 1083                            chunk_split(
$key[
'X509Certificate'], 64).
 
 1084                            "-----END CERTIFICATE-----\n";
 
 1091                $key = 
new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array(
'type' => 
'public'));
 
 1092                $key->loadKey($pemKey);
 
 1094                throw new SimpleSAML_Error_ConfigurationError(
 
 1095                    'Missing encryption key for entity `' . 
$spMetadata->getString(
'entityid') . 
'`',
 
 1102        $ea = new \SAML2\EncryptedAssertion();
 
 1103        $ea->setAssertion($assertion, 
$key);
 
 1163        $signResponse = 
$spMetadata->getBoolean(
'saml20.sign.response', 
null);
 
 1164        if ($signResponse === 
null) {
 
 1165            $signResponse = 
$idpMetadata->getBoolean(
'saml20.sign.response', 
true);
 
 1168        $r = new \SAML2\Response();
 
 1171        $r->setDestination($consumerURL);
 
 1173        if ($signResponse) {
 
$metadata['__DYNAMIC:1__']
foreach($paths as $path) $request
$sc SubjectConfirmationData
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
An exception for terminatinating execution or to throw for unit testing.
static getCurrentBinding()
Guess the current binding.
static getBinding($urn)
Retrieve a binding with the given URN.
const BINDING_HOK_SSO
The URN for the Holder-of-Key Web Browser SSO Profile binding.
const NAMEID_TRANSIENT
Transient NameID format.
const CM_BEARER
Bearer subject confirmation method.
const BINDING_HTTP_ARTIFACT
The URN for the HTTP-ARTIFACT binding.
const CM_HOK
Holder-of-Key subject confirmation method.
const BINDING_PAOS
The URN for the PAOS binding.
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
static getSecretSalt()
Retrieve the secret salt.
static checkSessionCookie($retryURL=null)
Check for session cookie, and show missing-cookie page if it is missing.
static generateID()
Generate a random identifier, ID_LENGTH bytes long.
const EXCEPTION_HANDLER_FUNC
The index in the state array which contains the exception handler function.
const RESTART
The index in the state array which contains the restart URL.
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
static loadFromArray($config, $location='[ARRAY]', $instance=null)
Loads a configuration from the given array.
log($default_level)
Print the exception to the log, by default with log level error.
static getByState(array &$state)
Retrieve the IdP "owning" the state.
static log($event, array $data=array())
Notify about an event.
static fromException(Exception $exception)
Create a SAML2 error from an exception.
static sendLogoutResponse(SimpleSAML_IdP $idp, array $state)
Send a logout response.
static receiveAuthnRequest(SimpleSAML_IdP $idp)
Receive an authentication request.
static handleAuthError(SimpleSAML_Error_Exception $exception, array $state)
Handle authentication error.
static buildAssertion(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state)
Build an assertion based on information in the metadata.
static getAssociationConfig(SimpleSAML_IdP $idp, array $association)
Retrieve the metadata for the given SP association.
static getLogoutURL(SimpleSAML_IdP $idp, array $association, $relayState)
Retrieve a logout URL for a given logout association.
static receiveLogoutMessage(SimpleSAML_IdP $idp)
Receive a logout message.
static buildLogoutRequest(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array $association, $relayState)
Build a logout request based on information in the metadata.
static getAttributeNameFormat(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata)
Determine which NameFormat we should use for attributes.
static processSOAPAuthnRequest(array &$state)
static sendLogoutRequest(SimpleSAML_IdP $idp, array $association, $relayState)
Send a logout request to a given association.
static encodeAttributes(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array $attributes)
Helper function for encoding attributes.
static generateNameIdValue(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state)
Calculate the NameID value that should be used.
static sendResponse(array $state)
Send a response to the SP.
static encryptAssertion(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, \SAML2\Assertion $assertion)
Encrypt an assertion.
static getAssertionConsumerService(array $supportedBindings, SimpleSAML_Configuration $spMetadata, $AssertionConsumerServiceURL, $ProtocolBinding, $AssertionConsumerServiceIndex)
Find SP AssertionConsumerService based on parameter in AuthnRequest.
static buildResponse(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, $consumerURL)
Build a authentication response based on information in the metadata.
static getResponseError(\SAML2\StatusResponse $response)
Retrieve the status code of a response as a sspmod_saml_Error.
static addSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, \SAML2\SignedElement $element)
Add signature key and sender certificate to an element (Message or Assertion).
static buildLogoutRequest(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata)
Build a logout request based on information in the metadata.
static buildLogoutResponse(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata)
Build a logout response based on information in the metadata.
static getEncryptionKey(SimpleSAML_Configuration $metadata)
Retrieve the encryption key for the given entity.
static validateMessage(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, \SAML2\Message $message)
Check signature on a SAML2 message if enabled.
if(array_key_exists('yes', $_REQUEST)) $attributes
catch(Exception $e) $message
if(!isset($associations[$assocId])) $association
if(!isset($_REQUEST['association'])) $assocId
hash(StreamInterface $stream, $algo, $rawOutput=false)
Calculate a hash of a Stream.
Attribute-related utility methods.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']