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

Compare with Current View Page History

« Previous Version 4 Next »

The scripts below show how to use SimpleSAMLphp to:

  • Request a specific minimum level op assurance (LoA) from the Strong Authentication gateway
  • Verify the LoA at which the user is authenticated

To use this scripts:

  1. Configure a SimpleSAMLphp SAML 2.0 hosted SP with the name "default-sp" (instructions).
  2. Add the Strong Authentication gateway as SAML 2.0 identity provider to <simplesaml>/metadata/saml20-idp-remote.php. See second example below.
  3. Put the sp.php script in the <simplesaml>/www directory.

 

sp.php
/*
Copyright 2014 SURFnet bv
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
    http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
 
<?php
// Include SimpleSAMLphp. Assume this script is placed in the <simplesaml>/www dir.
require_once('../lib/_autoload.php');
 
// Name of session variable for storing the minimum required LOA for a login
define( 'SSP_SESSION_MIN_LOA', 'RequestedMinLOA' );
 
// Build return URL. This is where to ask simplesamlPHP to direct the browser to after login or logout
// Point to this script, but without any request parameters so we won't trigger an login again (and again, and again, and ...)
$returnURL = ($_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
$returnURL .= $_SERVER['HTTP_HOST'];
$returnURL .= $_SERVER['SCRIPT_NAME'];
 
// Map integer level of assurance level to the identifier used by SURFconext Strong Authentication
// Note: The identifiers below are for the SURFconext Strong Authentication production gateway, when connecting to another
//       environment, update the identifiers accordingly. E.g. for pilot use 'http://pilot.surfconext.nl/assurance/loa1', etc...
$gLOAmap = array(
    1 => 'http://surfconext.nl/assurance/loa1',
    2 => 'http://surfconext.nl/assurance/loa2',
    3 => 'http://surfconext.nl/assurance/loa3',
);
 
try {
    // Init SP instance
    // Assumes you have setup a SP named "default-sp" in <simplesaml>/config/authsources.php
    // See: https://simplesamlphp.org/docs/stable/simplesamlphp-sp
    $as = new SimpleSAML_Auth_Simple('default-sp');    // Init SP instance
 
    /** @var $session SimpleSAML_Session */
    $session = SimpleSAML_Session::getInstance();
 
    // Process login action. Assumes the login function of your SP uses ...?action=login
    if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'login' ) {
 
        // We use the SSP session to keep track of the LOA we want.
        // Unset any existing RequiredAuthnContextClassRef
        $session->deleteData('string', SSP_SESSION_MIN_LOA);
 
        // login
        $requiredLOA = 2; // The LOA we want.
 
        // Store the requested LOA in the session so we can verify it later
        $session->setData('string', SSP_SESSION_MIN_LOA, $requiredLOA);
 
        $as->login( array(
            'ReturnTo' => $returnURL,
            'ForceAuthn' => false,
            'saml:AuthnContextClassRef' => $gLOAmap[$requiredLOA]  // Specify LOA
        ) );
 
        exit;   // Never reached. Added for clarity
    }
 
    // Process logout action
    if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'logout' ) {
        $as->logout( array (
            'ReturnTo' => $returnURL,
        ) );  // Process logout
 
        exit;   // Never reached. Added for clarity
    }
 
    // Output HTML page
 
    echo <<<head
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
            <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
            <style type="text/css">
                table,th,td {border: 1px solid black;}
                th,td {padding 1px}
            </style>
            <title>simpleSAMLphp Demo</title>
        </head>
        <body>
            <h1>SimpleSAMLphp LOA Demo</h1>
head;
 
    // Page to show when SAML authentication was successful
    if ( $as->isAuthenticated() ) {
        $attributes = $as->getAttributes();
 
        $requestedLoA = $session->getData('string', SSP_SESSION_MIN_LOA);    // What we requested during login
        $authState = $session->getAuthState();
        $authnConext = $authState['saml:sp:AuthnContext'];
        $nameID = $session->getNameID();
        $authnInstant = gmdate('r', $authState['AuthnInstant'] );
        $expire = gmdate('r', $authState['Expire'] );
 
        echo "<h2>You are logged in</h2>";
 
        echo "<h3>SimpleSAMLphp Session</h3>";
        echo "<p>SimpleSAMLphp session start: <b>{$authnInstant}</b></br />";
        echo "SimpleSAMLphp session expire: <b>{$expire}</b></p>";
 
        echo "<h3>LOA</h3>";
        echo "<p>Received authnConext: <b>{$authnConext}</b></p>";
 
        // We still need to verify that the Authentication is at the LoA we requested
        // Map LoA identifier back to integer LoA level
        $actualLoA = array_search($authnConext, $gLOAmap);
        if (false ==! $actualLoA)
            echo "<p>Actual LoA is: <b>{$actualLoA}</b></p>";
        else
            $actualLoA = -1;
 
        if (NULL !== $requestedLoA) {
            echo "<p>Requested LoA was: <b>{$requestedLoA}</b></p>";
            if ($actualLoA >= $requestedLoA)
                echo '<p><b>You were authenticated at or above the minimally required LoA</b></p>';
            else {
                echo '<p><b>You were NOT authenticated at the required LoA</b></p>';
                // TODO: Handle this authentication failure
            }
        }
 
        echo <<<html
        <h3>NameID</h3>
        <table>
            <tr><th>Value</th><td>{$nameID['Value']}</td></tr>
            <tr><th>Format</th><td>{$nameID['Format']}</td></tr>
        </table>
html;
        echo <<<html
        <h3>SAML Attributes</h3>
        <table>
            <tr><th>Attribute</th><th>Value(s)</th></tr>
html;
        foreach ($attributes as $attrName => $attrVal) {
            echo "<tr><td>{$attrName}</td><td>";
            if (is_array($attrVal))
                echo implode('<br />', $attrVal);
            else
                echo $attrVal;
            echo "</td>";
        }
        echo <<<html
        </table>
 
        <h3>Logout</h3>
        <p>
            <form name="logout" action="{$returnURL}" method="get">
               <input type="hidden" name="action" value="logout"/>
               <input type="submit" value="Logout" />
            </form>
        </p>
html;
    }
 
    // User is not authenticated
    else {
        echo <<<html
            <h2>Your are not logged in</h2>
html;
    }
 
    echo <<<html
            <h3>Login (again)</h3>
            <p>
                <form name="login" action="{$returnURL}" method="get">
                   <input type="hidden" name="action" value="login"/>
                   <input type="submit" value="Login" />
                </form>
            </p>
html;
 
    echo <<<html
        </body>
    </html>
html;
}
catch (Exception $e)
{
    echo $e->getFile().':'.$e->getLine().' : '.$e->getMessage();
} 
saml20-idp-remote.php
<?php
// SURFconext Strong Authentication production environment
$metadata['https://sa-gw.surfconext.nl/authentication/metadata'] = array (
    'entityid' => 'https://sa-gw.surfconext.nl/authentication/metadata',
    'metadata-set' => 'saml20-idp-remote',
    'SingleSignOnService' =>
        array (
            0 =>
                array (
                    'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
                    'Location' => 'https://sa-gw.surfconext.nl/authentication/single-sign-on',
                ),
        ),
    'keys' =>
        array (
            0 =>
                array (
                    'encryption' => false,
                    'signing' => true,
                    'type' => 'X509Certificate',
                    'X509Certificate' => 'MIICsjCCAZoCCQDHN3+HzElEDDANBgkqhkiG9w0BAQUFADAbMRkwFwYDVQQDFBBnYXRld2F5X3NhbWxfaWRwMB4XDTE1MDcyMzEyMTUxOVoXDTIwMDcyMTEyMTUxOVowGzEZMBcGA1UEAxQQZ2F0ZXdheV9zYW1sX2lkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALK/JwHWd5JftXYKO9qcTQ4dfKEnl35oJj6PlEyR6gpikdpgm2OY/zy4e7vcXfBChedVF3OUI4rRDWCz4yXT2sldzjuIyONJfA86xva5lxDARqT/+gRBuZ2pyMTb0okvl1G9ZlAjPumVH14591rp6OGT5TJIkILQ/pKp1INdiBqpiR53Z5YvsXEUJ8PHHZyILO00HnBldq0d77lmATr6QamXpbY+CZ9pIw65t32fhFcUfRC68C81/P2crCn3v5GMyrQcM/tB/xdVf/haEZiqgI/bjcreBpQobnAhwEsve+uvbSLFN1Rsc7o0W/7Pn6EGBX1h9rjKjDgqssHuWkVuU4sCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAmlqfTvEfGDeqqqvuAMDG5IKDo6h21wwByywNbRhimfOvL6FqIgAgx+D3gxW1lO41PcqQQKYIVUEAuYv+tW8COLdHcFRh/UV9ei4iquMwBCkO/XOoMC9FsRBo3yPaQClRK8OYj1IXer4JXNuFHeLblzf+GLYFoqMWWwT2dnBLAePoEgANKUm2aasxyiJmnroNa+O5zTP9ExT3qHphCCG1gh3iHrQu9iSEJxY12zAQYtPomIs8Vk/GBfj+ucUiBEEqaMpCH+t6f0VOIoP1SNHgNAaeBLVuOpS0VlLnwZFJkNPVOQpFgRuoFsH3/9i53Fs3eQreb9wzq2VkjDhhlc5eyA==',
                ),
        ),
);
 
// SURFconext Strong Authentication pilot environment
$metadata['https://gateway.pilot.stepup.surfconext.nl/authentication/metadata'] = array (
    'entityid' => 'https://gateway.pilot.stepup.surfconext.nl/authentication/metadata',
    'metadata-set' => 'saml20-idp-remote',
    'SingleSignOnService' =>
        array (
            0 =>
                array (
                    'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
                    'Location' => 'https://gateway.pilot.stepup.surfconext.nl/authentication/single-sign-on',
                ),
        ),
    'keys' =>
        array (
            0 =>
                array (
                    'encryption' => false,
                    'signing' => true,
                    'type' => 'X509Certificate',
                    'X509Certificate' => 'MIICwjCCAaoCCQDs1IDIiytYMTANBgkqhkiG9w0BAQUFADAjMSEwHwYDVQQDDBhTdGVwdXAgUGlsb3QgR2F0ZXdheSBJZFAwHhcNMTUwMjI3MTA0MTU5WhcNMjUwMjI0MTA0MTU5WjAjMSEwHwYDVQQDDBhTdGVwdXAgUGlsb3QgR2F0ZXdheSBJZFAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzlSzxPhG+B+o0ulUcR499NoMhaP4oX0+zpzi2vfY+Q1qw8x6b0eeUrIk99IpMrWN74twvuQ/eIecLZXIYhG94AYGB620OX7KMM8oCfdjc2I0lk8d+/rsxUqH0U4DDVBryrMcLjLGwe2CMncdSBuc2LCg15TveClC/QW/NJ6rvDiR1GoLouqx+CLBd+z2gwC+Od7YTUVY+22XrVzatzOZuz8Wdvja4VxHzv9Qyi6ta78ah345HWLeZsIh6pRF80qX0lpPRgwQSVXNpT8IxvoL28ViVVGkLU5SmdS3fbfLzlL5i3jHpWFcvRGPj5z8zmVZuDAka6P80WiKDVRg7gouXAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBANlnKHackl7MfHi+0lxb/ERuMkRpIGej29RSWL0aFojNpRjN2ihnuIjp4PPk98xQCKbVeN+PWXNqrrschbUfC5ikcYP5hoU7WJrHAWvEwmMNy1/UzcKtSgNby8loLFRzi68R92ZTumgFEBFYow9HzgC3HvDeBpRw/qFLZjsYqAjezTeRtafx8NIaBtKabRr5hedwUpnzldFbPqLxR1o0B/tqcUIqJOjdpEFIYus7VcBI6N6T1TKB4DyfqjbgzxhS5zrE1jFeKaamRWCqKUcEUfngoxQWlKd9LSBWRXjw0aM+P22WHdxxX/1rIneV5jVgOIlRgDO0Dpxn0qie4XnIqzo=',
                ),
        ),
);

 

 

 

  • No labels