]> git.mxchange.org Git - friendica-addons.git/blob - saml/vendor/onelogin/php-saml/README.md
Add SAML addon.
[friendica-addons.git] / saml / vendor / onelogin / php-saml / README.md
1 # OneLogin's SAML PHP Toolkit Compatible with PHP 7.X & 8.X
2
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)
4
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.
8
9
10 Warning
11 -------
12
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)
14
15 Security Guidelines
16 -------------------
17
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.
19
20
21 Why add SAML support to my software?
22 ------------------------------------
23
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:
27
28  * **Usability** - One-click access from portals or intranets, deep linking,
29    password elimination and automatically renewing sessions make life
30    easier for the user.
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
40    integration easier.
41  * **Opportunity** - B2B cloud vendor should support SAML to facilitate the
42    integration of their product.
43
44
45 General description
46 -------------------
47
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).
50
51 Supports:
52
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).
60
61 Key features:
62
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.
70
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)
72
73 Installation
74 ------------
75
76 ### Dependencies ###
77
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.
82
83 ### Code ###
84
85 #### Option 1. clone the repository from  github ####
86
87 git clone git@github.com:onelogin/php-saml.git
88
89 Then pull the 3.X.X branch/tag
90
91 #### Option 2. Download from github ####
92
93 The toolkit is hosted on github. You can download it from:
94
95  * https://github.com/onelogin/php-saml/releases
96
97 Search for 3.X.X releases
98
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.
102
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.
105
106 #### Option 3. Composer ####
107
108 The toolkit supports [composer](https://getcomposer.org/). You can find the `onelogin/php-saml` package at https://packagist.org/packages/onelogin/php-saml
109
110 In order to import the saml toolkit to your current php project, execute
111 ```
112 composer require onelogin/php-saml
113 ```
114
115 Remember to select the 3.X.X branch
116
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`.
118
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`.
121
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.
123
124 Compatibility
125 -------------
126
127 This 4.X.X supports PHP >=7.3 .
128
129 It is not compatible with PHP5.6 or PHP7.0.
130
131 Namespaces
132 ----------
133
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:
137
138     \OneLogin\Saml2\Utils::getSelfURLNoQuery()
139
140
141 Security warning
142 ----------------
143
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.
148
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.
150
151 Getting started
152 ---------------
153
154 ### Knowing the toolkit ###
155
156 The new OneLogin SAML Toolkit contains different folders (`certs`, `endpoints`,
157 `lib`, `demo`, etc.) and some files.
158
159 Let's start describing the folders:
160
161 #### `certs/` ####
162
163 SAML requires a x509 cert to sign and encrypt elements like `NameID`, `Message`,
164 `Assertion`, `Metadata`.
165
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:
168
169  * `sp.crt` - The public cert of the SP
170  * `sp.key` - The private key of the SP
171
172 Or also we can provide those data in the setting file at the `$settings['sp']['x509cert']`
173 and the `$settings['sp']['privateKey']`.
174
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`.
178
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.
181
182 #### `src/` ####
183
184 This folder contains the heart of the toolkit, the libraries:
185
186  * `Saml2` folder contains the new version of the classes and methods that
187    are described in a later section.
188
189
190 #### `doc/` ####
191
192 This folder contains the API documentation of the toolkit.
193
194
195 #### `endpoints/` ####
196
197 The toolkit has three endpoints:
198
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
202    Responses.
203
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.
207
208
209 #### `locale/` ####
210
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.
214
215
216 #### Other important files ####
217
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).
224
225
226 #### Miscellaneous ####
227
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.
232
233
234 ### How it works ###
235
236 #### Settings ####
237
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
240 encryption.
241
242 There are two ways to provide the settings information:
243
244  * Use a `settings.php` file that we should locate at the base folder of the
245    toolkit.
246  * Use an array with the setting data and provide it directly to the
247    constructor of the class.
248
249
250 There is a template file, `settings_example.php`, so you can make a copy of this
251 file, rename and edit it.
252
253 ```php
254 <?php
255
256 $settings = array(
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.
261     'strict' => true,
262
263     // Enable debug mode (to print errors).
264     'debug' => false,
265
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/
270     'baseurl' => null,
271
272     // Service Provider Data that we are deploying.
273     'sp' => array(
274         // Identifier of the SP entity  (must be a URI)
275         'entityId' => '',
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
280             'url' => '',
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',
285         ),
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(
293                     array(
294                         "name" => "",
295                         "isRequired" => false,
296                         "nameFormat" => "",
297                         "friendlyName" => "",
298                         "attributeValue" => array()
299                     )
300                 )
301         ),
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
306             'url' => '',
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',
311         ),
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
318         'x509cert' => '',
319         'privateKey' => '',
320
321         /*
322          * Key rollover
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.
327          */
328         // 'x509certNew' => '',
329     ),
330
331     // Identity Provider Data that we want connected with our SP.
332     'idp' => array(
333         // Identifier of the IdP entity  (must be a URI)
334         'entityId' => '',
335         // SSO endpoint info of the IdP. (Authentication Request protocol)
336         'singleSignOnService' => array(
337             // URL Target of the IdP where the Authentication Request Message
338             // will be sent.
339             'url' => '',
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',
344         ),
345         // SLO endpoint info of the IdP.
346         'singleLogoutService' => array(
347             // URL Location of the IdP where SLO Request will be sent.
348             'url' => '',
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
351             'responseUrl' => '',
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',
356         ),
357         // Public x509 certificate of the IdP
358         'x509cert' => '',
359         /*
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)
365          *
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.
369          *
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.
372          */
373         // 'certFingerprint' => '',
374         // 'certFingerprintAlgorithm' => 'sha1',
375
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
381          * ignored).
382          */
383         // 'x509certMulti' => array(
384         //      'signing' => array(
385         //          0 => '<cert1-string>',
386         //      ),
387         //      'encryption' => array(
388         //          0 => '<cert2-string>',
389         //      )
390         // ),
391     ),
392 );
393 ```
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`
399
400 ```php
401 <?php
402
403 $advancedSettings = array(
404
405     // Compression settings
406     'compress' => array(
407         'requests' => true,
408         'responses' => true
409     ),
410     // Security settings
411     'security' => array(
412
413         /** signatures and encryptions offered */
414
415         // Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
416         // will be encrypted.
417         'nameIdEncrypted' => false,
418
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,
422
423         // Indicates whether the <samlp:logoutRequest> messages sent by this SP
424         // will be signed.
425         'logoutRequestSigned' => false,
426
427         // Indicates whether the <samlp:logoutResponse> messages sent by this SP
428         // will be signed.
429         'logoutResponseSigned' => false,
430
431         /* Sign the Metadata
432          False || True (use sp certs) || array (
433                                                     'keyFileName' => 'metadata.key',
434                                                     'certFileName' => 'metadata.crt'
435                                                )
436                                       || array (
437                                                     'x509cert' => '',
438                                                     'privateKey' => ''
439                                                )
440         */
441         'signMetadata' => false,
442
443         /** signatures and encryptions required **/
444
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,
448
449         // Indicates a requirement for the <saml:Assertion> elements received by
450         // this SP to be encrypted.
451         'wantAssertionsEncrypted' => false,
452
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,
456
457         // Indicates a requirement for the NameID element on the SAMLResponse
458         // received by this SP to be present.
459         'wantNameId' => true,
460
461         // Indicates a requirement for the NameID received by
462         // this SP to be encrypted.
463         'wantNameIdEncrypted' => false,
464
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,
470
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,
474
475         // If true, SAMLResponses with an empty value at its Destination
476         // attribute will not be rejected for this fact.
477         'relaxDestinationValidation' => false,
478
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
482         // will be accepted.
483         'destinationStrictlyMatches' => false,
484
485         // If true, the toolkit will not raised an error when the Statement Element
486         // contain atribute elements with name duplicated
487         'allowRepeatAttributeName' => false,
488
489         // If true, SAMLResponses with an InResponseTo value will be rejectd if not
490         // AuthNRequest ID provided to the validation method.
491         'rejectUnsolicitedResponsesWithInResponseTo' => false,
492
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',
501
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',
509
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',
520
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,
524     ),
525
526     // Contact information template, it is recommended to supply a
527     // technical and support contacts.
528     'contactPerson' => array(
529         'technical' => array(
530             'givenName' => '',
531             'emailAddress' => ''
532         ),
533         'support' => array(
534             'givenName' => '',
535             'emailAddress' => ''
536         ),
537     ),
538
539     // Organization information template, the info in en_US lang is
540     // recomended, add more if required.
541     'organization' => array(
542         'en-US' => array(
543             'name' => '',
544             'displayname' => '',
545             'url' => ''
546         ),
547     ),
548 );
549 ```
550
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.
554
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.
559
560 Once we know what kind of data could be configured, let's talk about the way
561 settings are handled within the toolkit.
562
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.
565
566 ```php
567 // Initializes toolkit with settings.php & advanced_settings files.
568 $auth = new OneLogin\Saml2\Auth();
569 //or
570 $settings = new OneLogin\Saml2\Settings();
571
572 // Initializes toolkit with the array provided.
573 $auth = new OneLogin\Saml2\Auth($settingsInfo);
574 //or
575 $settings = new OneLogin\Saml2\Settings($settingsInfo);
576 ```
577
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:
581
582 ```php
583 <?php
584
585 require_once 'custom_settings.php';  // The custom_settings.php contains a
586                                      // $settingsInfo array.
587
588 $auth = new OneLogin\Saml2\Auth($settingsInfo);
589 ```
590
591
592 #### How load the library ####
593
594
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.
597
598
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:
601
602 ```php
603 <?php
604
605 define("TOOLKIT_PATH", '/var/www/php-saml/');
606 require_once(TOOLKIT_PATH . '_toolkit_loader.php');
607 ```
608
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).
611
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.
615
616
617 #### Initiate SSO ####
618
619 In order to send an `AuthNRequest` to the IdP:
620
621 ```php
622 <?php
623
624 define("TOOLKIT_PATH", '/var/www/php-saml/');
625 require_once(TOOLKIT_PATH . '_toolkit_loader.php');   // We load the SAML2 lib
626
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
630 ```
631
632 The `AuthNRequest` will be sent signed or unsigned based on the security info
633 of the `advanced_settings.php` (`'authnRequestsSigned'`).
634
635
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.
637
638 We can set a `'returnTo'` url to change the workflow and redirect the user to the other PHP file.
639
640 ```php
641 $newTargetUrl = 'http://example.com/consume2.php';
642 $auth = new OneLogin\Saml2\Auth();
643 $auth->login($newTargetUrl);
644 ```
645
646 The login method can receive other six optional parameters:
647
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.
654
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.
656
657 ```php
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);
663 exit();
664 ```
665
666 #### The SP Endpoints ####
667
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.
670
671 ##### SP Metadata `endpoints/metadata.php` #####
672
673 This code will provide the XML metadata file of our SP, based on the info that we provided in the settings files.
674
675 ```php
676 <?php
677
678 define("TOOLKIT_PATH", '/var/www/php-saml/');
679 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
680
681 try {
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');
688         echo $metadata;
689     } else {
690         throw new OneLogin\Saml2\Error(
691             'Invalid SP metadata: '.implode(', ', $errors),
692             OneLogin\Saml2\Error::METADATA_SP_INVALID
693         );
694     }
695 } catch (Exception $e) {
696     echo $e->getMessage();
697 }
698 ```
699 The `getSPMetadata` will return the metadata signed or not based
700 on the security info of the `advanced_settings.php` (`'signMetadata'`).
701
702 Before the XML metadata is exposed, a check takes place to ensure
703 that the info to be provided is valid.
704
705 Instead of use the Auth object, you can directly use
706
707 ```php
708 $settings = new OneLogin\Saml2\Settings($settingsInfo, true);
709 ```
710 to get the settings object and with the true parameter we will avoid the IdP Settings validation.
711
712
713 ##### Attribute Consumer Service(ACS) `endpoints/acs.php` #####
714
715 This code handles the SAML response that the IdP forwards to the SP through the user's client.
716
717 ```php
718 <?php
719
720 session_start();  // IMPORTANT: This is required in order to be able
721                   // to store the user data in the session.
722
723 define("TOOLKIT_PATH", '/var/www/php-saml/');
724 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
725
726 $auth = new OneLogin\Saml2\Auth();
727
728 if (isset($_SESSION) && isset($_SESSION['AuthNRequestID'])) {
729     $requestID = $_SESSION['AuthNRequestID'];
730 } else {
731     $requestID = null;
732 }
733
734 $auth->processResponse($requestID);
735 unset($_SESSION['AuthNRequestID']);
736
737 $errors = $auth->getErrors();
738
739 if (!empty($errors)) {
740     echo '<p>' . implode(', ', $errors) . '</p>';
741     exit();
742 }
743
744 if (!$auth->isAuthenticated()) {
745     echo "<p>Not authenticated</p>";
746     exit();
747 }
748
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();
755
756 if (isset($_POST['RelayState']) && OneLogin\Saml2\Utils::getSelfURL() != $_POST['RelayState']) {
757     $auth->redirectTo($_POST['RelayState']);
758 }
759
760 $attributes = $_SESSION['samlUserdata'];
761 $nameId = $_SESSION['samlNameId'];
762
763 echo '<h1>Identified user: '. htmlentities($nameId) .'</h1>';
764
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>';
772         }
773         echo '</ul></td></tr>';
774     }
775     echo '</tbody></table>';
776 } else {
777     echo _('No attributes found.');
778 }
779 ```
780
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.
783
784 At that point there are two possible alternatives:
785
786  1. If no `RelayState` is provided, we could show the user data in this view
787  or however we wanted.
788
789  2. If `RelayState` is provided, a redirection takes place.
790
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.
793
794
795 ###### The `getAttributes` method ######
796
797 In order to retrieve attributes we can use:
798
799 ```php
800 $attributes = $auth->getAttributes();
801 ```
802
803 With this method we get all the user data provided by the IdP in the Assertion
804 of the SAML Response.
805
806 If we execute ```print_r($attributes)``` we could get:
807
808 ```php
809 Array
810 (
811     [cn] => Array
812         (
813             [0] => John
814         )
815     [sn] => Array
816         (
817             [0] => Doe
818         )
819     [mail] => Array
820         (
821             [0] => john.doe@example.com
822         )
823     [groups] => Array
824         (
825             [0] => users
826             [1] => members
827         )
828 )
829 ```
830
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.
833
834
835 The following code is equivalent:
836
837 ```php
838 $attributes = $auth->getAttributes();
839 print_r($attributes['cn']);
840 ```
841
842 ```php
843 print_r($auth->getAttribute('cn'));
844 ```
845
846
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
852 empty array.
853
854
855 ##### Single Logout Service (SLS) `endpoints/sls.php` #####
856
857 This code handles the Logout Request and the Logout Responses.
858
859 ```php
860 <?php
861
862 session_start();  // IMPORTANT: This is required in order to be able
863                   // to close the user session.
864
865 define("TOOLKIT_PATH", '/var/www/php-saml/');
866 require_once dirname(TOOLKIT_PATH.'/_toolkit_loader.php';
867
868 $auth = new OneLogin\Saml2\Auth();
869
870 if (isset($_SESSION) && isset($_SESSION['LogoutRequestID'])) {
871     $requestID = $_SESSION['LogoutRequestID'];
872 } else {
873     $requestID = null;
874 }
875
876 $auth->processSLO(false, $requestID);
877
878 $errors = $auth->getErrors();
879
880 if (empty($errors)) {
881     echo 'Sucessfully logged out';
882 } else {
883     echo implode(', ', $errors);
884 }
885 ```
886
887 If the SLS endpoints receives a Logout Response, the response is
888 validated and the session could be closed
889
890
891
892 ```php
893 // part of the processSLO method
894
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';
900 } else {
901     if (!$keepLocalSession) {
902         OneLogin\Saml2\Utils::deleteLocalSession();
903     }
904 }
905 ```
906
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
909 the IdP.
910
911 ```php
912 // part of the processSLO method
913
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';
918 } else {
919     if (!$keepLocalSession) {
920         OneLogin\Saml2\Utils::deleteLocalSession();
921     }
922
923     $inResponseTo = $request->id;
924     $responseBuilder = new OneLogin\Saml2\LogoutResponse($this->_settings);
925     $responseBuilder->build($inResponseTo);
926     $logoutResponse = $responseBuilder->getResponse();
927
928     $parameters = array('SAMLResponse' => $logoutResponse);
929     if (isset($_GET['RelayState'])) {
930         $parameters['RelayState'] = $_GET['RelayState'];
931     }
932
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;
938     }
939
940     $this->redirectTo($this->getSLOurl(), $parameters);
941 }
942 ```
943
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
947
948 ```php
949 $keepLocalSession = False;
950 $callback = function () {
951     // Destroy user session
952 };
953
954 $auth->processSLO($keepLocalSession, null, false, $callback);
955 ```
956
957
958 If we don't want that `processSLO` to destroy the session, pass a true
959 parameter to the `processSLO` method
960
961 ```php
962 $keepLocalSession = True;
963 $auth->processSLO($keepLocalSession);
964 ```
965
966 #### Initiate SLO ####
967
968 In order to send a Logout Request to the IdP:
969
970 ```php
971 <?php
972
973 define("TOOLKIT_PATH", '/var/www/php-saml/');
974 require_once(TOOLKIT_PATH . '_toolkit_loader.php');
975
976 $auth = new OneLogin\Saml2\Auth();
977
978 $auth->logout();   // Method that sent the Logout Request.
979 ```
980
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.
991
992 The Logout Request will be sent signed or unsigned based on the security
993 info of the `advanced_settings.php` (`'logoutRequestSigned'`).
994
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.
1000
1001 We can set an `'returnTo'` url to change the workflow and redirect the user
1002 to other php file.
1003
1004 ```php
1005 $newTargetUrl = 'http://example.com/loggedOut.php';
1006 $auth = new OneLogin\Saml2\Auth();
1007 $auth->logout($newTargetUrl);
1008 ```
1009 A more complex logout with all the parameters:
1010 ```
1011 $auth = new OneLogin\Saml2\Auth();
1012 $returnTo = null;
1013 $parameters = array();
1014 $nameId = null;
1015 $sessionIndex = null;
1016 $nameIdFormat = null;
1017 $nameIdNameQualifier = null;
1018 $nameIdSPNameQualifier = null;
1019
1020 if (isset($_SESSION['samlNameId'])) {
1021     $nameId = $_SESSION['samlNameId'];
1022 }
1023 if (isset($_SESSION['samlSessionIndex'])) {
1024     $sessionIndex = $_SESSION['samlSessionIndex'];
1025 }
1026 if (isset($_SESSION['samlNameIdFormat'])) {
1027     $nameIdFormat = $_SESSION['samlNameIdFormat'];
1028 }
1029 if (isset($_SESSION['samlNameIdNameQualifier'])) {
1030     $nameIdNameQualifier = $_SESSION['samlNameIdNameQualifier'];
1031 }
1032 if (isset($_SESSION['samlNameIdSPNameQualifier'])) {
1033     $nameIdSPNameQualifier = $_SESSION['samlNameIdSPNameQualifier'];
1034 }
1035 $auth->logout($returnTo, $parameters, $nameId, $sessionIndex, false, $nameIdFormat, $nameIdNameQualifier, $nameIdSPNameQualifier);
1036 ```
1037
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.
1039
1040 ```php
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);
1046 exit();
1047 ```
1048
1049 #### Example of a view that initiates the SSO request and handles the response (is the acs target) ####
1050
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.
1053
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.
1056
1057 ```php
1058 <?php
1059
1060 session_start();    // Initialize the session, we do that because
1061                     // Note that processResponse and processSLO
1062                     // methods could manipulate/close that session
1063
1064 require_once dirname(__DIR__) . '/_toolkit_loader.php'; // Load Saml2 and xmlseclibs
1065 require_once 'settings.php';    // Load the setting info as an Array
1066
1067 $auth = new OneLogin\Saml2\Auth($settingsInfo);  // Initialize the SP SAML instance
1068
1069 if (isset($_GET['sso'])) {    // SSO action.  Will send an AuthNRequest to the IdP
1070     $auth->login();
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
1075     $auth->logout();
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']
1080
1081     $errors = $auth->getErrors();  // This method receives an array with the errors
1082                                    // that could took place during the process
1083
1084     if (!empty($errors)) {
1085         echo '<p>' . implode(', ', $errors) . '</p>';
1086     }
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
1090         exit();
1091     }
1092
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
1096     }                                             // relayState set
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>';
1102     } else {
1103         echo '<p>' . implode(', ', $errors) . '</p>';
1104     }
1105 }
1106
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>';
1116             }
1117             echo '</ul></td></tr>';
1118         }
1119         echo '</tbody></table>';
1120     } else {                             // If there is not user data, we notify
1121         echo "<p>You don't have any attribute</p>";
1122     }
1123
1124     echo '<p><a href="?slo" >Logout</a></p>'; // Print some links with possible
1125 } else {                                      // actions
1126     echo '<p><a href="?sso" >Login</a></p>';
1127     echo '<p><a href="?sso2" >Login and access to attrs.php page</a></p>';
1128 }
1129 ```
1130
1131 #### URL-guessing methods ####
1132
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.
1134
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.
1142
1143 getSelfURLNoQuery and getSelfRoutedURLNoQuery are used to calculate the currentURL in order to validate SAML elements like Destination or Recipient.
1144
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).
1146
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"]`.
1148
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`.
1150
1151
1152 ### Working behind load balancer ###
1153
1154 Is possible that asserting request URL and Destination attribute of SAML response fails when working behind load balancer with SSL offload.
1155
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.
1157
1158 Or by using the method described on the previous section.
1159
1160
1161 ### SP Key rollover ###
1162
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.
1165
1166
1167 ### IdP with multiple certificates ###
1168
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.
1171
1172 In order to handle that the toolkit offers the `$settings['idp']['x509certMulti']` parameter.
1173
1174 When that parameter is used, `'x509cert'` and `'certFingerprint'` values will be ignored by the toolkit.
1175
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
1179
1180
1181 ### Replay attacks ###
1182
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.
1184
1185 Get the ID of the last processed message/assertion with the `getLastMessageId`/`getLastAssertionId` methods of the Auth object.
1186
1187
1188 ### Main classes and methods ###
1189
1190 Described below are the main classes and methods that can be invoked.
1191
1192 #### Saml2 library ####
1193
1194 Lets describe now the classes and methods of the SAML2 library.
1195
1196 ##### OneLogin\Saml2\Auth - Auth.php #####
1197
1198 Main class of OneLogin PHP Toolkit
1199
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
1205    IdP.
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.
1227
1228
1229 ##### OneLogin\Saml2\AuthnRequest - `AuthnRequest.php` #####
1230
1231 SAML 2 Authentication Request class
1232
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.
1237
1238 ##### OneLogin\Saml2\Response - `Response.php` #####
1239
1240 SAML 2 Authentication Response class
1241
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
1248    IdP.
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
1254    AuthnStatement
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
1260    Conditions Element.
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)
1263
1264 ##### OneLogin\Saml2\LogoutRequest - `LogoutRequest.php` #####
1265
1266 SAML 2 Logout Request class
1267
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.
1278
1279 ##### OneLogin\Saml2\LogoutResponse - `LogoutResponse.php` #####
1280
1281 SAML 2 Logout Response class
1282
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.
1292
1293 ##### OneLogin\Saml2\Settings - `Settings.php` #####
1294
1295 Configuration of the OneLogin PHP Toolkit
1296
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
1322    the settings is ok.
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.
1329
1330 ##### OneLogin\Saml2\Metadata - `Metadata.php` #####
1331
1332 A class that contains functionality related to the metadata of the SP
1333
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
1337   the metadata
1338
1339 ##### OneLogin\Saml2\Utils - `Utils.php` #####
1340
1341 Auxiliary class that contains several methods
1342
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
1348    target url).
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
1356    for assertions).
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
1361    ignored.
1362  * `parseDuration` - Interprets a ISO8601 duration value relative to a given
1363    timestamp.
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).
1377
1378 ##### OneLogin\Saml2\IdPMetadataParser - `IdPMetadataParser.php` #####
1379
1380 Auxiliary class that contains several methods to retrieve and process IdP metadata
1381
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.
1386
1387
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
1391 SAML2.
1392
1393
1394 Demos included in the toolkit
1395 -----------------------------
1396
1397 The toolkit includes three demo apps to teach how use the toolkit, take a look on it.
1398
1399 Demos require that SP and IdP are well configured before test it.
1400
1401 ## Demo1 ##
1402
1403 ### SP setup ###
1404
1405 The Onelogin's PHP Toolkit allows you to provide the settings info in two ways:
1406
1407  * Use a `settings.php` file that we should locate at the base folder of the
1408    toolkit.
1409  * Use an array with the setting data.
1410
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.
1415
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.
1419
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.
1423
1424
1425 ### IdP setup ###
1426
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.
1429
1430
1431 ### How it works ###
1432
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.
1435
1436  2. When you click:
1437
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.
1443
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`.
1446
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`.
1450
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.
1453
1454  5. The single log out functionality could be tested by two ways.
1455
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.
1462
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.
1470
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
1473 must be done.
1474
1475
1476 ## Demo2 ##
1477
1478 ### SP setup ###
1479
1480 The Onelogin's PHP Toolkit allows you to provide the settings info in two ways:
1481
1482  * Use a `settings.php` file that we should locate at the base folder of the
1483    toolkit.
1484  * Use an array with the setting data.
1485
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.
1490
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`).
1493
1494
1495 ### IdP setup ###
1496
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.
1499
1500
1501 ### How it works ###
1502
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.
1505
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.
1510
1511 Notice that the SSO action can be initiated at `index.php` or `sso.php`.
1512
1513 The SAML workflow that take place is similar that the workflow defined in the
1514 demo1, only changes the targets.
1515
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.
1520
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.
1526
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.
1529
1530  4. The single log out functionality could be tested by two ways.
1531
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.
1539
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.
1548