ADFS API OTP Provider
OTP authentication for Microsoft Active Directory Federation Service (ADFS). It enables ADFS servers to provide multi-factor authentication (MFA) using a Time-Based One-Time Password (TOTP) Algorithm based on RFC6238. Using this MFA provider, users must enter a one-time passcode to complete a second-factor authentication login process. OTP code is delivered via 3rd party provider’s API Gateway endpoint using HTTP POST. Managed API Gateway service is provided by vendors like Amazon (AWS SNS), Microsoft (Azure API Management) etc.
OTP passcodes for 24 user accounts
OTP codes delivery via 3rd party provider’s API endpoint (Message delivery with: SMS, E-MAIL, Phone etc.)
OTP user accounts deactivation
Authentication against API endpoint
Send API parameters in a message body
API Custom AD attributes in POST message
Logs in Windows Applications Log
ADFS 2016 / ADFS 2019 / ADFS 2022 support
Support of ADFS CSS themes
Licensed version (additional features)
OTP passcodes for unlimited user accounts
OTP data storage in MS SQL service
OTP data storage in MS Active Directory attributes
OTP account lockout
Customization for POST data values when sending into API endpoint
QR code encryption with AES 256-bit encryption
User interface customizations
Free version notes are removed
Deploy SecureMFA API OTP Provider into ADFS Farm
Before you can start registering “SecureMfaApiOtpProvider” into your ADFS farm you must complete bellow steps. All commands must be executed in elevated PowerShell (PS) command prompt.
1) Deploy latest “SecureMfaApiOtpprovider” PowerShell module from Microsoft PSGallery using bellow PS command:
NOTE: As of April 2020, the PowerShell Gallery no longer supports lower than 1.2 TLS protocol. Hence if your servers don’t have GPO changes to reflect this requirement you may need manually to enforce TLS 1.2 for PowerShell session by using bellow command
If your ADFS server doesn’t have access to the Internet you can pull PowerShell module from Windows client which has Internet access using bellow PS command:
As alternative you can download “SecureMFA_API_OTP” nupkg file manually from https://www.powershellgallery.com/ website. Rename nupkg file’s extension into ZIP. Unzip content into a folder “SecureMFA_API_OTP” and place it into PS Modules default location on the server. That will work the same way as pulling package with native windows PS Tools.
2) Within “C:\Program Files\WindowsPowerShell\Modules\SecureMFA_API_OTP ” directory you will find “sql_Create_Database_SecureMfaOTP.txt” Modify FILENAME location to reflect your sql server storage configuration. Open the script in SQL manager and execute it. This will create a new SQL database for “SecureMfaApiOtpProvider”
3) Within “C:\Program Files\WindowsPowerShell\Modules\SecureMFA_API_OTP ” directory update “SecureMfaApiOtpProvider.json” file.
If you are using a free version you only need to modify "sqlserver" server settings and configure your “api_endpoint”. If you will buy a license for unlimited users you will need to update "company" , "serialkey" and "subscriptionid" information to unlock licensed provider features.
If you are not running your ADFS servers using service account and you cannot use SQL integrated security to access database, you need to change: "sqlintegratedsecurity": "false“ and update "sqluseraccount" and "sqluserpassword" with relevant information.
4) If you need to generate verbose logs in windows events for troubleshooting reasons change verboselog value from “false” to “true”. Please note that verbose logging can affect your servers’ performance, use it only for troubleshooting reasons. Don’t enable “verboselog” in production environments as it may reveal configuration secrets
5) Using SQL manager provision dbo access to “SecureMfaOTP” database for ADFS service account or SQL user.
Below is a sample of a SecureMfaApiOtpProvider.json file
Any configuration changes in json configuration file requires Install-SecureMfaApiOtpProvider to be executed again.
SecureMFA API OTP Provider Installation
Before a SecureMfaEmailOtpprovider will be invoked by AD FS, it must be registered in the system. with PowerShell command which performs the necessary installation actions including installation in the GAC, and registration in AD FS farm.
Primary ADFS node
Bellow command will install OTP authentication provider on the MAIN ADFS node.
Other ADFS node(s)
Bellow command will install OTP authentication provider on OTHER ADFS node(s).
NOTE: If you are using federation server farm that uses Windows Internal Database, you must start installation using the primary federation server of the farm as a MAIN node. Installation needs to be executed on ADFS farm server (not web application proxy servers).
To verify if “SecureMFA Email OTP Provider” has been installed successfully.
1) Open the AD FS Management Snap-in (from Server Manager Tools menu)
2) Click Authentication Policies at left
3) In the center pane, under Multi-Factor Authentication, click the blue Edit link to the right of Global Settings.
Under Select additional authentication methods at the bottom of the page, check if “Email Time Based OTP Authentication” is selected.
When user will be prompted for multifactor authentication via ADFS interface, to receive authentication OTP code via API interface user will have to click “Get Authorization Code”
If API endpoint has a valid configuration for the user below information will be presented on successful POST message of OTP code.
If API endpoint was not setup for the user below information will be presented on successful POST message of OTP code. More details will be logged in Windows Application log.
OTP code is delivered via 3rd party provider’s API Gateway endpoint using HTTP POST. Managed API Gateway service is provided by vendors like Amazon (AWS SNS), Microsoft (Azure Api Management) etc. These Services support message deliveries via SMS, E-MAIL, Mobile Notification Network, Phone Call etc.
SecureMFA_API_OTP Provider will post OTP code to API Gateway with extra text which can be customised. Provider will return HTTP Response value for successful POST (HTTP 200) and access denied POST (HTTP 403) messages in UI when sending messages to API endpoint. All other HTTP errors will return HTTP status code value only.
Information is updated in SQL Database or in Microsoft Active Directory attributes after user’s successful logon. What data store will be used depends on authentication mode configuration in MFA provider’s configuration file.
This feature only works for licensed adapters. If you set “login_failures” to be more than a zero in SecureMFA data store you will see failed user authentication attempts. When user reaches “failedlogoncount” number of attempts set in “login_failures” value user’s account will be locked out for a period of time set in "lockout_minutes" . If you want to disable this feature you must set “login_failures” to zero. All values are configured in SecureMfaApiOtpProvider.json file.
SecureMfaApiOtpProvider.json config settings to enable 5 min lockouts for 15 failed OTP passcode attemps :
This feature allows to disable SecureMFA OTP account and immedicably restrict MFA authentication without disabling user in Active Directory.
User will be getting following message If user’s SecureMFA OTP account has been disabled by support team.
How to disable SecureMFA OTP accounts please read “SecureMFA Support Tools” documentation.
Support tools are packaged into a separate PowerShell module which is used for OTP support and maintenance tasks.
Encryption only works for licensed adapters. AES 256-bit encryption is configured with the .NET wrapper side by using public sealed class AesCng: System.Security.Cryptography.Aes. It provides a Cryptography Next Generation (CNG) implementation of the Advanced Encryption Standard (AES) algorithm and allows to run provider when FIPS compliant algorithms for encryption are enforced on the Windows platform. The cipher mode is Cipher Block Chaining (CBC). The passphrase can be configured in the configuration file and it is recommended to be between 16-18 random characters. It is salted with 16 bytes string, zero padding and 4 key iterations. Full documentation on “AesCng .NET class” can be found in Microsoft documentation (https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aescng)
SecureMfaApiOtpProvider.json config settings to enable encryption:
When it is enabled your secret code is encrypted in Database and it looks like bellow.
Licensed clients can customize adapter text which is presented to the users during logon. You can use some simple html code like links to provide users with self-service portal links etc. Text customizations are configured in “SecureMfaApiOtpProvider.json” file.
NOTE: "ui_customization" must be set to "true" for bellow changes to take effect.
"ui_login_text": "Enter the passcode generated by your authenticator
All successful second factor authentication sessions will issue a new Actual Authentication method value: http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
Enable OTP Data Store in Microsoft Active Directory Attributes
This feature is only available for licensed OTP providers. It allows to store User OTP attributes in Active Directory domain. This removes dependency and cost of having MS SQL service configuration to store OTP database. To enable this feature, you have to update SecureMfaApiOtpProvider.json file to enable AD mode and update encryption passphrase with your custom string which will be used to encrypt secret data in AD attribute. AD mode doesn’t support unencrypted secrets.
You will have to execute following script “Create_SecureMFA_API_OTP _AD_attributes.ps1” which comes with OTP provider on Read-Write domain controller. You need to execute this script on Read-Write domain controller with AD account which is member of Schema Admins group. SecureMFA OTP provider when operates in AD mode it requires custom Active Directory (AD) attributes to be created to store OTP data for the user. This action cannot be undone and needs to be tested in your TEST domain first before moving into PRODUCTION. New AD Schema Attributes will be added into custom SecureMFA Auxiliary Class and that Class will be added into Existing User Class as AD Schema best practices suggest. OID numbers for custom attributes are from SecureMFA Private Enterprise range assigned by iana.org . Which do not overlap with other vendors OIDs numbers used to create custom AD attributes.
Note: THIS ONLY REQUIRES IF YOU PLAN TO RUN SecureMFA API OTP Provider in AD MODE. By default, write access to a new Active Directory attributes is allowed only for domain administrators. If you run ADFS under dedicated service account please make sure it has WRITE access to “sMFA-* user attributes”, in order for the provider to be able to update Active Directory user info.
Bellow print screen shows how AD user’s custom attributes will look like.
Following are AWS CLI bash commands to setup API Gateway interface.
1. Create SNS topic.
2. Verify ARN value for SNS topic
3. Create the subscription, substituting your own SMS device or email address in the SUBSCRIPTION_ENDPOINT variable. Make sure you include the country code in your number. You may need to confirm your subscription by clicking a link which you will receive from AWS Notification service if it is email endpoint.
4. Verify if subscription is active
5. Confirm that your subscription is configured correctly by publishing a message to your SNS topic. You should receive a text on your mobile device or email.
Now that we have an SNS topic with a subscription that sends to our endpoint device, next step is to set up API Gateway with a service proxy.
6. Create a REST API in API Gateway
7. Fetch your resources from API Gateway
8. Store the value of that resource id into a ROOT_RESOURCE_ID variable
9. create API /ingest resource. This resource should be created for each user which will use SecureMFA API OTP provider to authenticate.
10. See that there are two resources in our REST API now. Each extra user will need a new resource there.
11. Wire up a method for our resource. We want clients to send us data to be ingested into our topic, so we’ll use a POST method. Each extra user will need this config.
Now created the basic elements of our API Gateway REST API, in addition to the SNS topic and subscription we created in the previous section. Next, connect our two pieces by creating a service proxy integration. Creation of role is one time configuration.
12. Create the role with the proper trust policy
13. Update the inline policy on the role. With an IAM role, you grant it permission to perform certain actions. In this instance, we want to grant it permission to publish messages to our SNS topic. Resource value should include multiple values if you will have multiple user subscriptions.
14. Verify all resources assigned to gservice-proxy-role
15. Create the integration between our HTTP endpoint and our AWS service
16. Add your integration response
17. Add a method response. This is how API Gateway takes the integration response and assembles it into an HTTP-compatible response
18. Before API can be used, deploy it.
19. Use curl for invoking API endpoint to test functionallity.
If message is received via API Gateway using curl command, you can use it with SecureMFA-API-OTP Provider. Please see for more details in ‘Enable API Endpoint’ section.
Enable API Endpoint
Endpoint for posting OTP codes into API Gateway is specified under "api_endpoint" value. NOTE, API endpoint is accessed by ADFS Servers (not web application proxy servers). Most likely ADFS servers will need to access API endpoint via corporate proxy if it is outside corporate network. To allow access via proxy server ensure "proxy_enable" is set to "true". Otherwise you’ll have to set system settings for default proxy settings.
Below is a sample of json configuration file which will work with Amazon AWS API Gateway service It has time out value (ms) to terminate TCP sessions which take long time to complete and code text value which is extra text added to POST message into API gateway:
Complete URI for API endpoint will be created by combining "api_endpoint" and user’s anchor value from ADFS to make it unique. User’s anchor value will be captured before “@” value and all special characters will be removed including “.” or “_”. Text is converted into lowercases. For example, user’s account with UPN “Test1.Test1@adatum.labnet” will be converted into “test1test1” value.
API Gateway must be configured by following a RESTful API design, the combination of resource + method which allows to expose POST actions on a user’s object. For example, making a POST request to /prod/test1test1 should trigger delivery of message which is received in a POST payload.
Below is a sample how properly formatted URI will look like:
Please see Configure “AWS API Gateway for SMS or EMAIL deliveries” section to get more details how to setup test API Gateway.
Provider support “Custom Header” authentication to authenticate against API endpoint.
Below is a sample of json configuration file which enables “Custom Header” authentication against endpoint. It includes custom header key and value combination to be included with POST message.
API endpoint is accessed by ADFS Servers (not web application proxy servers). Most likely ADFS servers will need to access API endpoint via corporate proxy if it is outside corporate network. Proxy authentication is done under ADFS service account.
SecureMfaApiOtpProvider.json config settings to enable proxy:
As alternative you can configure system settings to enforce server to send messages via corporate proxy.
Send API parameters in a message body
Provider allows to send all parameters and data for API endpoint in POST message by changing bellow setting in JSON configuration file
Data for API endpoint will be included in a message body using JSON format and it will include following information:
You can test this functionality by using API Endpoint in Self-service password reset portal (SSPR) or you can use it with your own API solution which accepts JSON formatted messages.
API Custom AD attributes
For customised integrations API provider allows to include custom AD attributes in POST message body when using
"api_allparams_inbody": "true" setting in JSON config file. To include custom AD attributes SecureMfaApiOtpProvider.json must be enabled as below:
Note: Key value in POST message will be value after “api_customparams_” and AD user attribute value can be any user object attribute name in AD which is accessible to ADFS service account.
To see data that is sent in POST message you can enable verbose logging in the provider’s JSON configuration file. POST message details will be published in the Windows Applications Log file.
POST Message Data Values
This feature is only available for licensed OTP providers. You can add your custom information with POST message for API endpoint. Bellow JSON configuration setting allows to send extra information with POST data to API endpoint.
TOTP Time Drift
This feature is only available for licensed OTP providers. By default OTP time drift is allowed to be 30 seconds in the future and in the past as defined in RFC6238 , this makes provider to be compatible with other providers (SecureMfaOtp ) which allow to use QR apps on mobile device to generate OTP tokens. If your delivery method cannot deliver OTP message within default timeframe you can increase OTP validity value by adding extra seconds, but this will break compatibility with other authentication providers indicated above.
SecureMfaApiOtpProvider.json config settings to enable 60 seconds time drift:
Note: By default, the authorization code can be used only once. Suppose you want to reuse the authorization code multiple times during the timeframe update below the config file setting.
The below system events in Windows Event log may be used to verify and troubleshoot SecureMfa API OTP Provider:
Log Name: AD FS/Admin
All provider related logs are stored in Windows Application Event logs and some data in SQL table or AD Attributes.
Windows Application Event:
Source: Secure MFA API OTP
Deployment of a new version can be done by pulling latest version from PowerShell Gallery by using bellow command:
You’ll need to repeating all deployment steps as it was done for original installation. If it is highlighted in deployment notes that attribute store needs to be extended for OTP data, you’ll need extra step to complete your upgrade.
· If you are using to store your user OTP data in MS SQL you may need to execute “sql_Upgrade_From_Previous_Version.txt” on your SQL database.
· If you are using to store your user OTP data in AD you may need to execute “Create_SecureMFA_API_OTP _AD_attributes.ps1” on your Domain controller.
Files can be found in a directory with other SecureMFA Provider files. This will add any extra missing columns/attributes in the Database or AD.
OTP Users Management
Support tools for OTP Users management are packaged into a separate PowerShell module which can be used for OTP accounts management tasks.
For more details please read “SecureMFA Support Tools” documentation.
Configure AWS API Gateway for SMS or EMAIL deliveries
Bellow Amazon Web Services configuration shows how to setup API Gateway which allows to deliver OTP codes from SecureMFA API Provider using SMS or EMAIL. You’ll need admin access to AWS account and bash console for AWS CLI commands to complete configuration. You must use API provider setting "api_allparams_inbody": "false" in JSON config file for bellow exsample to work. Working deployment OTP messaging flow will look like bellow