diff --git a/docs/source/simplesamlphp-modules.xml b/docs/source/simplesamlphp-modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..f27b98efba21cf206de71407e51cb325ffa4caed --- /dev/null +++ b/docs/source/simplesamlphp-modules.xml @@ -0,0 +1,473 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" +"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> +<article> + <title>simpleSAMLphp modules</title> + + <section> + <title>simpleSAMLphp documentation</title> + + <para>This document is part of the simpleSAMLphp documentation + suite.</para> + + <itemizedlist> + <listitem> + <para><ulink url="http://rnd.feide.no/view/simplesamlphpdocs">List of + all simpleSAMLphp documentation</ulink></para> + </listitem> + </itemizedlist> + + <para>This document describes how the module system in simpleSAMLphp works. + It descibes what types of modules there are, how they are configured, and + how to write new modules.</para> + </section> + + <section> + <title>Overview</title> + + <para>There are currently three parts of simpleSAMLphp which can be stored + in modules - authentication sources, authentication processing filters and + themes. More than one thing can be stored in a single module. There is + also support for storing supporting files, such as templates and + dictionaries, in modules.</para> + + <para>The different functionalities which can be created as modules will be + described in more detail in the following sections; what follows is a short + introduction to what you can du with them:</para> + + <itemizedlist> + <listitem> + <para>Authentication sources implement different methods for + authenticating users, for example simple login forms which authenticate + against a database backend, or login methods which use client-side + certificates.</para> + </listitem> + + <listitem> + <para>Authentication processing filters perform various tasks after the + user is authenticated and has a set of attributes. They can add, remove + and modify attributes, do additional authentication checks, ask + questions of the user, +++.</para> + </listitem> + + <listitem> + <para>Themes allow you to package custom templates for multiple modules + into a single module.</para> + </listitem> + </itemizedlist> + </section> + + <section> + <title>Module layout</title> + + <para>Each simpleSAMLphp module is stored in a directory under the the + <filename>modules</filename>-directory. The module directory contains the + following directories and files:</para> + + <para> + <glosslist> + <glossentry> + <glossterm>default-disable</glossterm> + + <glossdef> + <para>The presence of this file indicates that the module is + disabled by default. This module can be enabled by creating a file + named <filename>enable</filename> in the same directory.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>default-enable</glossterm> + + <glossdef> + <para>The presence of this file indicates that the module is + enabled by default. This module can be disabled by creating a file + named <filename>disable</filename> in the same directory.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>dictionaries</glossterm> + + <glossdef> + <para>This directory contains dictionaries which belong to this + module. To use a dictionary stored in a module, the extended tag + names can be used: + <literal>{<module name>:<dictionary name>:<tag name>}</literal> + For example, <literal>{example:login:hello}</literal> will look up + <literal>hello</literal> in + <literal>modules/example/dictionaries/login.php</literal>.</para> + + <para>It is also possible to specify + <literal><module name>:<dictionary name></literal> as + the default dictionary when instantiating the + <literal>SimpleSAML_XHTML_Template</literal> class.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>lib</glossterm> + + <glossdef> + <para>This directory contains classes which belong to this module. + All classes must be named in the following pattern: + <literal>sspmod_<module name>_<class name></literal> + When looking up the filename of a class, simpleSAMLphp will search + for <literal><class name></literal> in the + <literal>lib</literal> directory. Underscores in the class name + will be translated into slashes.</para> + + <para>Thus, if simpleSAMLphp needs to load a class named + <literal>sspmod_example_Auth_Source_Example</literal>, it will + load the file named + <literal>modules/example/lib/Auth/Source/Example.php</literal>. + </para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>templates</glossterm> + + <glossdef> + <para>These are module-specific templates. To use one of these + templates, specify + <literal><module name>:<template file>.php</literal> as + the template file in the constructor of + <literal>SimpleSAML_XHTML_Template</literal>. For example, + <literal>example:login-form.php</literal> is translated to the file + <literal>modules/example/templates/default/login-form.php</literal>. + Note that <literal>default</literal> in the previous example is + defined by the <literal>theme.use</literal> configuration + option.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>themes</glossterm> + + <glossdef> + <para>This directory contains themes the module defines. A single + module can define multiple themes, and these themes may override + all templates in all modules. Each subdirectory of + <literal>themes</literal> defines a theme. The theme directory + contains a subdirectory for each module. The templates stored + under <literal>simplesamlphp/templates</literal> can be overridden + by a directory named <literal>default</literal>.</para> + + <para>To use a theme provided by a module, the + <literal>theme.use</literal> configuration option should be set to + <literal><module name>:<theme name></literal>.</para> + + <para>When using the theme <literal>example:blue</literal>, the + template <literal>templates/default/login.php</literal> will be + overridden by + <literal>modules/example/themes/blue/default/login.php</literal>, + while the template + <literal>modules/core/templates/default/loginuserpass.php</literal> + will be overridden by + <literal>modules/example/themes/blue/core/loginuserpass.php</literal>. + </para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>www</glossterm> + + <glossdef> + <para>All files stored in this directory will be available by + accessing the URL <literal>https://.../simplesamlphp/module.php/<module name>/<file name></literal>. + For example, if a script named <literal>login.php</literal> is + stored in <literal>modules/example/www/</literal>, it can be + accessed by the URL <literal>https://.../simplesamlphp/module.php/example/login.php</literal>.</para> + + <para>To retrieve this URL, the + <literal>SimpleSAML_Module::getModuleURL($resource)</literal>-function + can be used. This function takes in a resource on the form + <literal><module>/<file></literal>. This function will + then return an URL to the given file in the + <literal>www</literal>-directory of <literal>module</literal>.</para> + </glossdef> + </glossentry> + </glosslist> + </para> + </section> + + <section> + <title>Authentication sources</title> + + <para>An authentication source is used to authenticate a user and receive a + set of attributes belonging to this user. In a single-signon setup, the + authentication source will only be called once, and the attributes + belonging to the user will be cached until the user logs out.</para> + + <para>Authentication sources are defined in + <filename>config/authsources.php</filename>. This file contains an array of + <literal>name => configuration</literal> pairs. The name is used to + refer to the authentication source in metadata. When configuring an IdP to + authenticate against an authentication source, the <literal>auth</literal> + option should be set to this name. The configuration for an authentication + source is an array. The first element in the array identifies the class + which implements the authentication source. The remaining elements in the + array are configuration entries for the authentication source.</para> + + <para>A typical configuration entry for an authentication source looks like + this:</para> + + <programlisting>'example-static' => array( + /* This maps to modules/exampleauth/lib/Auth/Source/Static.php */ + 'exampleauth:Static', + + /* The following is configuration which is passed on to the exampleauth:Static authentication source. */ + 'uid' => 'testuser', + 'eduPersonAffiliation' => array('member', 'employee'), + 'cn' => array('Test User'), +),</programlisting> + + <para>To use this authentication source in a SAML 2.0 IdP, set the <literal>auth</literal>-option of the IdP to <literal>'example-static'</literal>:</para> + + <programlisting>'__DYNAMIC:1__' => array( + 'host' => '__DEFAULT__', + 'privatekey' => 'server.pem', + 'certificate' => 'server.crt', + <emphasis>'auth' => 'example-static',</emphasis> +),</programlisting> + + <section> + <title>Creating authentication sources</title> + + <para>Authentication sources are implemented by creating a class which + is a subclass of the <literal>SimpleSAML_Auth_Source</literal>-class. + They must implement at least one function - + <literal>authenticate</literal>. This function may can either update + the <literal>$state</literal>-array it receives with the attributes + of the user and return, or it may save the state and redirect the user to + another page for authentication. It redirects, it should later retrieve + the state array, update it with the attributes and call + <literal>SimpleSAML_Source_Auth::completeAuth($state)</literal>.</para> + + <para>There is also a simpler way to implement many authentication + sources. If the authentication source only needs a username and password + from the user, it may subclass + <literal>sspmod_core_Auth_UserPassBase</literal>, and implement a single + function - <literal>login($username, $password)</literal>. This function + receives the username and password the user gives, and should return an + associative array with the attributes of the user. If the username or + password is incorrect, it should throw an exception: + <literal>SimpleSAML_Error_Error('WRONGUSERPASS')</literal></para> + + <para>Requirements for an authentication source:</para> + + <itemizedlist> + <listitem> + <para>Must be derived from the + <literal>SimpleSAML_Auth_Source</literal>-class.</para> + </listitem> + + <listitem> + <para>If a constructor is implemented, it must first call the parent + constructor, passing along all parameters, before accessing any of + the parameters. In general, only the $config parameter should be + accessed.</para> + </listitem> + + <listitem> + <para>The <literal>authenticate(&$state)</literal>-function must be + implemented. If this function completes, it is assumed that the user + is authenticated, and that the $state array has been updated with the + user's attributes.</para> + </listitem> + + <listitem> + <para>If the <literal>authenticate</literal>-function does not + return, it must at a later time call + <literal>SimpleSAML_Auth_Source::completeAuth</literal> with the new + state. The state must be an update of the array passed to the + <literal>authenticate</literal>-function.</para> + </listitem> + + <listitem> + <para>No pages may be shown to the user from the + <literal>authenticate</literal>-function. Instead, the state should + be saved, and the user should be redirected to a new page. This must + be done to prevent unpredictable events if the user for example + reloads the page.</para> + </listitem> + + <listitem> + <para>No state information about any authentication should be stored + in the authentication source object. It must instead be stored in the + state array. Any changes to variables in the authentication source + object may be lost.</para> + </listitem> + + <listitem> + <para>The authentication source object must be serializable. It may + be serializes between being constructed and the call to the + <literal>authenticate</literal>-function. This means that, for + example, no database connections should be created in the constructor + and later used in the + <literal>authenticate</literal>-function.</para> + </listitem> + </itemizedlist> + </section> + </section> + + <section> + <title>Authentication processing filters</title> + + <para>Authentication processing filters postprocesses authentication + information received from authentication sources. It is possible to use + this for additional authentication checks, requesting the users consent + before delivering attributes to the user, modifying the users attributes, + and other things which should be performed before returning the user to + the service provider he came from.</para> + + <para>Authentication processing filters are added to IdPs by setting the + <literal>authproc</literal> option in the <literal>idp-hosted</literal>- + and <literal>sp-remote</literal>-metadata. This is an array of filters, + where the filters will typically run first to last. Each filter is either + specified as a single string (if there is no configuration) or as an array + (if there is configuration for the filter).</para> + + <para>Example:</para> + + <programlisting>'authproc' => array( + 'example:Test', + array('core:AttributeLimit', 'uid', 'mail', 'cn'), + array('core:AttributeMap', 'mail' => 'email'), +),</programlisting> + + <para>Filternames are on the form + <literal><module>:<name></literal>, and map to + <literal>modules/<module>/lib/Auth/Process/<name>.php</literal>, + which is expected to be a subclass of + <literal>SimpleSAML_Auth_ProcessingFilter</literal>.</para> + + <section> + <title>Priority and merging of SP/IdP <literal>authproc</literal> filter + lists</title> + + <para>By default, the filters defined in the IdP are run before those + defined in the SP. However, sometimes one may want to change the order, + and run some filters on the SP befoer one filter on the IdP. To achieve + this, we have the <literal>%priority</literal>-option of filters. The + default priority, if no <literal>%priority</literal>-option is added, is + 50. By giving a filter a higher priority value, you can make it run after + those with a lower priority:</para> + + <programlisting>/* saml20-idp-hosted.php */ +'authproc' => array( + array('consent:Consent', '%priority' => 60), +), + +/* saml20-sp-remote.php */ +'authproc' => array( + array('core:AttributeLimit', 'uid', 'mail', 'cn'), + array('core:AttributeMap', '%priority' => 70, 'mail' => 'email'), +),</programlisting> + + <para>In this example, the <literal>core:AttributeLimit</literal>-filter + will be run before the <literal>consent:Consent</literal>-filter. The + <literal>core:AttributeMap</literal>-filter will be run last (after the + <literal>consent:Consent</literal>-filter). Filters with the same + priority value will be ordered in the order they appear in the + configuration, with IdP filters preceeding SP filters.</para> + </section> + + <section> + <title>Creating authentication processing filters</title> + + <para>Authentication processing filters are created by creating a class + under <literal>Auth/Process/</literal> in a module. This class is + expected to subclass <literal>SimpleSAML_Auth_ProcessingFilter</literal>. + A filter must implement at lease one function - the + <literal>process(&$request)</literal>-function. This function can access + the <literal>$request</literal>-array add, delete and modify attributes, + and can also do more advanced processing based on the SP/IdP metadata + (which is also included in the <literal>$request</literal>-array). When + this function returns, it is assumed that the filter has finished + processing.</para> + + <para>If a filter for some reason needs to redirect the user, for example + to show a web page, it should save the current request. Upon completion + it should retrieve the request, update it with the changes it is going + to make, and call + <literal>SimpleSAML_Auth_ProcessingChain::resumeProcessing</literal>. + This function will continue processing the next configured filter.</para> + + <para>Requirements for authentication processing filters:</para> + + <itemizedlist> + <listitem> + <para>Must be derived from the + <literal>SimpleSAML_Auth_ProcessingFilter</literal>-class.</para> + </listitem> + + <listitem> + <para>If a constructor is implemented, it must first call the parent + constructor, passing along all parameters, before accessing any of + the parameters. In general, only the $config parameter should be + accessed.</para> + </listitem> + + <listitem> + <para>The <literal>process(&$state)</literal>-function must be + implemented. If this function completes, it is assumed that + processing is completed, and that the $request array has been + updated.</para> + </listitem> + + <listitem> + <para>If the <literal>process</literal>-function does not + return, it must at a later time call + <literal>SimpleSAML_Auth_ProcessingChain::resumeProcessing</literal> + with the new request state. The request state must be an update of + the array passed to the <literal>process</literal>-function.</para> + </listitem> + + <listitem> + <para>No pages may be shown to the user from the + <literal>process</literal>-function. Instead, the request state + should be saved, and the user should be redirected to a new page. + This must be done to prevent unpredictable events if the user for + example reloads the page.</para> + </listitem> + + <listitem> + <para>No state information should be stored in the filter object. It + must instead be stored in the request state array. Any changes to + variables in the filter object may be lost.</para> + </listitem> + + <listitem> + <para>The filter object must be serializable. It may be serialized + between being constructed and the call to the + <literal>process</literal>-function. This means that, for example, no + database connections should be created in the constructor and later + used in the <literal>process</literal>-function.</para> + </listitem> + </itemizedlist> + </section> + </section> + + <section> + <title>Themes</title> + + <para>This feature allows you to collect all your custom templates in one + place. The directory structure is like this: + <literal>modules/<thememodule>/themes/<theme>/<module>/<template></literal> + <literal>thememodule</literal> is the module where you store your theme, + while <literal>theme</literal> is the name of the theme. A theme is + activated by setting the <literal>theme.use</literal> configuration option + to <literal><thememodule>:<theme></literal>. + <literal>module</literal> is the module the template belongs to, and + <literal>template</literal> is the template in that module.</para> + + <para>For example, <literal>modules/example/themes/test/core/loginuserpass.php</literal> + replaces <literal>modules/core/templates/default/loginuserpass.php</literal>. + <literal>modules/example/themes/test/default/frontpage.php</literal> replaces + <literal>templates/default/frontpage.php</literal>. This theme can be + activated by setting <literal>theme.use</literal> to + <literal>example:test</literal>.</para> + </section> +</article> \ No newline at end of file