diff options
| author | Romain Chantereay <rchantereau@entrouvert.com> | 2005-03-17 09:43:17 +0000 |
|---|---|---|
| committer | Romain Chantereay <rchantereau@entrouvert.com> | 2005-03-17 09:43:17 +0000 |
| commit | 3d9f55de65e01255b2f2a808a9485c0afee85028 (patch) | |
| tree | 80a691fa4808ea5c38c0dbd7f0f0af0bea56080d /docs | |
| parent | 522740c130be1c63bfeca089bca3350d00b0a5e6 (diff) | |
| download | lasso-3d9f55de65e01255b2f2a808a9485c0afee85028.tar.gz lasso-3d9f55de65e01255b2f2a808a9485c0afee85028.tar.xz lasso-3d9f55de65e01255b2f2a808a9485c0afee85028.zip | |
First version of the "Writing a Libety PHP SP".
Almost all adapted copied/pasted from "Writing a Liberty C SP".
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/lasso-book/writing-a-php-sp.txt | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/docs/lasso-book/writing-a-php-sp.txt b/docs/lasso-book/writing-a-php-sp.txt new file mode 100644 index 00000000..e6e52d67 --- /dev/null +++ b/docs/lasso-book/writing-a-php-sp.txt @@ -0,0 +1,377 @@ +========================================= +Writing a Liberty service Provider in PHP +========================================= + +:Author: Romain Chantereau +:Contact: rchantereau@entrouvert.com +:date: $Date$ +:revision: $Revision$ +:copyright: Copyright © 2005 Entr'ouvert + +.. contents:: Table of Contents +.. section-numbering:: + +Lasso PHP Binding Basics +======================== + +Lasso functions are available from the LASSO php extension. + +In order to load the lasso extension you juste have to add the lasso PHP extension in your +``php.ini`` configuration file, or try to load it dynamicaly, like:: + + if (!extension_loaded('lasso')) + { + $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; + dl($prefix . 'lasso.' . PHP_SHLIB_SUFFIX); + } + +You can easily include this code everytime you need lasso. + + +The first thing to do is to call ``lasso_init()``. Similary, the last thing +should be to call ``lasso_shutdown()``. + +Once ``lasso_init()`` is called. The smallest and useless Lasso project will +therefore be:: + + lasso_init(); + print("Hello world.\n"); + lasso_shutdown(); + +If your PHP code is used in HTML script environment, it could be difficult to +call ``lasso_shutdown()``, this is not mandatory. + +Liberty and Lasso profiles +========================== + +Lasso provides the necessary functions to implement Liberty Alliance profiles, +as defined in the `Liberty ID-FF Bindings and Profiles Specification`_. They +are: + +- Single Sign-On and Federation +- Name Registration +- Federation Termination Notification +- Single Logout +- Identity Provider Introduction +- Name Identifier Mapping +- Name Identifier Encryption + +Each profile maps to a Lasso object such as ``LassoLogin``, ``LassoLogout``... +Those are initialized with data known about identity and service providers, +available in a ``LassoServer`` object. + +The ``LassoServer`` object may be created as follows:: + + lasso_init(); + $server = &new LassoServer("sp-metadata.xml", "sp-private-key.pem", + "sp-crt.pem", LASSO_SIGNATURE_METHOD_SHA1); + $server->addProvider(LASSO_PROVIDER_ROLE_IDP, "idp-metadata.xml", + "idp-public-key.pem", "ca-crt.pem"); + lasso_shutdown(); + +- ``sp-metadata.xml`` is the Liberty metadata file for the service provider +- ``idp-metadata.xml`` is the Liberty metadata file for the identity provider +- ``sp-private-key.pem`` is the service provider private key; used to sign + documents +- ``sp-crt.pem`` is the service provider certificate; sent inside signed + documents +- ``idp-public-key.pem`` is the identity provider public key; used to verify + signature in documents sent by the identity provider +- ``ca-crt.pem`` is the certificate of the certification authority used by the + identity provider. + +It is of course possible to have several calls to the ``addProvider`` method of +an instanciated ``LassoServer`` object if there are more than one identity provider. + +.. note:: Figures in the previously referred Binding and Profiles specification + document are quite helpful in figuring out the message passing. + +Serialization +------------- + +``LassoServer`` objects can be serialized into a XML formated string:: + + $dump = $server->dump(); + +It is then really easy to get back properly constructed objects:: + + $lspk_server = &LassoServer::newFromDump($dump); + +.. warning:: The server dump only contains the filenames; not the actual file + contents. Files should not be moved afterwards. + + +Liberty Metadata Files +====================== + + +They are descriptions of a provider containing ``providerID`` and various +norminative URLs:: + + <?xml version="1.0"?> + <EntityDescriptor + providerID="https://sp.example.com/" xmlns="urn:liberty:metadata:2003-08"> + <SPDescriptor> + <SingleLogoutServiceURL>https://sp.example.com/singleLogout</SingleLogoutServiceURL> + <SingleLogoutProtocolProfile>http://projectliberty.org/profiles/slo-idp-soap</SingleLogoutProtocolProfile> + <SoapEndpoint>https://sp.example.com/soapEndpoint</SoapEndpoint> + <AssertionConsumerServiceURL id="AssertionConsumerServiceURL1" isDefault="true"> + https://sp.example.com/assertionConsumer + </AssertionConsumerServiceURL> + <AuthnRequestsSigned>true</AuthnRequestsSigned> + </SPDescriptor> + </EntityDescriptor> + +Describe a service provider (with providerID ``https://sp.example.com``) whose +single logout service URL is ``https://sp.example.com/singleLogout``. Refer to +the Liberty Alliance specifications for details. + + +Single Sign-On and Federation Profile +===================================== + +.. warning:: The source code presented in this section has for sole purpose + to explain the different steps necessary to implement this + profile; they notably lack proper error checking. See `Proper + Error Checking`_ for details on error checking. + + +As a first step the user points its browser to the service provider to the +login URL; the service provider must then respond with an HTTP 302 Redirect +response, pointing the user browser to the identity provider single sign on +service. + +.. note:: the login URL is not normative; any name will do. + + +``$server`` is a instanciated ``LassoServer`` as seen earlier and +``$idpProviderId`` is a string with the identity provider Id (the string must +match a providerID defined in the metadata file). + +:: + + + $lassoLogin = &new LassoLogin($server); + $lassoLogin->initAuthnRequest($idpProviderId, LASSO_HTTP_METHOD_REDIRECT); + $lassoRequest = $lassoLogin->request; + $lassoRequest->NameIDPolicy = LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED; + $lassoRequest->consent = LASSO_LIB_CONSENT_UNAVAILABLE; + $lassoRequest->ForceAuthn = 0; + $lassoRequest->IsPassive = 0; + $lassoRequest->relayState = "relay state"; + + $lassoLogin->buildAuthnRequestMsg(); + + +You can now redirect the user to the URL defined in ``$lassoLogin->msg_url``; for +example:: + + header("Location: ".$lassoLogin->msg_url); + + +The user then logs in on the identity provider which ultimately redirects back +to the service provider; to the assertion consumer URL. A SAML artifact is +passed in the query parameter. + +.. note:: the assertion consumer URL is defined by Liberty; it must be declared + in the ``AssertionConsumerServiceURL`` element of the metadata file. + +:: + + $lassoLogin = &new LassoLogin($lspk_server); + $lassoLogin->initRequest($query_string, LASSO_HTTP_METHOD_REDIRECT); + $lassoLogin->buildRequestMsg(); + +The service provider must check this artifact using a SOAP request to the +identity provider. The URL is ``$lassoLogin->msg_url`` while the +request is ``$lassoLogin->msg_body``. The request must succeed with +an HTTP 200 status code; let's consider its content is put in the ``$answer``, +the next statement would be:: + + $lassoLogin->processResponseMsg($answer); + +The users are defined by a ``nameIdentifier`` (accessible through +``$lassoLogin->nameIdentifier``). Those typically map to users +and sessions in some database on the service provider. If existing; the +session should probably contains a ``session_dump`` element and the user a +``identity_dump`` element. See `Database Considerations`_ below for more +informations. + +It is now time to get them out of the database and apply them to the ``login`` +object. + +:: + + if ($session_dump != NULL) { + $lassoLogin->setSessionFromDump($session_dump); + } + if ($identity_dump != NULL) { + $lassoLogin->setIdentityFromDump($identity_dump); + } + $lassoLogin->acceptSso(); + +After ``lassoLogin->acceptSso()`` the session and the identity are updated (or +created) and should then be saved. If the identity has not regnogized by the +service provider an account will probably have to be created on the service +provider; this is a good opportunity to ask the user for more information. + +You can get respective dumps like this:: + + if($lassoLogin->isIdentityDirty()) + { + $lassoIdentity = $lassoLogin->identity; + $lassoIdentityDump = $lassoIdentity->dump(); + } + + if(lassoLogin->isSessionDirty()) + { + $lassoSession = $lassoLogin->session; + $lassoSessionDump = $lassoSession->dump(); + } + + /* code to store $identity_dump and $session_dump */ + + +A success web page can be displayed. + + +Single Logout Profile +===================== + +There are different single logout profiles; some initiated on the identity +provider, others initiated on the service provider, using either HTTP redirects +or SOAP requests. + +This part is about a logout using SOAP and initiated on the service provider. + +:: + + $lassoLogout = &new LassoLogout($server); + + +Identity and session dumps should be restored to prepare the logout request. + +:: + + if ($session_dump != NULL) + { + $lassoLogout->setSessionFromDump($session_dump); + } + if ($identity_dump != NULL) { + lassoLogout->setIdentiyFromDump($identity_dump); + } + + $lassoLogout->initRequest($idpProviderId, LASSO_HTTP_METHOD_SOAP); + $lassoLogout->buildRequestMsg(); + + +The service provider must then make a SOAP request to the identity provider; +``$msg_url`` and ``$msg_body``. You should then pass the answer to Lasso:: + + $lassoLogout->processResponseMsg($answer)); + +And save back session and user dump; the process is similar as the one at the +end of the single sign on profile. + + +Proper Error Checking +===================== + +Most Lasso functions raise PHP error (fatal) or warning (non-fatal). + +It is strongly advised to code an user error handler:: + + function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) + { + print("No: ".$errno." - ".$errmsg." at ".$filename.", line: ".$linenum."\n"); + } + +and to set up the script to use it:: + + set_error_handler("userErrorHandler"); + +Most Lasso functions returns 0 on success and a negative number on failure. It +is strongly advised to check this return code on each call. If the error raise a +PHP warning, the code resume after the call to the error handler function. + +:: + + $lrv = $lassoLogin->processResponseMsg($responseMsg); + if($lrv > 0) + { + print("Lasso Error: ".$lrv."\n"); + /* handling error; most probably bailing out */ + } + + + +Database Considerations +======================= + +Lasso has been designed to let the service provider keep on using existing +databases. Typically there is already a table describing users; just add an +identity dump column to the existing table: + +======= ======================================== ============== +User Id existing data (name, address...) Identity dump +======= ======================================== ============== +1 ... <Identity> ... +2 ... <Identity> ... +======= ======================================== ============== + +Mapping between existing users and name identifiers sent by the identity +provider can be done with a simple table. + +=============== ======= +Name Identifier User Id +=============== ======= +AQWWRRS... 1 +CGFASDE... 2 +YYSSSDS... 1 +=============== ======= + +.. note:: A separate table is needed because one user Id could map + to several name identifiers; in case there are several identity + providers. + +Sessions are also commonly stored in databases; just add a session dump column +to the existing session table: + +========== ================= ============= +Session Id misc session data Session dump +========== ================= ============= +6744066 ... <Session> ... +3338824 ... <Session> ... +========== ================= ============= + +Likewise sessions should be mapped to name identifiers. + +=============== ========== +Name Identifier Session Id +=============== ========== +AQWWRRS... 3338824 +=============== ========== + + + +API Reference +============= + +- LassoLogin_ +- LassoLogout_ +- LassoIdentity_ +- LassoServer_ +- LassoSession_ + + + + +.. _Liberty ID-FF Bindings and Profiles Specification: + http://www.projectliberty.org/specs/draft-liberty-idff-bindings-profiles-1.2-errata-v1.0.pdf + +.. _LassoLogin: /documentation/api-reference/lassologin.html +.. _LassoLogout: /documentation/api-reference/lassologout.html +.. _LassoIdentity: /documentation/api-reference/lassoidentity.html +.. _LassoServer: /documentation/api-reference/lassoserver.html +.. _LassoSession: /documentation/api-reference/lassosession.html + |
