1 # OneLogin's SAML PHP Toolkit Compatible with PHP 7.X & 8.X
3 [![Build Status](https://api.travis-ci.org/onelogin/php-saml.png?branch=master)](http://travis-ci.org/onelogin/php-saml) [![Coverage Status](https://coveralls.io/repos/onelogin/php-saml/badge.png)](https://coveralls.io/r/onelogin/php-saml) [![License](https://poser.pugx.org/onelogin/php-saml/license.png)](https://packagist.org/packages/onelogin/php-saml)
5 Add SAML support to your PHP software using this library.
6 Forget those complicated libraries and use this open source library provided
7 and supported by OneLogin Inc.
13 This version is compatible with PHP >=7.3 and 8.X and does not include xmlseclibs (you will need to install it via composer, dependency described in composer.json)
18 If you believe you have discovered a security vulnerability in this toolkit, please report it at https://www.onelogin.com/security with a description. We follow responsible disclosure guidelines, and will work with you to quickly find a resolution.
21 Why add SAML support to my software?
22 ------------------------------------
24 SAML is an XML-based standard for web browser single sign-on and is defined by
25 the OASIS Security Services Technical Committee. The standard has been around
26 since 2002, but lately it is becoming popular due its advantages:
28 * **Usability** - One-click access from portals or intranets, deep linking,
29 password elimination and automatically renewing sessions make life
31 * **Security** - Based on strong digital signatures for authentication and
32 integrity, SAML is a secure single sign-on protocol that the largest
33 and most security conscious enterprises in the world rely on.
34 * **Speed** - SAML is fast. One browser redirect is all it takes to securely
35 sign a user into an application.
36 * **Phishing Prevention** - If you don’t have a password for an app, you
37 can’t be tricked into entering it on a fake login page.
38 * **IT Friendly** - SAML simplifies life for IT because it centralizes
39 authentication, provides greater visibility and makes directory
41 * **Opportunity** - B2B cloud vendor should support SAML to facilitate the
42 integration of their product.
48 OneLogin's SAML PHP toolkit let you build a SP (Service Provider) over
49 your PHP application and connect it to any IdP (Identity Provider).
53 * SSO and SLO (SP-Initiated and IdP-Initiated).
54 * Assertion and nameId encryption.
55 * Assertion signature.
56 * Message signature: AuthNRequest, LogoutRequest, LogoutResponses.
57 * Enable an Assertion Consumer Service endpoint.
58 * Enable a Single Logout Service endpoint.
59 * Publish the SP metadata (which can be signed).
63 * **saml2int** - Implements the SAML 2.0 Web Browser SSO Profile.
64 * **Session-less** - Forget those common conflicts between the SP and
65 the final app, the toolkit delegate session in the final app.
66 * **Easy to use** - Programmer will be allowed to code high-level and
67 low-level programming, 2 easy to use APIs are available.
68 * **Tested** - Thoroughly tested.
69 * **Popular** - OneLogin's customers use it. Many PHP SAML plugins uses it.
71 Integrate your PHP toolkit at OneLogin using this guide: [https://developers.onelogin.com/page/saml-toolkit-for-php](https://developers.onelogin.com/page/saml-toolkit-for-php)
78 * `php >= 5.4` and some core extensions like `php-xml`, `php-date`, `php-zlib`.
79 * `openssl`. Install the openssl library. It handles x509 certificates.
80 * `gettext`. Install that library and its php driver. It handles translations.
81 * `curl`. Install that library and its php driver if you plan to use the IdP Metadata parser.
85 #### Option 1. clone the repository from github ####
87 git clone git@github.com:onelogin/php-saml.git
89 Then pull the 3.X.X branch/tag
91 #### Option 2. Download from github ####
93 The toolkit is hosted on github. You can download it from:
95 * https://github.com/onelogin/php-saml/releases
97 Search for 3.X.X releases
99 Copy the core of the library inside the php application. (each application has its
100 structure so take your time to locate the PHP SAML toolkit in the best place).
101 See the "Guide to add SAML support to my app" to know how.
103 Take in mind that the compressed file only contains the main files.
104 If you plan to play with the demos, use the Option 1.
106 #### Option 3. Composer ####
108 The toolkit supports [composer](https://getcomposer.org/). You can find the `onelogin/php-saml` package at https://packagist.org/packages/onelogin/php-saml
110 In order to import the saml toolkit to your current php project, execute
112 composer require onelogin/php-saml
115 Remember to select the 3.X.X branch
117 After installation has completed you will find at the `vendor/` folder a new folder named `onelogin` and inside the `php-saml`. Make sure you are including the autoloader provided by composer. It can be found at `vendor/autoload.php`.
119 **Important** In this option, the x509 certs must be stored at `vendor/onelogin/php-saml/certs`
120 and settings file stored at `vendor/onelogin/php-saml`.
122 Your settings are at risk of being deleted when updating packages using `composer update` or similar commands. So it is **highly** recommended that instead of using settings files, you pass the settings as an array directly to the constructor (explained later in this document). If you do not use this approach your settings are at risk of being deleted when updating packages using `composer update` or similar commands.
127 This 4.X.X supports PHP >=7.3 .
129 It is not compatible with PHP5.6 or PHP7.0.
134 If you are using the library with a framework like Symfony that contains
135 namespaces, remember that calls to the class must be done by adding a backslash (`\`) to the
136 start, for example to use the static method getSelfURLNoQuery use:
138 \OneLogin\Saml2\Utils::getSelfURLNoQuery()
144 In production, the `strict` parameter **MUST** be set as `"true"` and the
145 `signatureAlgorithm` and `digestAlgorithm` under `security` must be set to
146 something other than SHA1 (see https://shattered.io/ ). Otherwise your
147 environment is not secure and will be exposed to attacks.
149 In production also we highly recommended to register on the settings the IdP certificate instead of using the fingerprint method. The fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass. Other SAML toolkits deprecated that mechanism, we maintain it for compatibility and also to be used on test environment.
154 ### Knowing the toolkit ###
156 The new OneLogin SAML Toolkit contains different folders (`certs`, `endpoints`,
157 `lib`, `demo`, etc.) and some files.
159 Let's start describing the folders:
163 SAML requires a x509 cert to sign and encrypt elements like `NameID`, `Message`,
164 `Assertion`, `Metadata`.
166 If our environment requires sign or encrypt support, this folder may contain
167 the x509 cert and the private key that the SP will use:
169 * `sp.crt` - The public cert of the SP
170 * `sp.key` - The private key of the SP
172 Or also we can provide those data in the setting file at the `$settings['sp']['x509cert']`
173 and the `$settings['sp']['privateKey']`.
175 Sometimes we could need a signature on the metadata published by the SP, in
176 this case we could use the x509 cert previously mentioned or use a new x.509
177 cert: `metadata.crt` and `metadata.key`.
179 Use `sp_new.crt` if you are in a key rollover process and you want to
180 publish that x509 certificate on Service Provider metadata.
184 This folder contains the heart of the toolkit, the libraries:
186 * `Saml2` folder contains the new version of the classes and methods that
187 are described in a later section.
192 This folder contains the API documentation of the toolkit.
195 #### `endpoints/` ####
197 The toolkit has three endpoints:
199 * `metadata.php` - Where the metadata of the SP is published.
200 * `acs.php` - Assertion Consumer Service. Processes the SAML Responses.
201 * `sls.php` - Single Logout Service. Processes Logout Requests and Logout
204 You can use the files provided by the toolkit or create your own endpoints
205 files when adding SAML support to your applications. Take in mind that those
206 endpoints files uses the setting file of the toolkit's base folder.
211 Locale folder contains some translations: `en_US` and `es_ES` as a proof of concept.
212 Currently there are no translations but we will eventually localize the messages
213 and support multiple languages.
216 #### Other important files ####
218 * `settings_example.php` - A template to be used in order to create a
219 settings.php file which contains the basic configuration info of the toolkit.
220 * `advanced_settings_example.php` - A template to be used in order to create a
221 advanced_settings.php file which contains extra configuration info related to
222 the security, the contact person, and the organization associated to the SP.
223 * `_toolkit_loader.php` - This file load the toolkit libraries (The SAML2 lib).
226 #### Miscellaneous ####
228 * `tests/` - Contains the unit test of the toolkit.
229 * `demo1/` - Contains an example of a simple PHP app with SAML support.
230 Read the `Readme.txt` inside for more info.
231 * `demo2/` - Contains another example.
238 First of all we need to configure the toolkit. The SP's info, the IdP's info,
239 and in some cases, configure advanced security issues like signatures and
242 There are two ways to provide the settings information:
244 * Use a `settings.php` file that we should locate at the base folder of the
246 * Use an array with the setting data and provide it directly to the
247 constructor of the class.
250 There is a template file, `settings_example.php`, so you can make a copy of this
251 file, rename and edit it.
257 // If 'strict' is True, then the PHP Toolkit will reject unsigned
258 // or unencrypted messages if it expects them to be signed or encrypted.
259 // Also it will reject the messages if the SAML standard is not strictly
260 // followed: Destination, NameId, Conditions ... are validated too.
263 // Enable debug mode (to print errors).
266 // Set a BaseURL to be used instead of try to guess
267 // the BaseURL of the view that process the SAML Message.
268 // Ex http://sp.example.com/
269 // http://example.com/sp/
272 // Service Provider Data that we are deploying.
274 // Identifier of the SP entity (must be a URI)
276 // Specifies info about where and how the <AuthnResponse> message MUST be
277 // returned to the requester, in this case our SP.
278 'assertionConsumerService' => array(
279 // URL Location where the <Response> from the IdP will be returned
281 // SAML protocol binding to be used when returning the <Response>
282 // message. OneLogin Toolkit supports this endpoint for the
283 // HTTP-POST binding only.
284 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
286 // If you need to specify requested attributes, set a
287 // attributeConsumingService. nameFormat, attributeValue and
288 // friendlyName can be omitted
289 "attributeConsumingService"=> array(
290 "serviceName" => "SP test",
291 "serviceDescription" => "Test Service",
292 "requestedAttributes" => array(
295 "isRequired" => false,
297 "friendlyName" => "",
298 "attributeValue" => array()
302 // Specifies info about where and how the <Logout Response> message MUST be
303 // returned to the requester, in this case our SP.
304 'singleLogoutService' => array(
305 // URL Location where the <Response> from the IdP will be returned
307 // SAML protocol binding to be used when returning the <Response>
308 // message. OneLogin Toolkit supports the HTTP-Redirect binding
309 // only for this endpoint.
310 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
312 // Specifies the constraints on the name identifier to be used to
313 // represent the requested subject.
314 // Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported.
315 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
316 // Usually x509cert and privateKey of the SP are provided by files placed at
317 // the certs folder. But we can also provide them with the following parameters
323 * If you plan to update the SP x509cert and privateKey
324 * you can define here the new x509cert and it will be
325 * published on the SP metadata so Identity Providers can
326 * read them and get ready for rollover.
328 // 'x509certNew' => '',
331 // Identity Provider Data that we want connected with our SP.
333 // Identifier of the IdP entity (must be a URI)
335 // SSO endpoint info of the IdP. (Authentication Request protocol)
336 'singleSignOnService' => array(
337 // URL Target of the IdP where the Authentication Request Message
340 // SAML protocol binding to be used when returning the <Response>
341 // message. OneLogin Toolkit supports the HTTP-Redirect binding
342 // only for this endpoint.
343 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
345 // SLO endpoint info of the IdP.
346 'singleLogoutService' => array(
347 // URL Location of the IdP where SLO Request will be sent.
349 // URL location of the IdP where SLO Response will be sent (ResponseLocation)
350 // if not set, url for the SLO Request will be used
352 // SAML protocol binding to be used when returning the <Response>
353 // message. OneLogin Toolkit supports the HTTP-Redirect binding
354 // only for this endpoint.
355 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
357 // Public x509 certificate of the IdP
360 * Instead of use the whole x509cert you can use a fingerprint in order to
361 * validate a SAMLResponse, but we don't recommend to use that
362 * method on production since is exploitable by a collision attack.
363 * (openssl x509 -noout -fingerprint -in "idp.crt" to generate it,
364 * or add for example the -sha256 , -sha384 or -sha512 parameter)
366 * If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to
367 * let the toolkit know which algorithm was used. Possible values: sha1, sha256, sha384 or sha512
368 * 'sha1' is the default value.
370 * Notice that if you want to validate any SAML Message sent by the HTTP-Redirect binding, you
371 * will need to provide the whole x509cert.
373 // 'certFingerprint' => '',
374 // 'certFingerprintAlgorithm' => 'sha1',
376 /* In some scenarios the IdP uses different certificates for
377 * signing/encryption, or is under key rollover phase and
378 * more than one certificate is published on IdP metadata.
379 * In order to handle that the toolkit offers that parameter.
380 * (when used, 'x509cert' and 'certFingerprint' values are
383 // 'x509certMulti' => array(
384 // 'signing' => array(
385 // 0 => '<cert1-string>',
387 // 'encryption' => array(
388 // 0 => '<cert2-string>',
394 In addition to the required settings data (IdP, SP), there is extra
395 information that could be defined. In the same way that a template exists
396 for the basic info, there is a template for that advanced info located
397 at the base folder of the toolkit and named `advanced_settings_example.php`
398 that you can copy and rename it as `advanced_settings.php`
403 $advancedSettings = array(
405 // Compression settings
413 /** signatures and encryptions offered */
415 // Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
416 // will be encrypted.
417 'nameIdEncrypted' => false,
419 // Indicates whether the <samlp:AuthnRequest> messages sent by this SP
420 // will be signed. [Metadata of the SP will offer this info]
421 'authnRequestsSigned' => false,
423 // Indicates whether the <samlp:logoutRequest> messages sent by this SP
425 'logoutRequestSigned' => false,
427 // Indicates whether the <samlp:logoutResponse> messages sent by this SP
429 'logoutResponseSigned' => false,
432 False || True (use sp certs) || array (
433 'keyFileName' => 'metadata.key',
434 'certFileName' => 'metadata.crt'
441 'signMetadata' => false,
443 /** signatures and encryptions required **/
445 // Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest>
446 // and <samlp:LogoutResponse> elements received by this SP to be signed.
447 'wantMessagesSigned' => false,
449 // Indicates a requirement for the <saml:Assertion> elements received by
450 // this SP to be encrypted.
451 'wantAssertionsEncrypted' => false,
453 // Indicates a requirement for the <saml:Assertion> elements received by
454 // this SP to be signed. [Metadata of the SP will offer this info]
455 'wantAssertionsSigned' => false,
457 // Indicates a requirement for the NameID element on the SAMLResponse
458 // received by this SP to be present.
459 'wantNameId' => true,
461 // Indicates a requirement for the NameID received by
462 // this SP to be encrypted.
463 'wantNameIdEncrypted' => false,
465 // Authentication context.
466 // Set to false and no AuthContext will be sent in the AuthNRequest.
467 // Set true or don't present this parameter and you will get an AuthContext 'exact' 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'.
468 // Set an array with the possible auth context values: array('urn:oasis:names:tc:SAML:2.0:ac:classes:Password', 'urn:oasis:names:tc:SAML:2.0:ac:classes:X509').
469 'requestedAuthnContext' => false,
471 // Indicates if the SP will validate all received xmls.
472 // (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).
473 'wantXMLValidation' => true,
475 // If true, SAMLResponses with an empty value at its Destination
476 // attribute will not be rejected for this fact.
477 'relaxDestinationValidation' => false,
479 // If true, Destination URL should strictly match to the address to
480 // which the response has been sent.
481 // Notice that if 'relaxDestinationValidation' is true an empty Destintation
483 'destinationStrictlyMatches' => false,
485 // If true, the toolkit will not raised an error when the Statement Element
486 // contain atribute elements with name duplicated
487 'allowRepeatAttributeName' => false,
489 // If true, SAMLResponses with an InResponseTo value will be rejectd if not
490 // AuthNRequest ID provided to the validation method.
491 'rejectUnsolicitedResponsesWithInResponseTo' => false,
493 // Algorithm that the toolkit will use on signing process. Options:
494 // 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
495 // 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
496 // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
497 // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'
498 // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
499 // Notice that rsa-sha1 is a deprecated algorithm and should not be used
500 'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
502 // Algorithm that the toolkit will use on digest process. Options:
503 // 'http://www.w3.org/2000/09/xmldsig#sha1'
504 // 'http://www.w3.org/2001/04/xmlenc#sha256'
505 // 'http://www.w3.org/2001/04/xmldsig-more#sha384'
506 // 'http://www.w3.org/2001/04/xmlenc#sha512'
507 // Notice that sha1 is a deprecated algorithm and should not be used
508 'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
510 // Algorithm that the toolkit will use for encryption process. Options:
511 // 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'
512 // 'http://www.w3.org/2001/04/xmlenc#aes128-cbc'
513 // 'http://www.w3.org/2001/04/xmlenc#aes192-cbc'
514 // 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'
515 // 'http://www.w3.org/2009/xmlenc11#aes128-gcm'
516 // 'http://www.w3.org/2009/xmlenc11#aes192-gcm'
517 // 'http://www.w3.org/2009/xmlenc11#aes256-gcm';
518 // Notice that aes-cbc are not consider secure anymore so should not be used
519 'encryption_algorithm' => 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
521 // ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses
522 // uppercase. Turn it True for ADFS compatibility on signature verification
523 'lowercaseUrlencoding' => false,
526 // Contact information template, it is recommended to supply a
527 // technical and support contacts.
528 'contactPerson' => array(
529 'technical' => array(
539 // Organization information template, the info in en_US lang is
540 // recomended, add more if required.
541 'organization' => array(
551 The compression settings allow you to instruct whether or not the IdP can accept
552 data that has been compressed using [gzip](gzip) ('requests' and 'responses').
553 But if we provide a `$deflate` boolean parameter to the `getRequest` or `getResponse` method it will have priority over the compression settings.
555 In the security section, you can set the way that the SP will handle the messages
556 and assertions. Contact the admin of the IdP and ask him what the IdP expects,
557 and decide what validations will handle the SP and what requirements the SP will have
558 and communicate them to the IdP's admin too.
560 Once we know what kind of data could be configured, let's talk about the way
561 settings are handled within the toolkit.
563 The settings files described (`settings.php` and `advanced_settings.php`) are loaded
564 by the toolkit if no other array with settings info is provided in the constructor of the toolkit. Let's see some examples.
567 // Initializes toolkit with settings.php & advanced_settings files.
568 $auth = new OneLogin\Saml2\Auth();
570 $settings = new OneLogin\Saml2\Settings();
572 // Initializes toolkit with the array provided.
573 $auth = new OneLogin\Saml2\Auth($settingsInfo);
575 $settings = new OneLogin\Saml2\Settings($settingsInfo);
578 You can declare the `$settingsInfo` in the file that contains the constructor
579 execution or locate them in any file and load the file in order to get the
580 array available as we see in the following example:
585 require_once 'custom_settings.php'; // The custom_settings.php contains a
586 // $settingsInfo array.
588 $auth = new OneLogin\Saml2\Auth($settingsInfo);
592 #### How load the library ####
595 In order to use the toolkit library, if your project support composer you only
596 need to install it with composer (See the installation section) and you are done.
599 If your project doesn't use composer you need to import the `_toolkit_loader.php`
600 file located on the base folder of the toolkit. You can load this file in this way:
605 define("TOOLKIT_PATH", '/var/www/php-saml/');
606 require_once(TOOLKIT_PATH . '_toolkit_loader.php');
609 After that line we will be able to use the classes (and their methods) of the
610 toolkit (because the external and the Saml2 libraries files are loaded).
612 That toolkit depends on [xmlseclibs](https://github.com/robrichards/xmlseclibs) 3.X.X branch,
613 you will need to get its code and place on your project and reuse the _toolkit_loader.php
614 file to include xmlseclibs as well.
617 #### Initiate SSO ####
619 In order to send an `AuthNRequest` to the IdP:
624 define("TOOLKIT_PATH", '/var/www/php-saml/');
625 require_once(TOOLKIT_PATH . '_toolkit_loader.php'); // We load the SAML2 lib
627 $auth = new OneLogin\Saml2\Auth(); // Constructor of the SP, loads settings.php
628 // and advanced_settings.php
629 $auth->login(); // Method that sent the AuthNRequest
632 The `AuthNRequest` will be sent signed or unsigned based on the security info
633 of the `advanced_settings.php` (`'authnRequestsSigned'`).
636 The IdP will then return the SAML Response to the user's client. The client is then forwarded to the Attribute Consumer Service of the SP with this information. If we do not set a `'url'` param in the login method and we are using the default ACS provided by the toolkit (`endpoints/acs.php`), then the ACS endpoint will redirect the user to the file that launched the SSO request.
638 We can set a `'returnTo'` url to change the workflow and redirect the user to the other PHP file.
641 $newTargetUrl = 'http://example.com/consume2.php';
642 $auth = new OneLogin\Saml2\Auth();
643 $auth->login($newTargetUrl);
646 The login method can receive other six optional parameters:
648 * `$parameters` - An array of parameters that will be added to the `GET` in the HTTP-Redirect.
649 * `$forceAuthn` - When true the `AuthNRequest` will set the `ForceAuthn='true'`
650 * `$isPassive` - When true the `AuthNRequest` will set the `Ispassive='true'`
651 * `$strict` - True if we want to stay (returns the url string) False to redirect
652 * `$setNameIdPolicy` - When true the AuthNRequest will set a nameIdPolicy element.
653 * `$nameIdValueReq` - Indicates to the IdP the subject that should be authenticated.
655 If a match on the future SAMLResponse ID and the AuthNRequest ID to be sent is required, that AuthNRequest ID must to be extracted and saved.
658 $ssoBuiltUrl = $auth->login(null, array(), false, false, true);
659 $_SESSION['AuthNRequestID'] = $auth->getLastRequestID();
660 header('Pragma: no-cache');
661 header('Cache-Control: no-cache, must-revalidate');
662 header('Location: ' . $ssoBuiltUrl);
666 #### The SP Endpoints ####
668 Related to the SP there are three important views: The metadata view, the ACS view and the SLS view. The toolkit
669 provides examples of those views in the endpoints directory.
671 ##### SP Metadata `endpoints/metadata.php` #####
673 This code will provide the XML metadata file of our SP, based on the info that we provided in the settings files.
678 define("TOOLKIT_PATH", '/var/www/php-saml/');
679 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
682 $auth = new OneLogin\Saml2\Auth();
683 $settings = $auth->getSettings();
684 $metadata = $settings->getSPMetadata();
685 $errors = $settings->validateMetadata($metadata);
686 if (empty($errors)) {
687 header('Content-Type: text/xml');
690 throw new OneLogin\Saml2\Error(
691 'Invalid SP metadata: '.implode(', ', $errors),
692 OneLogin\Saml2\Error::METADATA_SP_INVALID
695 } catch (Exception $e) {
696 echo $e->getMessage();
699 The `getSPMetadata` will return the metadata signed or not based
700 on the security info of the `advanced_settings.php` (`'signMetadata'`).
702 Before the XML metadata is exposed, a check takes place to ensure
703 that the info to be provided is valid.
705 Instead of use the Auth object, you can directly use
708 $settings = new OneLogin\Saml2\Settings($settingsInfo, true);
710 to get the settings object and with the true parameter we will avoid the IdP Settings validation.
713 ##### Attribute Consumer Service(ACS) `endpoints/acs.php` #####
715 This code handles the SAML response that the IdP forwards to the SP through the user's client.
720 session_start(); // IMPORTANT: This is required in order to be able
721 // to store the user data in the session.
723 define("TOOLKIT_PATH", '/var/www/php-saml/');
724 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
726 $auth = new OneLogin\Saml2\Auth();
728 if (isset($_SESSION) && isset($_SESSION['AuthNRequestID'])) {
729 $requestID = $_SESSION['AuthNRequestID'];
734 $auth->processResponse($requestID);
735 unset($_SESSION['AuthNRequestID']);
737 $errors = $auth->getErrors();
739 if (!empty($errors)) {
740 echo '<p>' . implode(', ', $errors) . '</p>';
744 if (!$auth->isAuthenticated()) {
745 echo "<p>Not authenticated</p>";
749 $_SESSION['samlUserdata'] = $auth->getAttributes();
750 $_SESSION['samlNameId'] = $auth->getNameId();
751 $_SESSION['samlNameIdFormat'] = $auth->getNameIdFormat();
752 $_SESSION['samlNameidNameQualifier'] = $auth->getNameIdNameQualifier();
753 $_SESSION['samlNameidSPNameQualifier'] = $auth->getNameIdSPNameQualifier();
754 $_SESSION['samlSessionIndex'] = $auth->getSessionIndex();
756 if (isset($_POST['RelayState']) && OneLogin\Saml2\Utils::getSelfURL() != $_POST['RelayState']) {
757 $auth->redirectTo($_POST['RelayState']);
760 $attributes = $_SESSION['samlUserdata'];
761 $nameId = $_SESSION['samlNameId'];
763 echo '<h1>Identified user: '. htmlentities($nameId) .'</h1>';
765 if (!empty($attributes)) {
766 echo '<h2>' . _('User attributes:') . '</h2>';
767 echo '<table><thead><th>' . _('Name') . '</th><th>' . _('Values') . '</th></thead><tbody>';
768 foreach ($attributes as $attributeName => $attributeValues) {
769 echo '<tr><td>' . htmlentities($attributeName) . '</td><td><ul>';
770 foreach ($attributeValues as $attributeValue) {
771 echo '<li>' . htmlentities($attributeValue) . '</li>';
773 echo '</ul></td></tr>';
775 echo '</tbody></table>';
777 echo _('No attributes found.');
781 The SAML response is processed and then checked that there are no errors.
782 It also verifies that the user is authenticated and stored the userdata in session.
784 At that point there are two possible alternatives:
786 1. If no `RelayState` is provided, we could show the user data in this view
787 or however we wanted.
789 2. If `RelayState` is provided, a redirection takes place.
791 Notice that we saved the user data in the session before the redirection to
792 have the user data available at the `RelayState` view.
795 ###### The `getAttributes` method ######
797 In order to retrieve attributes we can use:
800 $attributes = $auth->getAttributes();
803 With this method we get all the user data provided by the IdP in the Assertion
804 of the SAML Response.
806 If we execute ```print_r($attributes)``` we could get:
821 [0] => john.doe@example.com
831 Each attribute name can be used as an index into `$attributes` to obtain the value. Every attribute value
832 is an array - a single-valued attribute is an array of a single element.
835 The following code is equivalent:
838 $attributes = $auth->getAttributes();
839 print_r($attributes['cn']);
843 print_r($auth->getAttribute('cn'));
847 Before trying to get an attribute, check that the user is
848 authenticated. If the user isn't authenticated or if there were
849 no attributes in the SAML assertion, an empty array will be
850 returned. For example, if we call to `getAttributes` before a
851 `$auth->processResponse`, the `getAttributes()` will return an
855 ##### Single Logout Service (SLS) `endpoints/sls.php` #####
857 This code handles the Logout Request and the Logout Responses.
862 session_start(); // IMPORTANT: This is required in order to be able
863 // to close the user session.
865 define("TOOLKIT_PATH", '/var/www/php-saml/');
866 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
868 $auth = new OneLogin\Saml2\Auth();
870 if (isset($_SESSION) && isset($_SESSION['LogoutRequestID'])) {
871 $requestID = $_SESSION['LogoutRequestID'];
876 $auth->processSLO(false, $requestID);
878 $errors = $auth->getErrors();
880 if (empty($errors)) {
881 echo 'Sucessfully logged out';
883 echo implode(', ', $errors);
887 If the SLS endpoints receives a Logout Response, the response is
888 validated and the session could be closed
893 // part of the processSLO method
895 $logoutResponse = new OneLogin\Saml2\LogoutResponse($this->_settings, $_GET['SAMLResponse']);
896 if (!$logoutResponse->isValid($requestId)) {
897 $this->_errors[] = 'invalid_logout_response';
898 } else if ($logoutResponse->getStatus() !== OneLogin\Saml2\Constants::STATUS_SUCCESS) {
899 $this->_errors[] = 'logout_not_success';
901 if (!$keepLocalSession) {
902 OneLogin\Saml2\Utils::deleteLocalSession();
907 If the SLS endpoints receives an Logout Request, the request is validated,
908 the session is closed and a Logout Response is sent to the SLS endpoint of
912 // part of the processSLO method
914 $decoded = base64_decode($_GET['SAMLRequest']);
915 $request = gzinflate($decoded);
916 if (!OneLogin\Saml2\LogoutRequest::isValid($this->_settings, $request)) {
917 $this->_errors[] = 'invalid_logout_request';
919 if (!$keepLocalSession) {
920 OneLogin\Saml2\Utils::deleteLocalSession();
923 $inResponseTo = $request->id;
924 $responseBuilder = new OneLogin\Saml2\LogoutResponse($this->_settings);
925 $responseBuilder->build($inResponseTo);
926 $logoutResponse = $responseBuilder->getResponse();
928 $parameters = array('SAMLResponse' => $logoutResponse);
929 if (isset($_GET['RelayState'])) {
930 $parameters['RelayState'] = $_GET['RelayState'];
933 $security = $this->_settings->getSecurityData();
934 if (isset($security['logoutResponseSigned']) && $security['logoutResponseSigned']) {
935 $signature = $this->buildResponseSignature($logoutResponse, $parameters['RelayState'], $security['signatureAlgorithm']);
936 $parameters['SigAlg'] = $security['signatureAlgorithm'];
937 $parameters['Signature'] = $signature;
940 $this->redirectTo($this->getSLOurl(), $parameters);
944 If you aren't using the default PHP session, or otherwise need a manual
945 way to destroy the session, you can pass a callback method to the
946 `processSLO` method as the fourth parameter
949 $keepLocalSession = False;
950 $callback = function () {
951 // Destroy user session
954 $auth->processSLO($keepLocalSession, null, false, $callback);
958 If we don't want that `processSLO` to destroy the session, pass a true
959 parameter to the `processSLO` method
962 $keepLocalSession = True;
963 $auth->processSLO($keepLocalSession);
966 #### Initiate SLO ####
968 In order to send a Logout Request to the IdP:
973 define("TOOLKIT_PATH", '/var/www/php-saml/');
974 require_once(TOOLKIT_PATH . '_toolkit_loader.php');
976 $auth = new OneLogin\Saml2\Auth();
978 $auth->logout(); // Method that sent the Logout Request.
981 Also there are eight optional parameters that can be set:
982 * `$returnTo` - The target URL the user should be returned to after logout.
983 * `$parameters` - Extra parameters to be added to the GET.
984 * `$name_id` - That will be used to build the LogoutRequest. If `name_id` parameter is not set and the auth object processed a
985 SAML Response with a `NameId`, then this `NameId` will be used.
986 * `$session_index` - SessionIndex that identifies the session of the user.
987 * `$stay` - True if we want to stay (returns the url string) False to redirect.
988 * `$nameIdFormat` - The NameID Format will be set in the LogoutRequest.
989 * `$nameIdNameQualifier` - The NameID NameQualifier will be set in the LogoutRequest.
990 * `$nameIdSPNameQualifier` - The NameID SP NameQualifier will be set in the LogoutRequest.
992 The Logout Request will be sent signed or unsigned based on the security
993 info of the `advanced_settings.php` (`'logoutRequestSigned'`).
995 The IdP will return the Logout Response through the user's client to the
996 Single Logout Service of the SP.
997 If we do not set a `'url'` param in the logout method and are using the
998 default SLS provided by the toolkit (`endpoints/sls.php`), then the SLS
999 endpoint will redirect the user to the file that launched the SLO request.
1001 We can set an `'returnTo'` url to change the workflow and redirect the user
1005 $newTargetUrl = 'http://example.com/loggedOut.php';
1006 $auth = new OneLogin\Saml2\Auth();
1007 $auth->logout($newTargetUrl);
1009 A more complex logout with all the parameters:
1011 $auth = new OneLogin\Saml2\Auth();
1013 $parameters = array();
1015 $sessionIndex = null;
1016 $nameIdFormat = null;
1017 $nameIdNameQualifier = null;
1018 $nameIdSPNameQualifier = null;
1020 if (isset($_SESSION['samlNameId'])) {
1021 $nameId = $_SESSION['samlNameId'];
1023 if (isset($_SESSION['samlSessionIndex'])) {
1024 $sessionIndex = $_SESSION['samlSessionIndex'];
1026 if (isset($_SESSION['samlNameIdFormat'])) {
1027 $nameIdFormat = $_SESSION['samlNameIdFormat'];
1029 if (isset($_SESSION['samlNameIdNameQualifier'])) {
1030 $nameIdNameQualifier = $_SESSION['samlNameIdNameQualifier'];
1032 if (isset($_SESSION['samlNameIdSPNameQualifier'])) {
1033 $nameIdSPNameQualifier = $_SESSION['samlNameIdSPNameQualifier'];
1035 $auth->logout($returnTo, $parameters, $nameId, $sessionIndex, false, $nameIdFormat, $nameIdNameQualifier, $nameIdSPNameQualifier);
1038 If a match on the future LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must to be extracted and stored.
1041 $sloBuiltUrl = $auth->logout(null, $parameters, $nameId, $sessionIndex, true);
1042 $_SESSION['LogoutRequestID'] = $auth->getLastRequestID();
1043 header('Pragma: no-cache');
1044 header('Cache-Control: no-cache, must-revalidate');
1045 header('Location: ' . $sloBuiltUrl);
1049 #### Example of a view that initiates the SSO request and handles the response (is the acs target) ####
1051 We can code a unique file that initiates the SSO process, handle the response, get the attributes, initiate
1052 the SLO and processes the logout response.
1054 Note: Review the `demo1` folder that contains that use case; in a later section we
1055 explain the demo1 use case further in detail.
1060 session_start(); // Initialize the session, we do that because
1061 // Note that processResponse and processSLO
1062 // methods could manipulate/close that session
1064 require_once dirname(__DIR__) . '/_toolkit_loader.php'; // Load Saml2 and xmlseclibs
1065 require_once 'settings.php'; // Load the setting info as an Array
1067 $auth = new OneLogin\Saml2\Auth($settingsInfo); // Initialize the SP SAML instance
1069 if (isset($_GET['sso'])) { // SSO action. Will send an AuthNRequest to the IdP
1071 } else if (isset($_GET['sso2'])) { // Another SSO action
1072 $returnTo = $spBaseUrl.'/demo1/attrs.php'; // but set a custom RelayState URL
1073 $auth->login($returnTo);
1074 } else if (isset($_GET['slo'])) { // SLO action. Will sent a Logout Request to IdP
1076 } else if (isset($_GET['acs'])) { // Assertion Consumer Service
1077 $auth->processResponse(); // Process the Response of the IdP, get the
1078 // attributes and put then at
1079 // $_SESSION['samlUserdata']
1081 $errors = $auth->getErrors(); // This method receives an array with the errors
1082 // that could took place during the process
1084 if (!empty($errors)) {
1085 echo '<p>' . implode(', ', $errors) . '</p>';
1087 // This check if the response was
1088 if (!$auth->isAuthenticated()) { // sucessfully validated and the user
1089 echo '<p>Not authenticated</p>'; // data retrieved or not
1093 $_SESSION['samlUserdata'] = $auth->getAttributes(); // Retrieves user data
1094 if (isset($_POST['RelayState']) && OneLogin\Saml2\Utils::getSelfURL() != $_POST['RelayState']) {
1095 $auth->redirectTo($_POST['RelayState']); // Redirect if there is a
1097 } else if (isset($_GET['sls'])) { // Single Logout Service
1098 $auth->processSLO(); // Process the Logout Request & Logout Response
1099 $errors = $auth->getErrors(); // Retrieves possible validation errors
1100 if (empty($errors)) {
1101 echo '<p>Sucessfully logged out</p>';
1103 echo '<p>' . implode(', ', $errors) . '</p>';
1107 if (isset($_SESSION['samlUserdata'])) { // If there is user data we print it.
1108 if (!empty($_SESSION['samlUserdata'])) {
1109 $attributes = $_SESSION['samlUserdata'];
1110 echo 'You have the following attributes:<br>';
1111 echo '<table><thead><th>Name</th><th>Values</th></thead><tbody>';
1112 foreach ($attributes as $attributeName => $attributeValues) {
1113 echo '<tr><td>' . htmlentities($attributeName) . '</td><td><ul>';
1114 foreach ($attributeValues as $attributeValue) {
1115 echo '<li>' . htmlentities($attributeValue) . '</li>';
1117 echo '</ul></td></tr>';
1119 echo '</tbody></table>';
1120 } else { // If there is not user data, we notify
1121 echo "<p>You don't have any attribute</p>";
1124 echo '<p><a href="?slo" >Logout</a></p>'; // Print some links with possible
1126 echo '<p><a href="?sso" >Login</a></p>';
1127 echo '<p><a href="?sso2" >Login and access to attrs.php page</a></p>';
1131 #### URL-guessing methods ####
1133 php-saml toolkit uses a bunch of methods in OneLogin\Saml2\Utils that try to guess the URL where the SAML messages are processed.
1135 * `getSelfHost` Returns the current host.
1136 * `getSelfPort` Return the port number used for the request
1137 * `isHTTPS` Checks if the protocol is https or http.
1138 * `getSelfURLhost` Returns the protocol + the current host + the port (if different than common ports).
1139 * `getSelfURL` Returns the URL of the current host + current view + query.
1140 * `getSelfURLNoQuery` Returns the URL of the current host + current view.
1141 * `getSelfRoutedURLNoQuery` Returns the routed URL of the current host + current view.
1143 getSelfURLNoQuery and getSelfRoutedURLNoQuery are used to calculate the currentURL in order to validate SAML elements like Destination or Recipient.
1145 When the PHP application is behind a proxy or a load balancer we can execute `setProxyVars(true)` and `setSelfPort` and `isHTTPS` will take care of the `$_SERVER["HTTP_X_FORWARDED_PORT"]` and `$_SERVER['HTTP_X_FORWARDED_PROTO']` vars (otherwise they are ignored).
1147 Also a developer can use `setSelfProtocol`, `setSelfHost`, `setSelfPort` and `getBaseURLPath` to define a specific value to be returned by `isHTTPS`, `getSelfHost`, `getSelfPort` and `getBaseURLPath`. And define a `setBasePath` to be used on the `getSelfURL` and `getSelfRoutedURLNoQuery` to replace the data extracted from `$_SERVER["REQUEST_URI"]`.
1149 At the settings the developer will be able to set a `'baseurl'` parameter that automatically will use `setBaseURL` to set values for `setSelfProtocol`, `setSelfHost`, `setSelfPort` and `setBaseURLPath`.
1152 ### Working behind load balancer ###
1154 Is possible that asserting request URL and Destination attribute of SAML response fails when working behind load balancer with SSL offload.
1156 You should be able to workaround this by configuring your server so that it is aware of the proxy and returns the original url when requested.
1158 Or by using the method described on the previous section.
1161 ### SP Key rollover ###
1163 If you plan to update the SP x509cert and privateKey you can define the new x509cert as `$settings['sp']['x509certNew']` and it will be
1164 published on the SP metadata so Identity Providers can read them and get ready for rollover.
1167 ### IdP with multiple certificates ###
1169 In some scenarios the IdP uses different certificates for
1170 signing/encryption, or is under key rollover phase and more than one certificate is published on IdP metadata.
1172 In order to handle that the toolkit offers the `$settings['idp']['x509certMulti']` parameter.
1174 When that parameter is used, `'x509cert'` and `'certFingerprint'` values will be ignored by the toolkit.
1176 The `x509certMulti` is an array with 2 keys:
1177 - `signing`. An array of certs that will be used to validate IdP signature
1178 - `encryption` An array with one unique cert that will be used to encrypt data to be sent to the IdP
1181 ### Replay attacks ###
1183 In order to avoid replay attacks, you can store the ID of the SAML messages already processed, to avoid processing them twice. Since the Messages expires and will be invalidated due that fact, you don't need to store those IDs longer than the time frame that you currently accepting.
1185 Get the ID of the last processed message/assertion with the `getLastMessageId`/`getLastAssertionId` methods of the Auth object.
1188 ### Main classes and methods ###
1190 Described below are the main classes and methods that can be invoked.
1192 #### Saml2 library ####
1194 Lets describe now the classes and methods of the SAML2 library.
1196 ##### OneLogin\Saml2\Auth - Auth.php #####
1198 Main class of OneLogin PHP Toolkit
1200 * `Auth` - Initializes the SP SAML instance
1201 * `login` - Initiates the SSO process.
1202 * `logout` - Initiates the SLO process.
1203 * `processResponse` - Process the SAML Response sent by the IdP.
1204 * `processSLO` - Process the SAML Logout Response / Logout Request sent by the
1206 * `redirectTo` - Redirects the user to the url past by parameter or to the url
1207 that we defined in our SSO Request.
1208 * `isAuthenticated` - Checks if the user is authenticated or not.
1209 * `getAttributes` - Returns the set of SAML attributes.
1210 * `getAttribute` - Returns the requested SAML attribute
1211 * `getNameId` - Returns the nameID
1212 * `getNameIdFormat` - Gets the NameID Format provided by the SAML response from the IdP.
1213 * `getNameIdNameQualifier` - Gets the NameID NameQualifier provided from the SAML Response String.
1214 * `getNameIdSPNameQualifier` - Gets the NameID SP NameQualifier provided from the SAML Response String.
1215 * `getSessionIndex` - Gets the SessionIndex from the AuthnStatement.
1216 * `getErrors` - Returns if there were any error
1217 * `getSSOurl` - Gets the SSO url.
1218 * `getSLOurl` - Gets the SLO url.
1219 * `getLastRequestID` - The ID of the last Request SAML message generated.
1220 * `buildRequestSignature` - Generates the Signature for a SAML Request
1221 * `buildResponseSignature` - Generates the Signature for a SAML Response
1222 * `getSettings` - Returns the settings info
1223 * `setStrict` - Set the strict mode active/disable
1224 * `getLastRequestID` - Gets the ID of the last AuthNRequest or LogoutRequest generated by the Service Provider.
1225 * `getLastRequestXML` - Returns the most recently-constructed/processed XML SAML request (AuthNRequest, LogoutRequest)
1226 * `getLastResponseXML` - Returns the most recently-constructed/processed XML SAML response (SAMLResponse, LogoutResponse). If the SAMLResponse had an encrypted assertion, decrypts it.
1229 ##### OneLogin\Saml2\AuthnRequest - `AuthnRequest.php` #####
1231 SAML 2 Authentication Request class
1233 * `AuthnRequest` - Constructs the `AuthnRequest` object.
1234 * `getRequest` - Returns deflated, base64 encoded, unsigned `AuthnRequest`.
1235 * `getId` - Returns the `AuthNRequest` ID.
1236 * `getXML` - Returns the XML that will be sent as part of the request.
1238 ##### OneLogin\Saml2\Response - `Response.php` #####
1240 SAML 2 Authentication Response class
1242 * `Response` - Constructs the SAML Response object.
1243 * `isValid` - Determines if the SAML Response is valid using the certificate.
1244 * `checkStatus` - Checks if the Status is success.
1245 * `getAudiences` - Gets the audiences.
1246 * `getIssuers` - Gets the Issuers (from Response and Assertion)
1247 * `getNameIdData` - Gets the NameID Data provided by the SAML response from the
1249 * `getNameId` - Gets the NameID provided by the SAML response from the IdP.
1250 * `getNameIdFormat` - Gets the NameID Format provided by the SAML response from the IdP.
1251 * `getNameIdNameQualifier` - Gets the NameID NameQualifier provided from the SAML Response String.
1252 * `getNameIdSPNameQualifier` - Gets the NameID SP NameQualifier provided from the SAML Response String.
1253 * `getSessionNotOnOrAfter` - Gets the SessionNotOnOrAfter from the
1255 * `getSessionIndex` - Gets the SessionIndex from the AuthnStatement.
1256 * `getAttributes` - Gets the Attributes from the AttributeStatement element.
1257 * `validateNumAssertions` - Verifies that the document only contains a single
1258 Assertion (encrypted or not).
1259 * `validateTimestamps` - Verifies that the document is still valid according
1261 * `getError` - After executing a validation process, if it fails, this method returns the cause
1262 * `getXMLDocument` - Returns the SAML Response document (If contains an encrypted assertion, decrypts it)
1264 ##### OneLogin\Saml2\LogoutRequest - `LogoutRequest.php` #####
1266 SAML 2 Logout Request class
1268 * `LogoutRequest` - Constructs the Logout Request object.
1269 * `getRequest` - Returns the Logout Request defated, base64encoded, unsigned
1270 * `getID` - Returns the ID of the Logout Request. (If you have the object you can access to the id attribute)
1271 * `getNameIdData` - Gets the NameID Data of the the Logout Request.
1272 * `getNameId` - Gets the NameID of the Logout Request.
1273 * `getIssuer` - Gets the Issuer of the Logout Request.
1274 * `getSessionIndexes` - Gets the SessionIndexes from the Logout Request.
1275 * `isValid` - Checks if the Logout Request received is valid.
1276 * `getError` - After executing a validation process, if it fails, this method returns the cause
1277 * `getXML` - Returns the XML that will be sent as part of the request or that was received at the SP.
1279 ##### OneLogin\Saml2\LogoutResponse - `LogoutResponse.php` #####
1281 SAML 2 Logout Response class
1283 * `LogoutResponse` - Constructs a Logout Response object
1284 (Initialize params from settings and if provided load the Logout Response)
1285 * `getIssuer` - Gets the Issuer of the Logout Response.
1286 * `getStatus` - Gets the Status of the Logout Response.
1287 * `isValid` - Determines if the SAML LogoutResponse is valid
1288 * `build` - Generates a Logout Response object.
1289 * `getResponse` - Returns a Logout Response object.
1290 * `getError` - After executing a validation process, if it fails, this method returns the cause.
1291 * `getXML` - Returns the XML that will be sent as part of the response or that was received at the SP.
1293 ##### OneLogin\Saml2\Settings - `Settings.php` #####
1295 Configuration of the OneLogin PHP Toolkit
1297 * `Settings` - Initializes the settings: Sets the paths of
1298 the different folders and Loads settings info from settings file or
1299 array/object provided
1300 * `checkSettings` - Checks the settings info.
1301 * `getBasePath` - Returns base path.
1302 * `getCertPath` - Returns cert path.
1303 * `getLibPath` - Returns lib path.
1304 * `getExtLibPath` - Returns external lib path.
1305 * `getSchemasPath` - Returns schema path.
1306 * `checkSPCerts` - Checks if the x509 certs of the SP exists and are valid.
1307 * `getSPkey` - Returns the x509 private key of the SP.
1308 * `getSPcert` - Returns the x509 public cert of the SP.
1309 * `getSPcertNew` - Returns the future x509 public cert of the SP.
1310 * `getIdPData` - Gets the IdP data.
1311 * `getSPData`Gets the SP data.
1312 * `getSecurityData` - Gets security data.
1313 * `getContacts` - Gets contact data.
1314 * `getOrganization` - Gets organization data.
1315 * `getSPMetadata` - Gets the SP metadata. The XML representation.
1316 * `validateMetadata` - Validates an XML SP Metadata.
1317 * `formatIdPCert` - Formats the IdP cert.
1318 * `formatSPCert` - Formats the SP cert.
1319 * `formatSPCertNew` - Formats the SP cert new.
1320 * `formatSPKey` - Formats the SP private key.
1321 * `getErrors` - Returns an array with the errors, the array is empty when
1323 * `getLastErrorReason` - Returns the reason of the last error
1324 * `getBaseURL` - Returns the baseurl set on the settings if any.
1325 * `setBaseURL` - Set a baseurl value
1326 * `setStrict` - Activates or deactivates the strict mode.
1327 * `isStrict` - Returns if the 'strict' mode is active.
1328 * `isDebugActive` - Returns if the debug is active.
1330 ##### OneLogin\Saml2\Metadata - `Metadata.php` #####
1332 A class that contains functionality related to the metadata of the SP
1334 * `builder` - Generates the metadata of the SP based on the settings.
1335 * `signmetadata` - Signs the metadata with the key/cert provided
1336 * `addX509KeyDescriptors` - Adds the x509 descriptors (sign/encriptation) to
1339 ##### OneLogin\Saml2\Utils - `Utils.php` #####
1341 Auxiliary class that contains several methods
1343 * `validateXML` - This function attempts to validate an XML string against
1344 the specified schema.
1345 * `formatCert` - Returns a x509 cert (adding header & footer if required).
1346 * `formatPrivateKey` - returns a RSA private key (adding header & footer if required).
1347 * `redirect` - Executes a redirection to the provided url (or return the
1349 * `isHTTPS` - Checks if https or http.
1350 * `getSelfHost` - Returns the current host.
1351 * `getSelfURLhost` - Returns the protocol + the current host + the port
1352 (if different than common ports).
1353 * `getSelfURLNoQuery` - Returns the URL of the current host + current view.
1354 * `getSelfURL` - Returns the URL of the current host + current view + query.
1355 * `generateUniqueID` - Generates a unique string (used for example as ID
1357 * `parseTime2SAML` - Converts a UNIX timestamp to SAML2 timestamp on the
1358 form `yyyy-mm-ddThh:mm:ss(\.s+)?Z`.
1359 * `parseSAML2Time` - Converts a SAML2 timestamp on the form
1360 `yyyy-mm-ddThh:mm:ss(\.s+)?Z` to a UNIX timestamp. The sub-second part is
1362 * `parseDuration` - Interprets a ISO8601 duration value relative to a given
1364 * `getExpireTime` - Compares two dates and returns the earliest.
1365 * `query` - Extracts nodes from the DOMDocument.
1366 * `isSessionStarted` - Checks if the session is started or not.
1367 * `deleteLocalSession` - Deletes the local session.
1368 * `calculateX509Fingerprint` - Calculates the fingerprint of a x509cert.
1369 * `formatFingerPrint` - Formats a fingerprint.
1370 * `generateNameId` - Generates a `nameID`.
1371 * `getStatus` - Gets Status from a Response.
1372 * `decryptElement` - Decrypts an encrypted element.
1373 * `castKey` - Converts a `XMLSecurityKey` to the correct algorithm.
1374 * `addSign` - Adds signature key and senders certificate to an element
1375 (Message or Assertion).
1376 * `validateSign` - Validates a signature (Message or Assertion).
1378 ##### OneLogin\Saml2\IdPMetadataParser - `IdPMetadataParser.php` #####
1380 Auxiliary class that contains several methods to retrieve and process IdP metadata
1382 * `parseRemoteXML` - Get IdP Metadata Info from URL.
1383 * `parseFileXML` - Get IdP Metadata Info from File.
1384 * `parseXML` - Get IdP Metadata Info from XML.
1385 * `injectIntoSettings` - Inject metadata info into php-saml settings array.
1388 For more info, look at the source code; each method is documented and details
1389 about what it does and how to use it are provided. Make sure to also check the doc folder where
1390 HTML documentation about the classes and methods is provided for SAML and
1394 Demos included in the toolkit
1395 -----------------------------
1397 The toolkit includes three demo apps to teach how use the toolkit, take a look on it.
1399 Demos require that SP and IdP are well configured before test it.
1405 The Onelogin's PHP Toolkit allows you to provide the settings info in two ways:
1407 * Use a `settings.php` file that we should locate at the base folder of the
1409 * Use an array with the setting data.
1411 In this demo we provide the data in the second way, using a setting array named
1412 `$settingsInfo`. This array users the `settings_example.php` included as a template
1413 to create the `settings.php` settings and store it in the `demo1/` folder.
1414 Configure the SP part and later review the metadata of the IdP and complete the IdP info.
1416 If you check the code of the index.php file you will see that the `settings.php`
1417 file is loaded in order to get the `$settingsInfo` var to be used in order to initialize
1418 the `Setting` class.
1420 Notice that in this demo, the `setting.php` file that could be defined at the base
1421 folder of the toolkit is ignored and the libs are loaded using the
1422 `_toolkit_loader.php` located at the base folder of the toolkit.
1427 Once the SP is configured, the metadata of the SP is published at the
1428 `metadata.php` file. Configure the IdP based on that information.
1431 ### How it works ###
1433 1. First time you access to `index.php` view, you can select to login and return
1434 to the same view or login and be redirected to the `attrs.php` view.
1438 2.1 in the first link, we access to (`index.php?sso`) an `AuthNRequest`
1439 is sent to the IdP, we authenticate at the IdP and then a Response is sent
1440 through the user's client to the SP, specifically the Assertion Consumer Service view: `index.php?acs`.
1441 Notice that a `RelayState` parameter is set to the url that initiated the
1442 process, the `index.php` view.
1444 2.2 in the second link we access to (`attrs.php`) have the same process
1445 described at 2.1 with the difference that as `RelayState` is set the `attrs.php`.
1447 3. The SAML Response is processed in the ACS (`index.php?acs`), if the Response
1448 is not valid, the process stops here and a message is shown. Otherwise we
1449 are redirected to the RelayState view. a) `index.php` or b) `attrs.php`.
1451 4. We are logged in the app and the user attributes are showed.
1452 At this point, we can test the single log out functionality.
1454 5. The single log out functionality could be tested by two ways.
1456 5.1 SLO Initiated by SP. Click on the "logout" link at the SP, after that a
1457 Logout Request is sent to the IdP, the session at the IdP is closed and
1458 replies through the client to the SP with a Logout Response (sent to the
1459 Single Logout Service endpoint). The SLS endpoint (`index.php?sls`) of the SP
1460 process the Logout Response and if is valid, close the user session of the
1461 local app. Notice that the SLO Workflow starts and ends at the SP.
1463 5.2 SLO Initiated by IdP. In this case, the action takes place on the IdP
1464 side, the logout process is initiated at the idP, sends a Logout
1465 Request to the SP (SLS endpoint, `index.php?sls`). The SLS endpoint of the SP
1466 process the Logout Request and if is valid, close the session of the user
1467 at the local app and send a Logout Response to the IdP (to the SLS endpoint
1468 of the IdP). The IdP receives the Logout Response, process it and close the
1469 session at of the IdP. Notice that the SLO Workflow starts and ends at the IdP.
1471 Notice that all the SAML Requests and Responses are handled by a unique file,
1472 the `index.php` file and how `GET` parameters are used to know the action that
1480 The Onelogin's PHP Toolkit allows you to provide the settings info in two ways:
1482 * Use a `settings.php` file that we should locate at the base folder of the
1484 * Use an array with the setting data.
1486 The first is the case of the demo2 app. The `setting.php` file and the
1487 `setting_extended.php` file should be defined at the base folder of the toolkit.
1488 Review the `setting_example.php` and the `advanced_settings_example.php` to
1489 learn how to build them.
1491 In this case as Attribute Consume Service and Single Logout Service we are going to
1492 use the files located in the endpoint folder (`acs.php` and `sls.php`).
1497 Once the SP is configured, the metadata of the SP is published at the
1498 `metadata.php` file. Based on that info, configure the IdP.
1501 ### How it works ###
1503 At demo1, we saw how all the SAML Request and Responses were handler at an
1504 unique file, the `index.php` file. This demo1 uses high-level programming.
1506 At demo2, we have several views: `index.php`, `sso.php`, `slo.php`, `consume.php`
1507 and `metadata.php`. As we said, we will use the endpoints that are defined
1508 in the toolkit (`acs.php`, `sls.php` of the endpoints folder). This demo2 uses
1509 low-level programming.
1511 Notice that the SSO action can be initiated at `index.php` or `sso.php`.
1513 The SAML workflow that take place is similar that the workflow defined in the
1514 demo1, only changes the targets.
1516 1. When you access `index.php` or `sso.php` for the first time, an `AuthNRequest` is
1517 sent to the IdP automatically, (as `RelayState` is sent the origin url).
1518 We authenticate at the IdP and then a `Response` is sent to the SP, to the
1519 ACS endpoint, in this case `acs.php` of the endpoints folder.
1521 2. The SAML Response is processed in the ACS, if the `Response` is not valid,
1522 the process stops here and a message is shown. Otherwise we are redirected
1523 to the `RelayState` view (`sso.php` or `index.php`). The `sso.php` detects if the
1524 user is logged and redirects to `index.php`, so we will be in the
1525 `index.php` at the end.
1527 3. We are logged into the app and the user attributes (if any) are shown.
1528 At this point, we can test the single log out functionality.
1530 4. The single log out functionality could be tested by two ways.
1532 4.1 SLO Initiated by SP. Click on the "logout" link at the SP, after that
1533 we are redirected to the `slo.php` view and there a Logout Request is sent
1534 to the IdP, the session at the IdP is closed and replies to the SP a
1535 Logout Response (sent to the Single Logout Service endpoint). In this case
1536 The SLS endpoint of the SP process the Logout Response and if is
1537 valid, close the user session of the local app. Notice that the SLO
1538 Workflow starts and ends at the SP.
1540 4.2 SLO Initiated by IdP. In this case, the action takes place on the IdP
1541 side, the logout process is initiated at the idP, sends a Logout
1542 Request to the SP (SLS endpoint `sls.php` of the endpoint folder).
1543 The SLS endpoint of the SP process the Logout Request and if is valid,
1544 close the session of the user at the local app and sends a Logout Response
1545 to the IdP (to the SLS endpoint of the IdP).The IdP receives the Logout
1546 Response, process it and close the session at of the IdP. Notice that the
1547 SLO Workflow starts and ends at the IdP.