Table of Contents

Leitfaden für Service Owners

Connecting to our Identity Providers (IdPs)

We provide you with the flexibility to connect your services to our IdP solutions through two protocols: SAML and OIDC. These protocols ensure a secure and smooth integration, allowing for seamless authentication and authorization processes for your applications.

1: Security Assertion Markup Language (SAML):

SAML allows for secure single sign-on (SSO) and federation across different applications and platforms. It enables the exchange of user authentication and authorization information in a standardized way, ensuring smooth communication between your services and our IdPs.

GWDG Academic ID SAML Solutions:

SimpleSAMLphp:

SimpleSAMLphp (https://simplesamlphp.org) is an open-source software package for providing IAM functionalities and features. It is written in PHP and supports straightforward integration of new customizable modules. SimpleSAMLphp is often used to provide authentication and authorization services for web-based applications; however, it also supports native mobile apps and APIs using different protocols, including SAML, OIDC, and OAuth. It is designed to be easy to install and configure and can be used as a standalone application or as a module within other applications.

Shibboleth:

Shibboleth (https://www.shibboleth.net) is a type of open-source SAML implementation developed by the Shibboleth Consortium. It provides content personalization, secure authentication, and authorization and enables SSO functionality for accessing services in multiple domains. Shibboleth has been designed to be compatible with many organizational domains' infrastructures to support general FIM requirements.

Information We Need from You:

To connect your services to our SAML SSO solution, we request the following information from you:

Once you have collected this information, please submit it to our support team at sso-support@gwdg.de.

Information You Need from Us:

We will provide you with the necessary SAML metadata, which is an XML document containing important configuration details about the IdP you requested to connect. The metadata includes information such as URLs of endpoints, supported bindings, identifiers, and public keys. Depending on your application framework or platform, you will need to locate the appropriate configuration file or settings where you can specify the IdP's metadata. This step ensures that your application recognizes and trusts our IdP. If your application doesn't have built-in SAML support, you can leverage external libraries specifically designed for SAML communication. These libraries provide pre-built functionalities and utilities for SAML authentication, simplifying the integration process. Choose a library that suits your programming language and framework.Please note that the specific implementation details may vary depending on your application framework, platform, and the chosen library. It is recommended to consult the documentation and resources specific to your application or chosen library for detailed instructions. After completing the configuration, thoroughly test the integration by initiating SSO requests and validating the SAML responses. Ensure that the authentication flow is seamless and that user attributes and assertions are correctly processed.

2: OpenID Connect (OIDC):

In addition to SAML, we support OIDC as an alternative protocol for integrating your services with our IdPs. OIDC is an identity layer built on top of the OAuth 2.0 framework. It extends the OAuth 2.0 authorization protocol to provide an additional authentication protocol. OIDC allows third-party applications to verify the identity of end-users and obtain basic user profile information. It uses JSON web tokens (JWTs) to exchange information between the client application and the OpenID Provider (OP).

GWDG Academic ID OIDC Solution:

Keycloak:

Keycloak is a Red Hat-sponsored IAM solution supporting multiple protocols. Some important technologies and features supported by this open-source solution are:

Information We Need from You:

To connect your services to our OIDC solution, we require the following information from you:

Information You Need from Us:

Once you submit the required information, we will provide you with the necessary OIDC configuration details, including the client ID, client secret, authorization endpoint, token endpoint, and other relevant parameters. These details will enable you to configure your application and communicate with our OIDC provider. Similar to the SAML connection, if your application doesn't have built-in support for OIDC, you can incorporate an OIDC client library or SDK suitable for your programming language and framework. Please ensure that you follow the configuration steps carefully, handle received tokens securely within your application, and adhere to best practices for OIDC implementation.

Which Protocol Is the Best Choice for You? SAML or OIDC:

When considering whether to choose SAML or OIDC for integrating your services with our IdM or IdP solutions, it's essential to evaluate the specific benefits each protocol offers. Here are some key arguments to help you make an informed decision:

Ultimately, the best choice depends on factors such as your existing infrastructure, compatibility requirements, and specific use cases. If you are unsure which protocol is the most suitable for your needs, we recommend consulting with our team. We can assist you in assessing your application's specific requirements and guide you in making an informed decision.

Hosting IdPs

At GWDG, we offer comprehensive solutions for hosting IdPs, ensuring the secure storage and management of user identities. Our services include establishing and configuring IdPs tailored to your specific requirements. Whether you prefer cloud-hosted solutions or on-premises installations, we have the expertise to guide you through the process. Our process for setting up IdPs and integrating them into your domains is straightforward. Here's an overview of how we can assist you:

Our goal is to make the IdP setup and integration process as smooth as possible, empowering you to provide a secure and streamlined user experience. With our assistance, you can focus on delivering your core services while leaving the technical complexities to us.

If you have any questions or require further information, please don't hesitate to contact our support team. We are here to help you every step of the way.

Setting up your Service Provider (SP)

Integrating your service with the GWDG Single Sign-On (SSO) solution requires compatibility with SAML2, or OIDC authentication protocols. If your application already incorporates built-in support for these authentication protocols, you are well on your way. In such cases, you simply need to request and configure GWDG SSO settings within your application to establish connections with our Identity Providers (IdPs). However, If your application lacks built-in SSO support, you can integrate external libraries into your project and configure it to function as a Service Provider (SP). This section introduces an open-source library as an example for SAML2 authentication protocol, guiding you through its installation and configuration.

Two widely recognized options for SAML2 SSO integration into your application are the Apache module mod_shib paired with shibboleth SP and SimpleSamlPHP. The former follows a generic approach as it relies on the Apache webserver for authentication, while the latter is particularly well-suited for integration with PHP applications. Our focus here will be on explaining the basic steps involved in setting up your SP using Apache and mod_shib.


Example: Installation Guideline

This guide has been tested on Debian 8 and 9 but should work similar on ubuntu installations. For other distributions consult the official Shibboleth documentation.

1. Install packges: apt-get install libapache2-mod-shib2 libshibsp7 shibboleth-sp2-common

2. Configure /etc/sbhibboleth/shibboleth2.xml. You can use the default and configure the following values:

3. Configure /etc/shibboleth/attribute-map.xml. Adjust attribute mapping to your applications needs. 4. Configure apache to protect routes with shibboleth authentication. A protected location could look like this: <Location /> AuthType shibboleth require valid-user </Location>

5. Restart apache and shibd: systemctl restart shibd.service; systemctl restart apache2.service; or /etc/init.d/shibd restart; /etc/init.d/apache2 restart (depending on your distribution and version)

6. Check if your metadata is available. It should be found at https://sp.example.org/Shibboleth.sso/Metadata. If it looks valid, proceed to step 7. Please keep in mind that the official documentation says not to use the autogenerated Metadata. If you decide to follow this hint, make the metadata publicy available at another place and proceed to step 7.

7. Open an issue in this github project to have your metadata configured in the sso. Provide either the autoconfigured or hosted metadata link in there.


Example: Configuration

/etc/shibboleth/shibboleth2.xml

<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">

    <!--
    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
    -->

    <!--
    To customize behavior for specific resources on Apache, and to link vhosts or
    resources to ApplicationOverride settings below, use web server options/commands.
    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
    
    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
    -->

    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
    <ApplicationDefaults entityID="https://sp.example.org/shibboleth"
                         REMOTE_USER="eppn persistent-id targeted-id">

        <!--
        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
        You MUST supply an effectively unique handlerURL value for each of your applications.
        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
        Note that while we default checkAddress to "false", this has a negative impact on the
        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
        -->
        <Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
                  checkAddress="false" handlerSSL="false" cookieProps="http">

            <!--
            Configures SSO for a default IdP. To allow for >1 IdP, remove
            entityID property and adjust discoveryURL to point to discovery service.
            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
            You can also override entityID on /Login query string, or in RequestMap/htaccess.
            -->
            <SSO entityID="https://sso.example.org/simplesaml/saml2/idp/metadata.php">
              SAML2 SAML1
            </SSO>

            <!-- SAML and local-only logout. -->
            <Logout>SAML2 Local</Logout>
            
            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>

            <!-- Status reporting service. -->
            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>

            <!-- Session diagnostic service. -->
            <Handler type="Session" Location="/Session" showAttributeValues="true"/>

            <!-- JSON feed of discovery information. -->
            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
        </Sessions>

        <!--
        Allows overriding of error template information/filenames. You can
        also add attributes with values that can be plugged into the templates.
        -->
        <Errors supportContact="root@localhost"
            helpLocation="/about.html"
            styleSheet="/shibboleth-sp/main.css"/>
        
	   <MetadataProvider
                type="XML"
                uri="https://sso.example.org/simplesaml/saml2/idp/metadata.php"
                backingFilePath="/etc/shibboleth/metadata/sso.example.org.xml"
                reloadInterval="7200">
              </MetadataProvider>



        <!-- Example of remotely supplied batch of signed metadata. -->
        <!--
        <MetadataProvider type="XML" uri="http://federation.org/federation-metadata.xml"
              backingFilePath="federation-metadata.xml" reloadInterval="7200">
            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
        </MetadataProvider>
        -->

        <!-- Example of locally maintained metadata. -->
        <!--
        <MetadataProvider type="XML" file="partner-metadata.xml"/>
        -->

        <!-- Map to extract attributes from SAML assertions. -->
        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
        
        <!-- Use a SAML query if no attributes are supplied during SSO. -->
        <AttributeResolver type="Query" subjectMatch="true"/>

        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>

        <!-- Simple file-based resolver for using a single keypair. -->
        <CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>

        <!--
        The default settings can be overridden by creating ApplicationOverride elements (see
        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
        Resource requests are mapped by web server commands, or the RequestMapper, to an
        applicationId setting.
        
        Example of a second application (for a second vhost) that has a different entityID.
        Resources on the vhost would map to an applicationId of "admin":
        -->
        <!--
        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
        -->
    </ApplicationDefaults>
    
    <!-- Policies that determine how to process and authenticate runtime messages. -->
    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>

    <!-- Low-level configuration about protocols and bindings available for use. -->
    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>

</SPConfig>

/etc/shibboleth/attribute-map.xml

    <!--
    The mappings are a mix of SAML 1.1 and SAML 2.0 attribute names agreed to within the Shibboleth
    community. The non-OID URNs are SAML 1.1 names and most of the OIDs are SAML 2.0 names, with a
    few exceptions for newer attributes where the name is the same for both versions. You will
    usually want to uncomment or map the names for both SAML versions as a unit.
    -->
    
    <!-- First some useful eduPerson attributes that many sites might use. -->
    
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" id="eppn">
        <AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
    </Attribute>
    
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" id="affiliation">
        <AttributeDecoder xsi:type="ScopedAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" id="unscoped-affiliation">
        <AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" id="entitlement"/>

    <Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail"/>
    
    <Attribute name="urn:oid:0.9.2342.19200300.100.1.1" id="uid"/>


    <!-- A persistent id attribute that supports personalized anonymous access. -->
    <Attribute name="urn:mace:dir:attribute-def:eduPersonTargetedID" id="targeted-id">
        <AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
    </Attribute>

    <!-- Second, an alternate decoder that will decode the incorrect form into the newer form. -->
    <!-- 
    <Attribute name="urn:mace:dir:attribute-def:eduPersonTargetedID" id="persistent-id">
        <AttributeDecoder xsi:type="NameIDFromScopedAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
    </Attribute>
    -->
    
    <!-- Third, the new version (note the OID-style name): -->
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" id="persistent-id">
        <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
    </Attribute>

    <!-- Fourth, the SAML 2.0 NameID Format: -->
    <Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="persistent-id">
        <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
    </Attribute>
    
    <!-- Some more eduPerson attributes, uncomment these to use them... -->
    <!--
    <Attribute name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" id="primary-affiliation">
        <AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    <Attribute name="urn:mace:dir:attribute-def:eduPersonNickname" id="nickname"/>
    <Attribute name="urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN" id="primary-orgunit-dn"/>
    <Attribute name="urn:mace:dir:attribute-def:eduPersonOrgUnitDN" id="orgunit-dn"/>
    <Attribute name="urn:mace:dir:attribute-def:eduPersonOrgDN" id="org-dn"/>

    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.5" id="primary-affiliation">
        <AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.2" id="nickname"/>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.8" id="primary-orgunit-dn"/>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.4" id="orgunit-dn"/>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.3" id="org-dn"/>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" id="assurance"/>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.5.1.1" id="member"/>
 
    -->

    <!-- Examples of LDAP-based attributes, uncomment to use these... -->
    <!--
    <Attribute name="urn:oid:2.5.4.3" id="cn"/>
    <Attribute name="urn:oid:2.5.4.4" id="sn"/>
    <Attribute name="urn:oid:2.5.4.42" id="givenName"/>
    <Attribute name="urn:oid:2.16.840.1.113730.3.1.241" id="displayName"/>
    <Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail"/>
    <Attribute name="urn:oid:2.5.4.20" id="telephoneNumber"/>
    <Attribute name="urn:oid:2.5.4.12" id="title"/>
    <Attribute name="urn:oid:2.5.4.43" id="initials"/>
    <Attribute name="urn:oid:2.5.4.13" id="description"/>
    <Attribute name="urn:oid:2.5.4.7" id="l"/>
    <Attribute name="urn:oid:2.5.4.10" id="o"/>
    <Attribute name="urn:oid:2.5.4.11" id="ou"/>
    -->

</Attributes>

/etc/apache2/site-enabled/ssl.conf

<VirtualHost *:443>

  DocumentRoot /var/www/html

  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>
  <Directory /var/www/>
    Options Indexes FollowSymLinks
		AllowOverride All
		Order allow,deny
		allow from all
  </Directory>
    # always fill env with shib variable
    <Location />
        AuthType shibboleth
        ShibRequestSetting requireSession false
        Require shibboleth
    </Location>

  <Location /index.php/login>
    AuthType shibboleth
    ShibRequireSession On
    ShibUseHeaders Off
    ShibExportAssertion On
    require valid-user
  </Location>

  ServerName sp.example.org
  UseCanonicalName On
SSLCertificateFile /etc/letsencrypt/live/sp.example.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sp.example.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>