How To Set Up SSO in Apache using SimpleSAMLphp and ADFS on Ubuntu 20.04

This tutorial will show you how to configure single sign-on and enable Active Directory authentication in Apache using SimpleSAMLphp on Ubuntu 20.04. 

SSO is a property of access control of multiple related, yet independent, software systems. With this property, a user logs in with a single ID and password to gain access to a connected system or systems without using different usernames or passwords, or in some configurations seamlessly sign on at each system. 

SimpleSAMLphp is an award-winning application written in native PHP that deals with authentication. It authenticates the user against a SAML 2.0 IdP, and grants access to resources depending on attributes received from the identity provider (IdP). 

AD FS is a software component developed by Microsoft that can be installed on Windows Server operating systems to provide users with single sign-on access to systems and applications located across organizational boundaries. 

Apache is the most widely-used web server in the world. It provides many powerful features including dynamically loadable modules, robust media support, and extensive integration with other popular software.
 

Prerequisites

To follow this tutorial along, you will need one (physical or virtual) machine installed with Ubuntu 20.04. These instruction assume that your Active Directory domain and AD FS service are already in place. 
 
When you have all the prerequisites in place, you can proceed with below steps. 
 

Install Required Packages

Login to your Ubuntu system using non-root sudo privileges and install these required packages:
sudo apt -y install apache2 openssl php7.4 php7.4-fpm php7.4-gd php7.4-mysql php7.4-mbstring php7.4-common php7.4-curl php-memcache php7.4-xml php7.4-ldap php7.4-cli php7.4-json php7.4-radius php7.4-mysql perl git wget nano ntpdate
 

Configure PHP

Edit php.ini files and update date.timezone parameter your timezone:
sudo nano /etc/php/7.4/fpm/php.ini
Change:
 
;date.timezone =
 
to:
date.timezone = Asia/Karachi

Save and close the editor when you are finished.

Make sure you repeat the same step for /etc/php/7.4/cli/php.ini file as well. 

Type below to activate PHP in Apache

sudo a2enmod proxy_fcgi setenvif;sudo a2enconf php7.4-fpm
sudo systemctl restart php7.4-fpm
sudo systemctl restart apache2
 

Download SimpleSAMLphp

You can check latest stable release at GitHub repository. You can download stable release on your Ubuntu system like below:
cd ~
wget https://github.com/simplesamlphp/simplesamlphp/releases/download/v1.18.8/simplesamlphp-1.18.8.tar.gz
tar -xf simplesamlphp*.gz
sudo mv simplesamlphp-1.18.8 /usr/share/simplesamlphp
 

Create Self-signed SSL Certificate

Type below command to generate a self-signed SSL certificate for your service provider (sp.techsupportpk.com) in our case:
sudo openssl req -newkey rsa:4096 -new -x509 -days 3652 -nodes -out /usr/share/simplesamlphp/cert/sp.crt -keyout /usr/share/simplesamlphp/cert/sp.pem
Enter appropriate information on the following prompts on your Ubuntu terminal:
Country Name (2 letter code) [AU]:PK
State or Province Name (full name) [Some-State]:Sind
Locality Name (eg, city) []:Karachi
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tech Support Pakistan
Organizational Unit Name (eg, section) []:IT Support
Common Name (e.g. server FQDN or YOUR name) []:sp.techsupportpk.com
Email Address []:support@techsupportpk.com
Type below to create a self-signed SSL certificate for your identity provider (idp.techsupportpk.com) in our case.
sudo openssl req -newkey rsa:4096 -new -x509 -days 3652 -nodes -out /usr/share/simplesamlphp/cert/idp.crt -keyout /usr/share/simplesamlphp/cert/idp.pem
Enter appropriate information on the following prompts on your Ubuntu terminal:
Country Name (2 letter code) [AU]:PK
State or Province Name (full name) [Some-State]:Sind
Locality Name (eg, city) []:Karachi
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tech Support Pakistan
Organizational Unit Name (eg, section) []:IT Support
Common Name (e.g. server FQDN or YOUR name) []:idp.techsupportpk.com
Email Address []:support@techsupportpk.com
 

Configure SimpleSAMLphp 

Type below command to generate a random string to be used as secretsalt:
sudo tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

This will generate a random string on your Ubuntu terminal, save generated string in a text file, you will need it in a while. 

Type below to create hashed password for SimpleSAMLphp administrator account:

php /usr/share/simplesamlphp/bin/pwgen.php

This will prompt you to enter a strong password of your choice to be converted in hashed. Save hashed password in a text file, you will need it in a while. 

Edit config.php to make some important changes:

sudo nano /usr/share/simplesamlphp/config/config.php
Search below text, update their values with yours:
'technicalcontact_name' => 'Support',
'technicalcontact_email' => 'support@techsupportpk.com',

'timezone' => 'Asia/Karachi',

'secretsalt' => 'defaultsecretsalt',

'auth.adminpassword' => '123',

Save and close the editor when you are finished. 

Create a SimpleSAMLphp configuration file in Apache:

sudo nano /etc/apache2/conf-available/simplesamlphp.conf
 
Add configuration directives like an example below:
Alias /simplesaml /usr/share/simplesamlphp/www

<Directory /usr/share/simplesamlphp/www>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>

Save and close the editor when you are finished. 

Create a VirtualHost for your url (sp.techsupportpk.com) in our case:

sudo nano /etc/apache2/sites-available/techsupportpk.conf

Add below configuration directives in it:

<VirtualHost *:80>
ServerName sp.techsupportpk.com
Redirect / https://sp.techsupportpk.com/
</VirtualHost>

<VirtualHost _default_:443>
ServerName sp.techsupportpk.com
DocumentRoot /var/www/private
SSLEngine On
SSLCertificateFile /usr/share/simplesamlphp/cert/sp.crt
SSLCertificateKeyFile /usr/share/simplesamlphp/cert/sp.pem
</VirtualHost>

Save and close the editor when you are finished. 

Create a directory under /var/www/ location to store your web contents.

sudo mkdir -p /var/www/private
Verify your Apache configuration with below command:
sudo apache2ctl configtest

If everything configured correctly, this will return Syntax OK. in the output. If there any error, fix them first then move to next step. 

Activate your Apache configuration like below:

sudo a2enmod ssl
sudo a2enconf simplesamlphp.conf
sudo a2ensite techsupportpk.conf
sudo systemctl restart apache2
Synchronize your Ubuntu system clock with your AD FS like below:
sudo ntpdate idp.techsupportpk.com
Open up your preferred web browser, type https://sp.techsupportpk.com/simplesaml in the address bar, ignore browser SSL warning:
 

You will see SimpleSAMLphp dashboard like below.
 
Click Login as administrator 
 
 
If you remember, this administrator password you generated with pwgen.php command, and configured it in config.php file.
 
Enter your password, and click Login:


Once logged in, click Configuration tab to verify your PHP installation, you can safely ignore optional warning as we don't need them.
 

Navigate to Federation tab, click XML to SimpleSAMLphp metadata converter
 

Click Choose File to upload your AD FS metadata file, click Parse

This will return two sets of data. The first: saml20-sp-remote can be ignored since we are not using SimpleSAMLphp as an identity provider. 
 
Scroll to saml20-idp-remote and copy the contents of this field to the clipboard.



Go back to your Linux terminal, edit saml20-idp-remote.php file like below:
sudo nano /usr/share/simplesamlphp/metadata/saml20-idp-remote.php
 
Paste copied contents in it:

Save and close the editor when you are finished.

Edit authsources.php with any of your preferred text editor:
sudo nano /usr/share/simplesamlphp/config/authsources.php
 
Add your AD FS as an authentication source like below:
'techsupportpk-sp' => array(
    'saml:SP',
    'entityID' => null,
    'idp' => 'http://idp.techsupportpk.com/adfs/services/trust',
    'discoURL' => null,
    'sign.logout' => TRUE,
    'SignLogoutRequest' => TRUE,
    'SignLogoutResponse' => TRUE,
    'redirect.sign' => TRUE,
    'assertion.encryption' => TRUE,
    'privatekey' => 'idp.pem',
    'certificate' => 'idp.crt',
    'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
),
Save and close the editor when you are finished.

After modification, authsources.php will look similar to like below:

 
Go back to your browser, refresh https://sp.techsupportpk.com/simplesaml page, navigate to Federation tab, and you will your SP metadata entity like below:

 
You will need this SP metadata url to configure your AD FS Relying Party Trust in the next step.
 

Configure AD FS Relying Party Trust

Log in to your AD FS machine, access SP metadata url with any of your preferred web browser, save metadata file anywhere on your AD FS machine. Once you have SP metadata file downloaded, rename it like techsupportpk-sp.xml
 
Open up AD FS Management console, Right-click Relying Party Trust, Click Add Relying Party Trust 
 
Keep default Claims aware, click Start

Click Import data about the replying party from a file, click Browse, select your SP metadata xml file, click Next

 
 
You can safely ignore this warning popup, Click OK

Enter the display name, click Next
 
Keep the Permit everyone access polity, Click Next
 
Click Next
 
Click Close
 
Right-click on your Relying Party Trust entity, click Edit Claim Issuance Policy
 
Click Add Rule
 
Select Send LDAP Attributes as Claim, click Next
 
Configure claim rule like below:
 
Click Finish when you are done.
 
Add another rule, select Transform an Incoming Claim, click Next
 
Configure rule like below:
 
Click Finish when you are done.
 
Click Apply, OK

At this stage, your AD FS Relying Party Trust configuration is ready to serve the purpose.
 
 

Verify AD FS Relying Party Trust Configuration

From a web browser, access your https://sp.techsupportpk.com/simplesaml and navigate to Authentication tab, click Test configured authentication sources

 
Click on authentication source (techsupportpk-sp) in our case.


If everything configured correctly, you will be taken to your AD FS login page:


Enter your valid username and password like below to sign-in:
 
 
Upon successful login, you’ll be bounced back to SimpleSAMLphp with information of your authentication claims as you can see in screenshot below:
 
 
If you face any issue, double-check everything you configured and then check the logs for hints as to what could have gone wrong.

Test Apache SSO

Create a simple index.php page in /var/www/private/ like an example below:
cd /var/www/private
sudo nano index.php
 
Add following code in it:
<html>
<head>
<title>Index Page</title>
</head>
<body>
<?php
echo '<h2>This page is accessible to everyone without authentication!</h2>';
 echo '<a href="login.php">Login</a>';
?>
</body>
</html>
Save and close the editor when you are finished.
 
Create a simple login.php to test SSO functionality:
sudo nano login.php

Add following code in it: 
<?php
require_once ('/usr/share/simplesamlphp/lib/_autoload.php');
$as = new SimpleSAML_Auth_Simple('techsupportpk-sp');
$as->requireAuth();

$attributes = $as->getAttributes();
?>
<html>
<head>
<title>Login</title>
</head>
<body>
<?php
echo '<h2>This simple login page is accessible to only authenticated users!</h2>';
?>

<?php
echo '<pre>';
print_r($attributes);
echo '</pre>';

echo '<a href="logout.php">Logout</a>';

?>
</body>
</html>
Save and close the editor when you are finished.

Create a simple logout.php to test SLO function.
sudo nano logout.php

Add below code in it:
<?php
require_once ('/usr/share/simplesamlphp/lib/_autoload.php');
$as = new SimpleSAML_Auth_Simple('techsupportpk-sp');

$as->logout(array(
'ReturnTo' => '/logged_out.php',
'ReturnStateParam' => 'LogoutState',
'ReturnStateStage' => 'MyLogoutState',
));
?>
Save and close the editor when you are finished.
 
Create a simple logged_out.php like below: 
sudo nano logged_out.php
 
Add below code in it"
<?php

require_once ('/usr/share/simplesamlphp/lib/_autoload.php');

try {
if ($_REQUEST['LogoutState']) {
$state = SimpleSAML_Auth_State::loadState((string)$_REQUEST['LogoutState'], 'MyLogoutState');
}
else {
echo "Were you logged in?";
exit;
}
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
exit;
}
$ls = $state['saml:sp:LogoutStatus']; // Only works for SAML SP
if ($ls['Code'] === 'urn:oasis:names:tc:SAML:2.0:status:Success' && !isset($ls['SubCode'])) {
// Successful logout.
echo("You have been logged out.");
} else {
// Logout failed. Tell the user to close the browser.
echo("We were unable to log you out of all your sessions. To be completely sure that you are logged out, you need to close your web browser.");
}
?>
Save and close the editor when you are finished.
 
Open up web browser, enter https://sp.techsupportpk.com/ in the address bar, you will see your simple index.php page as shown in screenshot below:
 

When you click on Login, you will be taken to your AD FS login page as shown in screenshot below:
 

Once signed-in with valid credentials, you will be redirected to your simple login.php page as shown in screenshot below:
 
 
Click logout to test logout functionality.

Conclusion

Now that you have successfully configured SSO in Apache using SimpleSAMLphp and Active Directory Federation Service, you can start integrating SSO functionality in your applications.

1 comment:

  1. Is it possible to have ADFS fields injected in the request headers automatically, based on who's authenticated on the browser instead of having to provide a username and password?

    ReplyDelete

Powered by Blogger.