Skip to content

Configuring Email OTP

This section provides the instructions to configure multi-factor authentication (MFA) using Email One Time Password (Email OTP) in WSO2 Identity Server (WSO2 IS). The Email OTP enables a one-time password (OTP) to be used at the second step of MFA.

Info

For information on MFA concepts, see About MFA.

Follow the instructions in the sections below to configure MFA using Email OTP:

Deploying travelocity sample application

In this guide we will be using travelocity.com as a sample application to which we will be enabling MFA for sign-in. To deploy the travelocity sample application, follow the steps in Deploying the travelocity.com Sample App.


Configure the email OTP provider

You can use WSO2 Identity Server as the email OTP provider or you can configure Gmail or SendGrid as the email OTP provider using Gmail or SendGrid APIs. Follow the instructions in one of Option1 or Option2 to set up the email OTP provider.

Option1: Configure WSO2 IS as the email OTP provider

Expand this section to follow the steps to configure WSO2 IS to send emails once the Email OTP is enabled.
  1. Enable the email sending configurations of the WSO2 Identity Server as explained here.

Tip

The email template used to send this email notification is the EmailOTP template.

You can edit and customize the email template. For more information on how to do this, see Customizing Automated Emails.

  1. Add the following configuration to the deployment.toml file in the <IS_HOME>/repository/conf/ directory.

    [authentication.authenticator.email_otp]
    name ="EmailOTP"
    enable=true
    [authentication.authenticator.email_otp.parameters]
    EMAILOTPAuthenticationEndpointURL = "https://localhost:9443/emailotpauthenticationendpoint/emailotp.jsp"
    EmailOTPAuthenticationEndpointErrorPage = "https://localhost:9443/emailotpauthenticationendpoint/emailotpError.jsp"
    EmailAddressRequestPage = "https://localhost:9443/emailotpauthenticationendpoint/emailAddress.jsp"
    usecase = "local"
    secondaryUserstore = "primary"
    EMAILOTPMandatory = false
    sendOTPToFederatedEmailAttribute = false
    federatedEmailAttributeKey = "email"
    EmailOTPEnableByUserClaim = true
    CaptureAndUpdateEmailAddress = true
    showEmailAddressInUI = true
    useEventHandlerBasedEmailSender = true
    emailAddressRegex = '(?&lt;=.{1}).(?=.*@)'
    tokenExpirationTime = 300000
    Click to view the parameter definitions

    Parameter Description Sample Values
    usecase This parameter defines how the email ID will be retrieved.
    • local: This is the default value and is based on the federated username. You must set the federated username in the local userstore . The federated username must be the same as the local username.
    • assocication: The federated username must be associated with the local account in advance in the user portal. The local username is retrieved from the association. To associate the user, log into the user portal and go to Associated Account by clicking View details.
    • subjectUri: When configuring the federated authenticator, select the attribute in the subject identifier under the service provider section in UI, this is used as the username of the EmailOTP authenticator.
    • userAttribute : The name of the federated authenticator's user attribute. That is the local username that is contained in a federated user's attribute. When using this, add the following parameter under the [authentication.authenticator.email_otp.parameters] section in the deployment.toml file and put the value, e.g., email and screen_name, id.

      [authentication.authenticator.email_otp.parameters]
      userAttribute = "email"

      If you use OpenID Connect supported authenticators such as LinkedIn and Foursquare or in the case of multiple social login options as the first step and EmailOTP as second step, you need to add similar configuration for the specific authenticator in the deployment.toml file.

      Click here to view examples

      Facebook

      [authentication.authenticator.facebook.parameters]
      EmailOTP-userAttribute = "email"
      federatedEmailAttributeKey = "email"

      Foursquare

      [[authentication.custom_authenticator]]
      name= "Foursquare"
      [authentication.custom_authenticator.parameters]
      EmailOTP-userAttribute = "http://wso2.org/foursquare/claims/email"
      federatedEmailAttributeKey = "http://wso2.org/foursquare/claims/email"
      Likewise, you can add the Authenticator Config for Amazon, Google, Twitter, and Instagram with the relevant values.


    • local
    • association
    • userAttribute
    • subjectUri
    secondaryUserstore

    You can define multiple user stores per tenant as comma separated values.

    Example:

    secondaryUserstore = "jdbc, abc, xyz"
    Tip

    The user store configurations are maintained per tenant:

    • If you use a super tenant, set all the parameter values into the /repository/conf/deployment.toml file.
    • If you use a tenant,
      • Upload the XML file (/repository/conf/identity/application-authentication.xml) into a specific registry location (/_system/governance/EmailOTP).
      • Create the collection named EmailOTP, add the resource and upload the application-authentication.xml file into the registry.
      • While doing the authentication,the sysetm first checks whether there is an XML file uploaded to the registry. If that is so, it reads it from the registry but does not take the local file. If there is no file in the registry, then it only takes the property values from the local file.
      • You can use the registry or local file to get the property values.
    EMAILOTPMandatory

    Thisparmeterdefineswhtherthe EmailOTP is enforced as the second step of the 2FA/MFA or not.

    • If the user is not found in the active directory where the parameter is set to true, the OTP is directly sent to the email address defined in the claims set.
    • If the user is not found in the active directory where the parameter is set to false, the authentication flow terminates at the first step of the 2FA/MFA.
    • true
    • false
    sendOTPToFederatedEmailAttribute

    When the EMAILOTPMandatory and this parameter are set to true and the user is not found in the active directory, the OTPissetn to the mail defined in the federated authenticator claim.

    When the EMAILOTPMandatory is set to false, an error page gets displayed.

    When the EMAILOTPMandatory is set to false and the user is not found in the active directory, the authentication mechanism terminates at the first step of the 2FA/MFA. This parameter is not required in such a scenario.

    • true
    • false
    federatedEmailAttributeKey This parameter identifies the email attribute of the federated authenticator,
    e.g. Foursquare. Set this parameter if the sendOTPToFederatedEmailAttribute is set to true. Example: http://wso2.org/foursquare/claims/email
    EmailOTPEnableByUserClaim

    This parameter enables the user to override the functionality defined at the EMAILOTPMandatory parameter.

    • If this parameter and the EMAILOTPMandatory parameters are set to true, the user can either enable or disable the EmailOTP functionality.
    • If this parameter is set to false where the EMAILOTPMandatory parameter is set to true, the user gets redirected to an error page.
    • If this parameter and the EMAILOTPMandatory parameters are set to false, the authentication flow terminates at the first step of the 2FA/MFA.
    • If the user is not available in the active directory
    • true
    • false
    CaptureAndUpdateEmailAddress This parameter enables the user to update the email address that is used to send the OTP, at the first login where the email address is not previously set.
    • true
    • false
    EmailAddressRequestPage

    This parameter enables to display a page that requests for an email address where

    • The user has not registered an email address.
    • Sending OTP is defined as the second step of 2FA/MFA.
    • The CaptureAndUpdateEmailAddress parameter is set to true.

    Example: https://localhost:9443/emailotpauthenticationendpoint/emailAddress.jsp

    showEmailAddressInUI This parameter enables to display the email address to which the OTP is sent to on the UI.
    • true
    • false
    emailAddressRegex When showEmailAddressInUI is enabled, it provides the capability to define the way the email address should be displayed in the UI. This can be configured with a proper regex pattern as required.
    • (?<=.{1}).(?=.@)  :  t***@mail.com
    • (?<=.)^@|(?:(?<=@.)|(?!)\G(?=[@]$)).(?=.*\.)  :  t***@m***.com
    tokenExpirationTime This parameter helps to define a custom Email OTP expiry time. The default expiration time is 300000 milliseconds.
    • 300000

  2. Start WSO2 IS.

Option2: Configure Gmail as the email OTP provider

Expand this section to send the One Time Password (OTP) using Gmail APIs or using SendGrid.

Follow the steps given below to configure Gmail APIs as the mechanism to send the OTP.

  1. Create a Google account at https://gmail.com.
  2. Go to https://console.developers.google.com and click ENABLE APIS AND SERVICES.
  3. Search for Gmail API and click on it.
  4. Click Enable to enable the Gmail APIs.

    Why is this needed?

    If you do not enable the Gmail APIs, you will run into a 401 error when trying out step13.

  5. Click Credentials and click Create to create a new project.

  6. Click Credentials and click the Create credentials drop-down.

  7. Select OAuth client ID option.

    oauth-client-id

  8. Click Configure consent screen.
    configure-consent-screen

  9. Enter the Product name that needs to be shown to users, enter values to any other fields you prefer to update, and click Save.

  10. Select the Web application option.
    Enter https://localhost:9443/commonauth as the Authorize redirect URIs text-box, and click Create.

    authorize-redirect-uris

    The client ID and the client secret are displayed.
    Copy the client ID and secret and keep it in a safe place as you require it for the next step.
    client-id-client-secret

  11. Copy the URL below and replace the <ENTER_CLIENT_ID> tag with the generated Client ID . This is required to generate the authorization code.

    Format

    https://accounts.google.com/o/oauth2/auth?redirect_uri=https%3A%2F%2Flocalhost%3A9443%2Fcommonauth&response_type=code&client_id=<ENTER_CLIENT_ID>&scope=http%3A%2F%2Fmail.google.com&approval_prompt=force&access_type=offline

    Example

    https://accounts.google.com/o/oauth2/auth?redirect_uri=https%3A%2F%2Flocalhost%3A9443%2Fcommonauth&response_type=code&client_id=854665841399-l13g81ri4q98elpen1i1uhsdjulhp7ha.apps.googleusercontent.com&scope=http%3A%2F%2Fmail.google.com&approval_prompt=force&access_type=offline

  12. Paste the updated URL into your browser.

    1. Select the preferred Gmail account with which you wish to proceed.

    2. Click Allow.

    3. Obtain the authorization code using a SAML tracer on your browser.

      authorization-code

  13. To generate the access token, copy the following cURL command and replace the following place holders:

    1. <CLIENT-ID> : Replace this with the client ID obtained in Step 10 above.
    2. <CLIENT_SECRET> : Replace this with the client secret obtained in Step 10 above.
    3. <AUTHORIZATION_CODE> : Replace this with the authorization code obtained in Step 12 above.

    Format

    curl -v -X POST --basic -u <CLIENT-ID>:<CLIENT_SECRET> -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -k -d "grant_type=authorization_code&code=<AUTHORIZATION_CODE>&redirect_uri=https://localhost:9443/commonauth" https://www.googleapis.com/oauth2/v3/token

    Example

    curl -v -X POST --basic -u 854665841399-l13g81ri4q98elpen1i1uhsdjulhp7ha.apps.googleusercontent.com:MK3h4fhSUT-aCTtSquMB3Vll -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -k -d "grant_type=authorization_code&code=4/KEDlA2KjGtib4KlyzaKzVNuDfvAmFZ10T82usT-6llY#&redirect_uri=https://localhost:9443/commonauth" https://www.googleapis.com/oauth2/v3/token

    Sample Response

    > POST /oauth2/v3/token HTTP/1.1
    > Host: www.googleapis.com
    > Authorization: Basic OTk3NDE2ODczOTUwLWY4Y2N1YnJobW1ramdkYXNkNnZkZ2tzOGxoaWExcnRhLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tOkJkNlBoY3ZVWXFrM1BhdnA4ZjBZcUQtMw==
    > User-Agent: curl/7.54.0
    > Accept: */*
    > Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    > Content-Length: 127
    > 
    < HTTP/1.1 200 OK
    < Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    < Pragma: no-cache
    < Expires: Mon, 01 Jan 1990 00:00:00 GMT
    < Date: Wed, 10 Jan 2018 08:29:57 GMT
    < Vary: X-Origin
    < Content-Type: application/json; charset=UTF-8
    < X-Content-Type-Options: nosniff
    < X-Frame-Options: SAMEORIGIN
    < X-XSS-Protection: 1; mode=block
    < Server: GSE
    < Alt-Svc: hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303338; quic=51303337; quic=51303335,quic=":443"; ma=2592000; v="41,39,38,37,35"
    < Accept-Ranges: none
    < Vary: Origin,Accept-Encoding
    < Transfer-Encoding: chunked
    < 
    {
     "access_token": "ya29.Gls-BbTUseE2f-Lrc9q0QtdlvIoYFTg2zkYPsXHwgob4pHAFlE66GMgJjwTHT9eHfivhVcATROzU8FaUgt0wVL1sz-7IsC2Slfpdm6i3uFcurNTFbTlABk3jKJ--",
     "token_type": "Bearer",
     "expires_in": 3600,
     "refresh_token": "1/8pMBx_lrUyitknmGzzH-yOcvoPIZ1OqhPeWvcYJOd0U"
    }

    Paste the updated cURL command in your terminal to generate the OAuth2 access token, token validity period, and the refresh token.
    oauth2-access-refresh

  14. Update the following configurations in the <IS_HOME>/repository/conf/identity/deployment.toml file.

    Sample configuration when using Identity Server as Email OTP Provider

    [authentication.authenticator.email_otp]
    name = "EmailOTP"
    enable= true
    [authentication.authenticator.email_otp.parameters]
    EMAILOTPAuthenticationEndpointURL = "https://localhost:9443/emailotpauthenticationendpoint/emailotp.jsp"
    EmailOTPAuthenticationEndpointErrorPage = "https://localhost:9443/emailotpauthenticationendpoint/emailotpError.jsp"
    EmailAddressRequestPage = "https://localhost:9443/emailotpauthenticationendpoint/emailAddress.jsp"
    usecase = "association"
    secondaryUserstore = "primary"
    EMAILOTPMandatory = false
    sendOTPToFederatedEmailAttribute = false
    federatedEmailAttributeKey = "email"
    EmailOTPEnableByUserClaim = true
    CaptureAndUpdateEmailAddress = true
    showEmailAddressInUI = true
    useEventHandlerBasedEmailSender = true
    emailAddressRegex = '(?&lt;=.{1}).(?=.*@)'
    Tip
    • If you need to send the content in a payload, you can introduce a property in a format \<API> Payload and define the value. Similarly, you can define the Form Data.FormdataforSendgridAPIisgivenasan example.
    • You can use \<API> URLParams, \<API>AuthTokenType, \<API>Failure and \<API>TokenEndpoint property formats to specify the URL parameters, Authorization token type, Message to identify failure and Endpoint to get access token from refresh token respectively.
    • Value of \<API> URLParams should be like; api_user=\<API_USER>&api_key=\<API_KEY>&data=\<DATA>&list\<LIST>

    Property Description
    GmailClientId Enter the Client ID you got in step 10 .
    Example: 501390351749-ftjrp3ld9da4ohd1rulogejscpln646s.apps.googleusercontent.com
    GmailClientSecret Enter the client secret you got in step 10 .
    Example: dj4st7_m3AclenZR1weFNo1V
    SendgridAPIKey This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.
    GmailRefreshToken Enter the refresh token that you got as the response in step 13 . Example: 1/YgNiepY107SyzJdgpynmf-eMYP4qYTPNG_L73MXfcbv
    GmailEmailEndpoint Enter your username of your Gmail account in place of the [userId] place holder. Example: https://www.googleapis.com/gmail/v1/users/[email protected]/messages/send
    SendgridEmailEndpoint This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.
    accessTokenRequiredAPIs

    Use the default value.

    apiKeyHeaderRequiredAPIs

    This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.

    SendgridFormData=to This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.
    SendgridURLParams This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.
    GmailAuthTokenType Use the default value.
    GmailTokenEndpoint Use the the deafult value.
    SendgridAuthTokenType This property is only required if you are using the Sengrid method. Since you are using Gmail APIs, keep the default value.


Configure the Identity Provider

Follow the steps below to add an identity provider:

  1. Click Add under Main > Identity > Identity Providers.
    adding-an-identity-provider

  2. Provide a suitable name for the identity provider.
    name-the-identity-provider

  3. Expand the EmailOTPAuthenticator Configuration under Federated Authenticators.

    1. Select the Enable and Default check boxes(If you are using Gmail or Sendgrid as the email OTP provider, provide values for Email API and Email fields as well).

    2. Click Register.

      registering-an-identity-provider

    You have now added the identity provider.


Configure the Service Provider

In the Deploying travelocity sample application section you have configured a service provider to register the travelocity.com as an application in the WSO2 Identity Server. Follow the steps below to modify the same service provider in order to configure Email OTP as second authentication step.

  1. Return to the Management Console home screen.

  2. Click List under Main > Identity > Service Providers and locate the above created service provider and click Edit.

  3. Go to Claim Configuration and select the http://wso2.org/claims/emailaddress claim.

    claim-configuration

  4. Go to Local and Outbound Authentication Configuration section.

    1. Select the Advanced configuration radio button option.

    2. Creating the first authentication step:

      1. Click Add Authentication Step.

      2. Click Add Authenticator that is under Local Authenticators of Step 1 to add the basic authentication as the first step.
        Adding basic authentication as a first step ensures that the first step of authentication will be done using the user's credentials that are configured with the WSO2 Identity Server

    3. Creating the second authentication step:

      1. Click Add Authentication Step.

      2. Click Add Authenticator that is under Federated Authenticators of Step 2 to add the EMAIL OTP identity provider you created as the second step.
        EMAIL OTP is a second step that adds another layer of authentication and security.

    add-authenticator

  5. Click Update.

    You have now added and configured the service provider.

    Note

    For more information on service provider configuration, see Configuring SAML2 Web Single Sign-On.


Update the email address of the user

Follow the steps given below to update the user's email address.

  1. Return to the WSO2 Identity Server Management Console home screen.
  2. Click List under Add under Main > Identity > Users and Roles.
    management-console
    1. Click Users.
      console-users-options
    2. Click User Profile under Admin.
      console-user-profile
    3. Update the email address.
      console-email-address
    4. Click Update.

Configure the user claims

Follow the steps below to map the user claims:

  1. Click List under Main > Identity > Claims.
    listing-claims

    1. Click http://wso2.org/claims.
      available-claim-dialects

    2. Click Edit in Disable EmailOTP. disable-emailotp-claim

    3. Select Suport by Default and click Update. emailotp-support-by-default

    4. Click Add.

      To disable this claim for the admin user, navigate to Users and Roles > List and click Users. Click on the User Profile link corresponding to admin account and enter "false" as the value for the Disable EmailOTP field. This will disable the second factor authentication for the admin user.


Test the sample

  1. To test the sample, go to the following URL: http://wso2is.local:8080/travelocity.com

    testing-travelocity-sample

  2. Click the link to log in with SAML from WSO2 Identity Server.

  3. The basic authentication page appears. Use your WSO2 Identity Server credentials.
    basic-authentication-credentials

  4. You receive a token to your email account. Enter the code to authenticate. If the authentication is successful, you are taken to the home page of the travelocity.com app.

    email-otp-authenticating

    travelocity-home


What's next?

Top