You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Shibboleth is a free, open-source web single sign-on system with rich attribute-exchange based on open standards, principally SAML. It supports both Apache (on several platforms, notably Linux, OSX, Solaris, and Windows), and several versions of Microsoft IIS (5, 6, 7).

Because Shibboleth functions at the level of the http server, no language-specific configuration is required. Therefore, any web application can use Shibboleth for authentication, regardless whether it is written in PHP, Perl, Java, VB.NET, or C#.NET, etc. In some cases, however, it might be required to use Apache (or IIS) as a reverse proxy to shield the actual web application (which might for example be running on Apache Tomcat). An example setup for this scenario is described elsewhere.

In this document, we will set up Shibboleth 2 for use with Apache and connect it to SURFconext.  We use a recent Debian GNU/Linux system, but instructions should carry over to other UNIX-like system pretty straightforwardly.  The Shibboleth Wiki describes installation of Shibboleth on other systems and platforms more extensively.

In this document, we will show you step by step how to set up an SP.  As an example, we will use the test-SP My First SP at https://mfsp.gadgets.surfconext.nl/ . For your own SP, you will have to change the configuration examples to match you local setup!

If you encounter any problems while following these instructions, please feel free to contact us at support@surfconext.nl.

A security checklist for Shibboleth can be found here.

Setting up Shibboleth

Start by setting up Apache 2 as you normally would.  The SP to connect to SURFconext should be using HTTPS with valid certificates (self-signed certificates do not suffice).  An example configuration file for the SP could look like this:

<VirtualHost _default_:443>
        Servername mfsp.gadgets.surfconext.nl
        ServerAdmin bas.zoetekouw@surfnet.nl

        DocumentRoot /var/www/mfsp
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
        </Directory>

        SSLEngine on
        SSLCertificateFile    /etc/ssl/certs/yourhost.crt
        SSLCertificateKeyFile /etc/ssl/private/yourhost.key
</VirtualHost>

Then, install Shibboleth 2.  In Debian and Ubuntu, the package is called libapache2-mod-shib2, and simply apt-getting will work fine. However, this will currently install an older version, non-supported version of Shibboleth SP (namely version 2.4.3). If you want a newer version (currently 2.5.1), you should add a different Ubuntu repository from SWITCH. Follow the instructions here.

Note that in this tutorial, we assume that Shibboleth Service Provider v2.4.3 is used. Older versions of Shibboleth use different options in the configuration file. The Shibboleth developers provide packages for Redhat Linux, CentOS, SUSE, and OpenSUSE.  Installation instructions for these platforms can be found at the Shibboleth wiki.

Shibboleth consists of two parts: a daemon (shibd) that handles communication with the SP and IdPs, and an Apache module that handles the authentication in the web server.  Make sure that the daemon is running, and that the Apache module is loaded (a2enmod shib2; apachectl -k graceful).

If everything is set up correctly, you should be able to reach https://mfsp.gadgets.surfconext.nl/Shibboleth.sso/Status (substitute your local host name, obviously).  This should show Shibboleth status information in XML form.  Note that this link will only work from a remote machine if you modify the access control list (acl) attribute of the <Handler type="Status"> entry in the /etc/shibboleth/shibboleth2.xml file.
The file should look like this:

<StatusHandler time="2011-10-14T14:06:55Z">
  <Version Xerces-C="3.1.1" XML-Tooling-C="1.4.2" XML-Security-C="1.6.1" OpenSAML-C="2.4.3" Shibboleth="2.4.3"/>
  <NonWindows sysname="Linux" nodename="mfsp" release="2.6.37-1-686" version="#1 SMP Tue Feb 15 18:21:50 UTC 2011" machine="i686"/>
  <SessionCache>
    <OK/>
  </SessionCache>
  <Application id="default" entityID="https://sp.example.org/shibboleth"/>
  <Handlers>
    <Handler type="ArtifactResolutionService" Location="/Artifact/SOAP" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"/>
    <Handler type="AssertionConsumerService" Location="/SAML2/POST" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
    <Handler type="AssertionConsumerService" Location="/SAML2/POST-SimpleSign" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"/>
    <Handler type="AssertionConsumerService" Location="/SAML2/Artifact" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
    <Handler type="AssertionConsumerService" Location="/SAML2/ECP" Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"/>
    <Handler type="AssertionConsumerService" Location="/SAML/POST" Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"/>
    <Handler type="AssertionConsumerService" Location="/SAML/Artifact" Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"/>
    <Handler type="SessionInitiator" Location="/Login"/>
    <Handler type="SingleLogoutService" Location="/SLO/SOAP" Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"/>
    <Handler type="SingleLogoutService" Location="/SLO/Redirect" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"/>
    <Handler type="SingleLogoutService" Location="/SLO/POST" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
    <Handler type="SingleLogoutService" Location="/SLO/Artifact" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
    <Handler type="LogoutInitiator" Location="/Logout"/>
    <Handler type="MetadataGenerator" Location="/Metadata"/>
    <Handler type="Status" Location="/Status"/>
    <Handler type="Session" Location="/Session"/>
    <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
  </Handlers>
  <Status>
    <OK/>
  </Status>
</StatusHandler>

Setting up your SP in Shibboleth

Next, Shibboleth needs to be set up as an SP.  The configuration process is described more eloborately at https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPGettingStarted, but the instructions below should get you up to speed quickly.

Start by generating a new SSL key pair.  This key pair will be used to sign metadata and SAML messages that are exchanged between SURFconext and your SP.

openssl req -newkey rsa:4096 -new -x509 -days 365 -nodes -text -out shib.crt -keyout shib.key

This will give you a private key (shib.key) and a public certificate (shib.crt) that are valid for one year.  Note that the public certificate does not need to be signed by a CA;  the public keys will be exchanged with SURFconext over a secure HTTPS connection, which will need to have a properly signed key.

The public and private keys should be placed in /etc/shibboleth. Protect the private key file against unauthorized access with the following command:

chmod 600 /etc/shibboleth/shib.key

Edit /etc/shibboleth/shibboleth2.xml and make the following changes:  

  • Change the entityID in the <ApplicationDefaults> section to the URI of your SP.  This defines the name by which SURFconext will refer to your SP.  The value should be a proper URL, for example 

    <ApplicationDefaults entityID="https://mfsp.gadgets.surfconext.nl/shibboleth"
                         REMOTE_USER="eppn persistent-id targeted-id">
  • In the <ApplicationDefaults> section, add the names of the key and certificate file that you have just created.

    <CredentialResolver type="File" key="shib.key" certificate="shib.crt"/>
  • Inside the <ApplicationDefaults> section, add a MetadataProvider for SURFconext.  This tells Shibboleth where to find SURFconext's SAML metadata:
  •       <MetadataProvider type="XML"
                            uri="https://engine.surfconext.nl/authentication/idp/metadata"
                            backingFilePath="metadata-surfconext.xml"
                            reloadInterval="7200">
            <MetadataFilter type="RequireValidUntil" maxValidityInterval="172800"/>
          </MetadataProvider>
    
  • Inside the <ApplicationDefaults> section should be a <Sessions> section. In there, add a Single Sign-On entry for SURFconext.  This tells Shibboleth that SURFconext users can use Single Sign-On and that authentication information with SURFconext should be exchanged using SAML2.

    <SSO entityID="https://engine.surfconext.nl/authentication/idp/metadata">SAML2</SSO>

Result

After these changes, the shibboleth2.xml file should look like this:

<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
  xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
  clockSkew="180">

  <ApplicationDefaults entityID="https://mfsp.gadgets.surfconext.nl/shibboleth"
             REMOTE_USER="eppn persistent-id targeted-id">
    <Sessions lifetime="28800" timeout="3600" checkAddress="false" relayState="ss:mem" handlerSSL="false">
      <SSO entityID="https://engine.surfconext.nl/authentication/idp/metadata">SAML2</SSO>
      <Logout>SAML2 Local</Logout>
      <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
      <Handler type="Status"            Location="/Status"/>
      <Handler type="Session"           Location="/Session" showAttributeValues="false"/>
      <Handler type="DiscoveryFeed"     Location="/DiscoFeed"/>
    </Sessions>
    <Errors supportContact="root@localhost" logoLocation="/shibboleth-sp/logo.jpg" styleSheet="/shibboleth-sp/main.css"/>
    <MetadataProvider type="XML" uri="https://engine.surfconext.nl/authentication/idp/metadata" backingFilePath="metadata-surfconext.xml" reloadInterval="7200">
      <MetadataFilter type="RequireValidUntil" maxValidityInterval="172800"/>
    </MetadataProvider>
    <AttributeExtractor type="XML" validate="true" path="attribute-map.xml"/>
    <AttributeResolver type="Query" subjectMatch="true"/>
    <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
    <CredentialResolver type="File" key="shib.key" certificate="shib.crt"/>
  </ApplicationDefaults>
  <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
  <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
</SPConfig>

Now, restart Shibd.  It should tell you (in the logs in /var/log/shibboleth/) that it is fetching metadata from SURFconext.  The message you're looking fore will look like this:

2011-10-17 13:49:15 INFO OpenSAML.MetadataProvider.XML : loaded XML resource (https://engine.surfconext.nl/authentication/idp/metadata)

Setting up Apache

Now we need to setup Apache to require Shibboleth-based authentication. Add the following entry to your apache vhost configuration:

<Location /secure>
  AuthType shibboleth
  ShibRequestSetting requireSession 1
  require valid-user
</Location>

to enable Shibboleth-authentication for all files under https://mfsp.gadgets.surfconext.nl/secure.  See the Shibboleth wiki for more information about the available configuration options.
If you visit anything under https://mfsp.gadgets.surfconext.nl/secure., Apache and Shibboleth should now try to authenticate using the SURFconext IdP. As your SP is not yet registered with SURFconext, you should get the following error message:

Connecting your SP

At this point, you should contact support@surfconext.nl and ask for permission to connect your SP to SURFconext. The default situation is that you will be connected to the Do-It-Yourself test platform first. This allows you to test the connection and authentication.

When sending in the request, be sure to include the following information:

  • the name of your service as will be presented to endusers;
  • a description of the functionality your SP offers;
  • a link to your SP's metadata (e.g, https://mfsp.gadgets.surfconext.nl/Shibboleth.sso/Metadata);
  • a list of IdPs (institutions) that will need access to your SP;
  • A name and email address of a technical contact person responsible for the service;
  • the attrubtes you wish to use for this service.

For a Production setup with the SURFconext platform, you also need to include the data as specified in the SP Metadata Requirements

This can be done with the template property of the MetadataGenerator

<Handler type="MetadataGenerator"
                Location="/Metadata"
                template="sp-metadataTemplate.xml"
                signing="false"/>

Your sp-metadataTemplate.xml can be based on https://engine.surfconext.nl/authentication/sp/metadata. Download this metadata, place it in the /etc/shibboleth directory and rename it to sp-metadataTemplate.xml. Change the relevant sections to reflect your organisation. Note that you do not have to replace the certificate, signature, entityID or other fields that Shibboleth can generate itself with the provided configuration. Shibboleth is intelligent enough to replace these fields with the values of your specific install. More information on Shibboleth's MetadataGenerator Handler can be found here.

The SURFconext administrators will contact you when you SP has been added, and they might ask you to verify that everything works as expected.

Testing

When your SP has been added to SURFconext, and you visit the secure part of your site (e.g., https://mfsp.gadgets.surfconext.nl/secure ), you should be presented with a so-called WAYF (Where Are You From) screen. There, the user can select which IdP he would like to use for authentication. This could look like this:

Which IdPs are shown depends on the configuration of SURFconext. By default only the IdPs that have explicitly allowed access to your service are shown here. In addition, the Guest IdP can be used by other people to login.

After selection, the user is asked to log in at his local institute, and is redirected back to your website. To make the web application aware of how the authentication was handled, Shibboleth sets a number of server variables that can be accessed formt he web application.

To test if everything works correctly, put the following simple PHP script in https://mfsp.gadgets.surfconext.nl/secure/test.php

:

<html>
<head><title>Shibboleth test</title></head>
<body><pre><?php print_r($_SERVER); ?></pre></body>
</html>

The output from this script (after successful authentication) should contain (apart from regular Apache server variables) a number of Shibboleth-specific variables:

    [Shib-Application-ID] => default
    [Shib-Session-ID] => _1597c53856f95eb328b232e0dc74702d
    [Shib-Identity-Provider] => https://engine.surfconext.nl/authentication/idp/metadata
    [Shib-Authentication-Instant] => 2011-11-02T10:55:35Z
    [Shib-Authentication-Method] => urn:oasis:names:tc:SAML:2.0:ac:classes:Password
    [Shib-AuthnContext-Class] => urn:oasis:names:tc:SAML:2.0:ac:classes:Password
    [Shib-Session-Index] => 82a98744094c34a839f91800239d7a10
    [persistent-id] => https://engine.surfconext.nl/authentication/idp/metadata!https://mfsp.gadgets.surfconext.nl/shibboleth! 8e01d4e3965255f4e3beeeae42e84f357fa87a84

The meaning of these variables is described at the Shibboleth wiki.

Asking for the right attributes

As you can see in the example above, only a limited number of attributes are passed from Shibboleth to the web server. In order to get additional attributes, you need to edit the file /etc/shibboleth/attribute-map.xml. This file defines the mapping between SAML attributes and Apache server variables.

In order to get the default SURFconext attributes, the file /etc/shibboleth/attribute-map.xml needs to be replaced with the following:

<?xml version="1.0"?>
  <Attributes xmlns="urn:mace:shibboleth:2.0:attribute-map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="persistent-id">
    <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$Name" defaultQualifiers="true"/>
  </Attribute>
  <Attribute name="urn:oid:1.3.6.1.4.1.1076.20.40.40.1"                  nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-user"/>
  <Attribute name="urn:mace:dir:attribute-def:displayName"                  nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-displayName"/>
  <Attribute name="urn:mace:dir:attribute-def:sn"                           nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-surName"/>
  <Attribute name="urn:mace:dir:attribute-def:cn"                           nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-commonName"/>
  <Attribute name="urn:mace:dir:attribute-def:givenName"                    nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-givenName"/>
  <Attribute name="urn:mace:dir:attribute-def:eduPersonPrincipalName"       nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-eduPersonPN"/>
  <Attribute name="urn:mace:dir:attribute-def:mail"                         nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-email"/>
  <Attribute name="urn:mace:terena.org:attribute-def:schacHomeOrganization" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-HomeOrg"/>
  <Attribute name="urn:mace:dir:attribute-def:uid"                          nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-uid"/>
  <Attribute name="urn:oid:1.3.6.1.4.1.1076.20.100.10.10.1"                 nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-userStatus"/>
  <Attribute name="urn:oid:1.3.6.1.4.1.1076.20.100.10.10.2"                 nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-voName"/>
  <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.5.1.1"                 nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" id="Shib-memberOf"/>
</Attributes>

The meaning of these attributes, as well as examples of what their values look like, can be found here.

With this new attribute mapping in place (and after restarting shibd), the server variables displayed by https://mfsp.gadgets.surfconext.nl/secure/test.php should look like:

    [Shib-Application-ID] => default
    [Shib-Session-ID] => _51601ddffbb5537cc24295a8f5804d11
    [Shib-Identity-Provider] => https://engine.surfconext.nl/authentication/idp/metadata
    [Shib-Authentication-Instant] => 2011-11-02T12:36:03Z
    [Shib-Authentication-Method] => urn:oasis:names:tc:SAML:2.0:ac:classes:Password
    [Shib-AuthnContext-Class] => urn:oasis:names:tc:SAML:2.0:ac:classes:Password
    [Shib-Session-Index] => 82a98744094c34a839f91800239d7a10
    [Shib-HomeOrg] => surfnet.nl
    [Shib-commonName] => Bas Zoetekouw
    [Shib-displayName] => Bas Zoetekouw
    [Shib-eduPersonPN] => bas@surfnet.nl
    [Shib-email] => Bas.Zoetekouw@surfnet.nl
    [Shib-givenName] => Bas
    [Shib-surName] => Zoetekouw
    [Shib-uid] => bas
    [Shib-userStatus] => member
    [Shib-memberOf] => urn:collab:org:surf.nl
    [Shib-user] => urn:collab:person:surfnet.nl:bas
    [persistent-id] => 8e01d4e3965255f4e3beeeae42e84f357fa87a84

That's all folks!

At this point, your SP is successfully coupled to SURFconext. Congratulations!

  • No labels