<?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>Setting up a simpleSAMLphp SAML 2.0 IdP to use with Google Apps for
  Education</title>

  <articleinfo>
    <date>2007-10-15</date>

    <pubdate>Thu Aug 21 10:30:22 2008</pubdate>

    <author>
      <firstname>Andreas Åkre</firstname>

      <surname>Solberg</surname>

      <email>andreas.solberg@uninett.no</email>
    </author>
  </articleinfo>

  <section>
    <title>Introduction</title>

    <para>This article assumes that you have already read the simpleSAMLphp
    installation manual, and installed a version of simpleSAMLphp at your
    server.</para>

    <para>In this example we will setup this server as an IdP for Google Apps
    for Education:</para>

    <literallayout>dev2.andreas.feide.no</literallayout>
  </section>

  <section>
    <title>Enabling the Identity Provider functionality</title>

    <para>Edit <filename>config.php</filename>, and enable the SAML 2.0
    IdP:</para>

    <programlisting>'enable.saml20-sp'  =&gt; false,
'enable.saml20-idp' =&gt; true,
'enable.shib13-sp'  =&gt; false,
'enable.shib13-idp' =&gt; false,</programlisting>
  </section>

  <section>
    <title>Setting up a SSL signing certificate</title>

    <para>For test purposes, you can skip this section, and use the
    certificate included in the simpleSAMLphp distribution.</para>

    <para>For a production system, you must generate a new certificate for
    your IdP.</para>

    <warning>
      <para>The certificate that follows the simpleSAMLphp distribution must
      <emphasis>NEVER</emphasis> be used in production, as the private key is
      also included in the package and can be downloaded by anyone.</para>
    </warning>

    <para>Here is an example of openssl commands to generate a new key and a
    self signed certificate to use for signing SAML messages:</para>

    <screen>openssl genrsa -des3 -out googleappsidp.key 1024 
openssl rsa -in googleappsidp.key -out googleappsidp.pem
openssl req -new -key googleappsidp.key -out googleappsidp.csr
openssl x509 -req -days 1095 -in googleappsidp.csr -signkey googleappsidp.key -out googleappsidp.crt</screen>

    <para>The certificate above will be valid for 1095 days (3 years).</para>

    <para>Here is an example of typical user input when creating a certificate
    request:</para>

    <screen>Country Name (2 letter code) [AU]:<userinput>NO</userinput>
State or Province Name (full name) [Some-State]:<userinput>Trondheim</userinput>
Locality Name (eg, city) []:<userinput>Trondheim</userinput>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<userinput>UNINETT</userinput>
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:<userinput>dev2.andreas.feide.no</userinput>
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:</screen>

    <note>
      <para>simpleSAMLphp will only work with RSA and not DSA
      certificates.</para>
    </note>
  </section>

  <section id="sect.authmodule">
    <title>Authentication modules</title>

    <para>The IdP must be connected to your existing user catalog.
    Authentication modules are provided for different user catalog
    technologies.</para>

    <para>The <filename>www/auth</filename> directory contains multiple files,
    each representing an authentication module. In the IdP hosted metadata
    configuration you specify which authentication module should be used for
    that specific IdP. You can implement your own authentication module, see
    the IdP documentation.</para>

    <para>These authentication modules are included in the simpleSAMLphp
    distribution:</para>

    <glosslist>
      <glossentry>
        <glossterm>auth/login.php</glossterm>

        <glossdef>
          <para>This is the standard LDAP backend authentication module. It
          uses LDAP configuration from the <filename>config.php</filename>
          file.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>auth/login-ldapmulti.php</glossterm>

        <glossdef>
          <para>This authentication module lets you connect to multiple LDAPs
          depending on the home organization selected by the user.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>auth/login-feide.php</glossterm>

        <glossdef>
          <para>A multi-LDAP module which looks up the users in LDAP, first
          searching for <literal>eduPersonPrincipalName</literal>.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>auth/login-radius.php</glossterm>

        <glossdef>
          <para>This authentication module will authenticate users against an
          RADIUS server instead of LDAP.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>auth/login-auto.php</glossterm>

        <glossdef>
          <para>This module will automatically login the user with some test
          details. You can use this to test the IdP functionality if you do
          not have</para>

          <para>This module is not completed yet. Work in progress.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>auth/login-cas-ldap.php</glossterm>

        <glossdef>
          <para>Authentication via CAS, followed by attribute lookup in
          LDAP.</para>
        </glossdef>
      </glossentry>
    </glosslist>

    <section>
      <title>Configuring the LDAP authentication module</title>

      <para>The LDAP module is found in
      <filename>auth/login.php</filename>.</para>

      <para>If you want to perform local authentication using this server,
      using the LDAP authenticaiton plugin, the following parameters should be
      configured in <filename>config.php</filename>:</para>

      <itemizedlist>
        <listitem>
          <para><literal>auth.ldap.dnpattern</literal>: Which DN to bind to.
          <literal>%username%</literal> is replaced with with the user name
          typed in.</para>
        </listitem>

        <listitem>
          <para><literal>auth.ldap.hostname</literal>: Host name of the LDAP
          server</para>
        </listitem>

        <listitem>
          <para><literal>auth.ldap.attributes</literal>: List of attributes
          retrieved from LDAP. Set this option to <literal>null</literal> to
          retrieve all attributes available.</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Configuring the multi-LDAP authentication module</title>

      <para>The module is found in
      <filename>auth/login-ldapmulti.php</filename>.</para>

      <note>
        <para>Documentation will be added later. For now, contact the
        author.</para>
      </note>
    </section>
  </section>

  <section>
    <title>Configuring metadata for an SAML 2.0 IdP</title>

    <para>If you want to setup a SAML 2.0 IdP for Google Apps, you need to
    configure two metadata files: <filename>saml20-idp-hosted.php</filename>
    and <filename>saml20-sp-remote.php</filename>.</para>

    <section>
      <title>Configuring SAML 2.0 IdP Hosted metadata</title>

      <para>This is the configuration of the IdP itself. Here is some example
      config:</para>

      <programlisting>  // The SAML entity ID is the index of this config.
  'dev2.andreas.feide.no' =&gt; array(

    // The hostname of the server (VHOST) that this SAML entity will use.
   'host'        =&gt; 'sp.example.org',

    // X.509 key and certificate. Relative to the cert directory.
    'privatekey'   =&gt; 'googleappsidp.pem',
    'certificate'  =&gt; 'googleappsidp.crt',

    // Authentication plugin to use. login.php is the default one that uses LDAP.
    'auth'         =&gt; 'auth/login.php',
    'authority'    =&gt; 'login'
  )</programlisting>

      <para>Parameter details:</para>

      <glosslist>
        <glossentry>
          <glossterm>index (index of array)</glossterm>

          <glossdef>
            <para>The entity ID of the IdP. In this example this value is set
            to: <literal>dev2.andreas.feide.no</literal>.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>host</glossterm>

          <glossdef>
            <para>The hostname of the server running this IdP, in this case:
            <literal>dev2.andreas.feide.no</literal>.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>privatekey</glossterm>

          <glossdef>
            <para>Name of private key file in PEM format, in the
            <filename>certs</filename> directory. For key generation, see
            generation of the <literal>googleappsidp</literal> key,
            above.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>certificate</glossterm>

          <glossdef>
            <para>Name of certificate file in PEM format, in the
            <filename>certs</filename> directory. For certificate generation,
            see generation of the <literal>googleappsidp</literal> key,
            above.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>auth</glossterm>

          <glossdef>
            <para>Which authentication module to use. Default:
            <filename>auth/login.php,</filename>the LDAP authentication
            module. See the <xref linkend="sect.authmodule" /> for more
            information on the authentication modules.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>authority</glossterm>

          <glossdef>
            <para>The ID of the authentication module you are using. Set this
            value if you only allow one authentication module.</para>
          </glossdef>
        </glossentry>
      </glosslist>
    </section>

    <section>
      <title>Configuring SAML 2.0 SP Remote metadata</title>

      <para>In the (saml20-sp-remote.php) file we will configure an entry for
      Google Apps for education. There is already an entry for Google Apps in
      the template, but we will change the domain name:</para>

      <programlisting>  /*
   * This example shows an example config that works with Google Apps for education.
   * What is important is that you have an attribute in your IdP that maps to the local part of the email address
   * at Google Apps. E.g. if your google account is foo.com, and you have a user with email john@foo.com, then you
   * must set the simplesaml.nameidattribute to be the name of an attribute that for this user has the value of 'john'.
   */
  'google.com' =&gt; array(
    'AssertionConsumerService'   =&gt; 'https://www.google.com/a/g.feide.no/acs', 
    'spNameQualifier'            =&gt; 'google.com',
    'NameIDFormat'               =&gt; 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
    'simplesaml.nameidattribute' =&gt; 'uid',
    'simplesaml.attributes'      =&gt; false
  );</programlisting>

      <para>You must also map some attributes received from the authentication
      module into email field sent to Google Apps. In this example, the LDAP
      returns the <code>uid</code> attribute. The <code>uid</code> attribute
      contains the local part of the user name.</para>

      <para>You should modify the <literal>AssertionConsumerService</literal>
      to include your Google Apps domain name instead of
      <literal>g.feide.no</literal>.</para>

      <para>For an explanation of the parameters, see the <ulink
      url="simplesamlphp-idp.html">simpleSAMLphp IdP
      documentation</ulink>.</para>
    </section>
  </section>

  <section>
    <title>Configure Google Apps for education</title>

    <para>Start by logging in to our Google Apps for education account panel.
    Then select "Advanced tools":</para>

    <figure>
      <title>We go to advanced tools</title>

      <screenshot>
        <mediaobject>
          <imageobject>
            <imagedata fileref="resources/simplesamlphp-googleapps/googleapps-menu.png" />
          </imageobject>
        </mediaobject>
      </screenshot>
    </figure>

    <para>Then select "Set up single sign-on (SSO)":</para>

    <figure>
      <title>We go to setup SSO</title>

      <screenshot>
        <mediaobject>
          <imageobject>
            <imagedata fileref="resources/simplesamlphp-googleapps/googleapps-sso.png" />
          </imageobject>
        </mediaobject>
      </screenshot>
    </figure>

    <para>Upload a certificate, such as the googleappsidp.crt created
    above:</para>

    <figure>
      <title>Uploading certificate</title>

      <screenshot>
        <mediaobject>
          <imageobject>
            <imagedata fileref="resources/simplesamlphp-googleapps/googleapps-cert.png" />
          </imageobject>
        </mediaobject>
      </screenshot>
    </figure>

    <para>Fill out the remaining fields:</para>

    <para>The most important field is the Sign-in page URL. Set it to
    something similar to:</para>

    <literallayout>http://dev2.andreas.feide.no/simplesaml/saml2/idp/SSOService.php</literallayout>

    <para>using the hostname of your IdP server.</para>

    <para>You must also configure the IdP initiated Single LogOut endpoint of
    your server. The RelayState parameter of the endpoint is the URL where the
    user is redirected after successfull logout. Recommended value:</para>

    <literallayout>http://dev2.andreas.feide.no/simplesaml/saml2/idp/initSLO.php?RelayState=/simplesaml/logout.php</literallayout>

    <para>again, using the host name of your IdP server.</para>

    <para>The Sign-out page or change password url can be static pages on your
    server.</para>

    <para>The network mask determines which IP addresses will be asked for SSO
    login. IP addresses not matching this mask will be presented with the
    normal Google Apps login page. I think you can leave this field empty to
    enable authentication for all URLs.</para>

    <figure>
      <title>Fill out the remaining fields</title>

      <screenshot>
        <mediaobject>
          <imageobject>
            <imagedata fileref="resources/simplesamlphp-googleapps/googleapps-ssoconfig.png" />
          </imageobject>
        </mediaobject>
      </screenshot>
    </figure>

    <section>
      <title>Add a user in Google Apps that is known to the IdP</title>

      <para>Before we can test login, a new user must be defined in Google
      Apps. This user must have a mail field matching the email prefix mapped
      from the attribute as described above in the metadata section.</para>
    </section>
  </section>

  <section>
    <title>Test to login to Google Apps for education</title>

    <para>Go to the URL of your mail account for this domain, the URL is
    similar to the following:</para>

    <literallayout>http://mail.google.com/a/yourgoogleappsdomain.com</literallayout>

    <para>replacing the last part with your own google apps domain
    name.</para>
  </section>

  <section>
    <title>Security Considerations</title>

    <para>Make sure that your IdP server runs HTTPS (SSL). The Apache
    documentation contains information for how to configure HTTPS.</para>

    <para>Make sure you have replaced the default certificate delivered with
    the simpleSAMLphp distribution with your own certificate.</para>
  </section>

  <section>
    <title>Support</title>

    <para>If you need help to make this work, or want to discuss simpleSAMLphp
    with other users of the software, you are fortunate: Around simpleSAMLphp
    there is a great Open source community, and you are welcome to join! The
    forums are open for you to ask questions, contribute answers other further
    questions, request improvements or contribute with code or plugins of your
    own.</para>

    <itemizedlist>
      <listitem>
        <para><ulink url="http://rnd.feide.no/simplesamlphp">simpleSAMLphp
        homepage (at Feide RnD)</ulink></para>
      </listitem>

      <listitem>
        <para><ulink url="http://rnd.feide.no/view/simplesamlphpdocs">List of
        all available simpleSAMLphp documentation</ulink></para>
      </listitem>

      <listitem>
        <para><ulink
        url="http://rnd.feide.no/content/simplesamlphp-users-mailinglist">Join
        the simpleSAMLphp user's mailing list</ulink></para>
      </listitem>

      <listitem>
        <para><ulink url="https://ow.feide.no/simplesamlphp:start">Visit and
        contribute to the simpleSAMLphp wiki</ulink></para>
      </listitem>
    </itemizedlist>
  </section>
</article>