FIDO/GLUU Identity Provider
This guide describes how to implement a NIEF SAML Identity Provider (IDP) system that authenticates with Fast IDentity Online (FIDO) credentials held on a personal mobile device.
FIDO is a standard for performing multi-factor authentication of users by verifying proof of possession of a smart phone, along with requiring the user to authenticate to the smart phone with a biometric. This FIDO/Gluu Implementation Guide provides details on how to deploy a NIEF SAML IDP using the Gluu Server along with the ThumbSignIn online FIDO service. The Gluu Server only runs on the Linux operating system (it can be run within a virtual machine or docker container).
This guide is designed around the use of commercial software that has free versions that are sufficient for small and simple deploys:
The Gluu Server runs on various versions of Linux, details of all supported versions can be found within the Gluu Installation Guide. For this guide, we will assume the use of CentOS 7 as it is free and the version of Linux the NIEF team knows best.
- Prior to installing Gluu update the CentOS selinux settings to permissive within the /etc/selinux/config file.
- There are additional preparatory steps listed within the Gluu Installation Guide that may be required depending on your virtual hosting platform/service and/or version of Linux.
It may be easier to follow the detailed Gluu Installation Guide, but the quick version of the install steps are included here. Each of these commands should be executed from a root login on the Linux machine to add/trust the Gluu repository and then install the Gluu Server RPM:
# wget https://repo.gluu.org/centos/Gluu-centos7.repo -O /etc/yum.repos.d/Gluu.repo # wget https://repo.gluu.org/centos/RPM-GPG-KEY-GLUU -O /etc/pki/rpm-gpg/RPM-GPG-KEY-GLUU # rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-GLUU # yum clean all # yum install gluu-server-3.1.5
Updating Linux Startup
Next you need to update the Linux server to start the Gluu service on boot:
# /sbin/gluu-serverd-3.1.5 enable # /sbin/gluu-serverd-3.1.5 start
Initial Gluu Setup
Finally, you need to login to the Gluu container and configure it for initial use:
# /sbin/gluu-serverd-3.1.5 login # cd /install/community-edition-setup # ./setup.py
This setup script will prompt for a variety of things, most of these should be obvious how to populate or can be left as the default settings. There are three we call out as important:
- Password for oxTrust and LDAP superuser - This password is important for further configuration of the system, be sure to set it to something you can remember and/or use in your password manager.
- Install Apache HTTPD Server - If your Linux deploy already has a working Apache httpd install, you may wish to forgo this and use your configuration of Apache HTTPD. If you prefer to use the Gluu version, you may need to disable the Apache Httpd you have installed.
- Install Shibboleth SAML IDP - This defaults to false, but it is required for our purposes.
At the end of this install you will be redirected to use a browser to point to the configuration GUI for Gluu. If that URL works, you should see a login page that looks like this:
You will want to login as admin with the password specified during the setup step (Password for oxTrust and LDAP superuser) specified earlier. If the login fails, you may need to reboot your system, as some of the required services may not have started on install.
Install ThumbSign SDK
To be able to use ThumbSignIn, you will need to have a copy of their Java SDK configured within ThumbSignIn. You can download it from here, and you must install it in opt/gluu/jetty/oxauth/lib/ext
Create ThumbSignIn Account
Install ThumbSignIn App
Initially you will need to install the ThumbSignIn App from the Google Play Store or the Apple App Store. Searching for ThumbSignIn should show the app, it is published by Pramati.
Create ThumbSignIn Account
You can regsiter a new ThumbSignIn account on the register page: https://app.thumbsignin.com/signup. You will need to provide an email address which will be associated with the account and used for account recovery. Account creation proceeds using the ThumbSignIn mobile app.
There are only two critical data items required from the ThumbSignIn portal, you can get them by using the links to automatically copy them to the clipboard during later Gluu configuration steps:
To use the Gluu configuration UI you will need to login to oxAuth. You should be able to do this by following the link provided during install. Once you have logged into Gluu as a superuser, you should see a configuration UI that looks like the following:
Configuring ThumbSignIn Plugin
Find the ThumbSignIn Plugin in the menu under configuration -> manage custom scripts as seen here:
Within this script you will need to populate three fields:
You will need to populate these three fields:
- ts_host - https://api.thumbsignin.com
- ts_apiKey is the Application ID from the ThumbSignIn Portal
- ts_apiSecret is the Secret Key from the ThumbSignIn Portal
You must enable the the plugin by clicking the checkbox at the bottom of the ThumbSignIn expanded script:
Finally, you have to click Update to load the plugin:
Updating Session Timeouts
Do to the use of the external ThumbSignIn service for authentication you need to also update some session timeouts within Gluu to accomodate this authentication method. Go to JSON Configuration -> oxAuth Configuration and set the sessionIDUnauthenticatedUnusedLifetime parameter to 240 seconds. It is pretty far down the page and it's best to search for the string sessionIDUnauthenticatedUnusedLifetime to find the setting:
The very next setting above sessionIdLifetime may also need to be updated if the IDP wishes to terminate the session when the browser session ends. To do this change the sessionIdLifetime to 0 or -1.
For more sophisticated user registration customized for your organization and deploy, please review the capabilities available within Gluu's SCIM 2.0 APIs. For very simple user registration useful for a demonstration deploy you can enable basic user registration.
A quick synopsis for basic user registration is included here. Navigate to the user registration custom script:
If you want to mimic the behavior of the existing NIEF demonstration at https://fido.nief.org, you will also want to update the script value for enable_user to true so that an administrator does not need to enable each user registered. For production deploys this value would likely remain false if this user registration script is used. Click the enable checkbox and click update to enable user registration:
You can now access this user registration page at
Configuring SAML Trusted Partners
Within Gluu to configure a trusted partner navigate to SAML -> Add Trust Relationships:
If you want to add trust to the entire NIEF Testbed, you can do so by populating it as follows:
|Display Name||NIEF Testbed|
|Description||For engaging in interoperability testing with NIEF.|
|Sp Metadata URL||https://ref.gfipm.net/gfipm-signed-ref-metadata.xml|
Configuring SAML Attributes
GLUU has it's own internal attribute dictionary and tracking capabilities centered around LDAP. If you are sourcing SAML attributes from other sources, one can update the underlying Shibboleth attribute configuration directly. Typically for GLUU's Shibboleth install you want to update their configuration template files located at /opt/gluu-server-3.1.5/opt/gluu/jetty/identity/conf/shibboleth3/idp.
Sourcing Attributes from SQL Server
As an example if the attribute source is coming from an SQL Server, you would need to add an appropriate JDBC driver to Shibboleth. It appears that this one from Microsoft is the most appropriate: SQL Server JDBC Driver.
The jar file downloaded will likely need to be added to the idp.war file found at /opt/gluu-server-3.1.5/opt/gluu/jetty/idp/webapps/idp.war.
The Shibboleth Dataconnector configuration should look something like the following:
<resolver:DataConnector id="myDB" xsi:type="dc:RelationalDatabase"> <dc:ApplicationManagedConnection jdbcDriver="com.microsoft.sqlserver.jdbc.SQLServerDriver" jdbcURL="jdbc:mysql://localhost:3306/userdb" jdbcUserName="shib" jdbcPassword="shibpw" /> <dc:QueryTemplate> <![CDATA[ select us.username, organization.name, MAX(case when user_attribute_value.attribute_ref = 'EmailAddressText' THEN user_attribute_value.attribute_value END) email, MAX(case when user_attribute_value.attribute_ref = 'SurName' THEN user_attribute_value.attribute_value END) lastname, MAX(case when user_attribute_value.attribute_ref = 'GivenName' THEN user_attribute_value.attribute_value END) firstname, MAX(case when user_attribute_value.attribute_ref = 'TelephoneNumber' THEN user_attribute_value.attribute_value END) phone, MAX(case when user_attribute_value.attribute_ref = '28CFRCertificationIndicator' THEN user_attribute_value.attribute_value END) cert28, MAX(case when user_attribute_value.attribute_ref = 'SwornLawEnforcementOfficerIndicator' THEN user_attribute_value.attribute_value END) sleo, MAX(case when user_attribute_value.attribute_ref = 'PublicSafetyOfficerIndicator' THEN user_attribute_value.attribute_value END) pso, MAX(case when user_attribute_value.attribute_ref = 'BackgroundCheckStatus' THEN user_attribute_value.attribute_value END) background, MAX(case when user_attribute_value.attribute_ref = 'DriversLicenseCheckStatus' THEN user_attribute_value.attribute_value END) dl, MAX(case when user_attribute_value.attribute_ref = 'DEARegistrationNumber' THEN user_attribute_value.attribute_value END) deanum, MAX(case when user_attribute_value.attribute_ref = 'HIPAAPrivacyRuleTrainingIndicator' THEN user_attribute_value.attribute_value END) hipaa, MAX(case when user_attribute_value.attribute_ref = 'DrugTestStatus' THEN user_attribute_value.attribute_value END) drug, MAX(case when user_attribute_value.attribute_ref = 'HealthProviderUserRole' THEN user_attribute_value.attribute_value END) role, MAX(case when organization_attribute_value.attribute_ref = 'EmployerOrganizationGeneralCategoryCode' THEN organization_attribute_value.attribute_value END) orgcat, MAX(case when organization_attribute_value.attribute_ref = 'EmployerORI' THEN organization_attribute_value.attribute_value END) ori from registered_user us left join (user_attribute_value, organization, organization_user, organization_attribute_value) on (us.id = user_attribute_value.user_ref AND us.id = organization_user.use_ref AND organization_user.organization_ref = organization.id AND organization_attribute_value.organization_ref = organization.id) where us.username = '$requestContext.principalName' ]]> </dc:QueryTemplate> <dc:Column columnName="email" attributeID="email" /> <dc:Column columnName="lastname" attributeID="lastname" /> <dc:Column columnName="firstname" attributeID="firstname" /> <dc:Column columnName="name" attributeID="orgname" /> <dc:Column columnName="orgcat" attributeID="orgcat" /> <dc:Column columnName="ori" attributeID="ori" /> <dc:Column columnName="phone" attributeID="phone" /> <dc:Column columnName="cert28" attributeID="cert28" /> <dc:Column columnName="sleo" attributeID="sleo" /> <dc:Column columnName="pso" attributeID="pso" /> <dc:Column columnName="background" attributeID="background" /> <dc:Column columnName="dl" attributeID="dl" /> </resolver:DataConnector>
It is always a good idea to test and validate a new IDP deployment within a test environment. The NIEF Testbed is intended for exactly this purpose.