The goal of this guide is to be able to authenticate users by Active Directory (AD) credentials using Kerberos SPNEGO mechanism. If a SPNEGO token is not available, offer a secondary two factor (2FA) authentication mechanism. The SimpleSAMLphp module Negotiate offer the Simple And Protected Negotiate (SPNEGO) mechanism. The SPNEGO token is a Kerberos service ticket encoded in a platform independent manner ASN.1 DER format.
From the Negotiate module documentation:
"In effect this module aims to extend the Microsoft AD SSO session to the SAML IdP. (Or any other Kerberos domain) It doesn't work like this of course but for the user the client is automatically authenticated when an SP sends the client to the IdP. In reality Negotiate authenticates the user via SPNEGO and issues a separate SAML session. The Kerberos session against the Authentication Server is completely separate from the SAML session with the IdP"
The module will be used to authenticate a user by the HTTP-Based Cross-Platform Negotiate Protocol. When the browser is redirected from the SP to the IdP single sign on end point the IdP responds with a HTTP 401 challenge header. The users AD credentials is used to request a valid Kerberos service ticket from the KDC. The ticket is encoded into a SPNEGO token and transferd to the IdP.
If the browser aren't configured correctly or the Kerberos ticket is missing. It is up to the browser to solve this. Some browser will prompt the user for a user-name and a password (NTLM) and not proceed until the users have entered the credentials. This is not what we want. If the browser are unable to supply a valid kerberos ticket the IdP should display the 2FA page.
The SimpleSAMLphp Radius module are used as the secondary authentication mechanism for 2FA. How to setup the radius server is out of scope and will not be explained in this guide.
The SimpleSAMLphp default login page must be extended with the JavaScript and AJAX code. By defining a theme in a module the module can override the default login page. The default loginuserpass.php is included in the theme but are altered to run the negocheck code.
The login flow must be able to check if the browser is able to respond to a 401 challenge header. AJAX send requests asynchronously in the background. Utilizing AJAX to separate the process of checking for a SPNEGO token from the presentation layer, it is possible to load the 2FA page but hiddend and with JavaScript execute the AJAX request. If the AJAX request do not return or return SPNEGO not available the 2FA page are already loaded and will be displayed.
Install PHP extensions to be able to supprt Radius and Kerberos Negotiate authentication
sudo apt-get install php5-dev libkrb5-dev php-pear
sudo pecl install krb5
sudo pecl install radius
echo "extension=krb5.so" | tee /etc/php5/mods-available/krb5.ini
echo "extension=radius.so" | tee /etc/php5/mods-available/radius.ini
cd /etc/php5/apache2/conf.d/
ln -s ../../mods-available/krb5.ini 20-krb5.ini
ln -s ../../mods-available/radius.ini 20-radius.ini
Add the rewrite rules to the Apache simpleSAMLphp configuration. Alias /simplesaml "/var/simplesamlphp/www" <Directory "/var/simplesamlphp/www"> RewriteEngine on RewriteCond %\{HTTP:Authorization\} !^$ RewriteRule .* - \[E=HTTP_AUTHORIZATION:%\{HTTP:Authorization\},L\] Require all granted </Directory> Enable the rewrite module and restart Apache. sudo a2enmod rewrite sudo service apache2 restart |
This task is performed on the AD domain controller.
Create a user account in the Active Directory
Use ADSI Edit to locate the user account
Right-click the user account object, and then click Properties
Click the Attribute Editor tab
Click filter and ensure that Constructed is selected
Locate msDS-KeyVersionNumber in the Attributes list.
ktpass -princ HTTP/mysimplesamlphpserver.example.com@MYADDOMAIN -mapuser DOMAIN_NETBIOS\username -pass mypassword -out krb5.keytab /crypto RC4-HMAC-NT /kvno msDS-KeyVersionNumber_from_previus_step -ptype KRB5_NT_SRV_HST
Move the ketab file krb5.keytab to the directory /var/simplesamlphp/config on the SimpleSAMLphp host.
Set permissions
cd /var/simplesamlphp
chown root:www-data config/krb5.keytab
chmod 440 config/krb5.keytab
Enable the module cd /var/simplesamlphp touch modules/radius/enable Change the parameters to match the intended environment then add the configuration to config/authsource.php '2FA' => array( 'radius:Radius', 'servers' => array( array( 'hostname' => 'radius.example.com', 'port' => 18121, 'secret' => 'verysecuresecret', ), ), 'username_attribute' => 'sAMAccountName', ), Get the attributes from the AD using the LDAP module. touch modules/ldap/enable Change the parameters to match the intended environment then add the configuration to metadata/saml20-idp-hosted.php. /* UID */ 'userid.attribute' => 'uid', \\ /* Fix attributes */ 'AttributeNameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', \\ /* Additional IDP-specific authentication processing filters */ 'authproc' => array( 100 => array( 'class' => 'core:AttributeAlter', 'subject' => 'sAMAccountName', 'pattern' => '/(\[^@\]+)/', '%replace', 'target' => 'uid', ), 110 => array( 'class' => 'ldap:AttributeAddFromLDAP', 'attributes' => array('mail','displayName'), 'attribute.policy' => 'merge', 'search.filter' => '(sAMAccountName=%uid%)', 'ldap.basedn' => 'ou=All Users,dc=office,dc=nic,dc=se', 'ldap.hostname' => 'ldaps://2k8r2dc1.office.nic.se ldaps://2k8r2dc2.office.nic.se ldaps://2k8r2dc3.office.nic.se', 'ldap.username' => 'CN=2fa,OU=Service Accounts,dc=office,dc=nic,dc=se', 'ldap.password' => '1sNNG2Tf-elhdLW', 'ldap.product' => 'ActiveDirectory', 'ldap.timeout' => 2, 'ldap.debug' => FALSE, ), ), \\ /* |