Using native authentication in Entra External ID to sign in a user with email and OTP

Rory Braybrook
The new control plane
3 min readMay 27, 2024
Image showing login screen with OTP
Image via Copilot Designer

First, read this post, as it covers a lot of the basics.

The documentation is here.

Essentially, you use the API to sign in as a user. You specify:

  • an email address
  • then, an OTP is sent to the email address, and you need to provide a way to enter it
  • you send the OTP back to the API to verify
  • you get a token
  • the user is signed in Entra External ID

You are free to do this on one page or use multiple pages or whatever.

As before, we will use Postman.

Note that the redirectURI in the app. registration for Postman is:

https://oauth.pstmn.io/v1/browser-callback

Note that each step gives a new continuation token that you have to copy to the next step.

Prerequisites

These are noted here.

  • Register an application in the Microsoft Entra admin centre. Make sure you grant delegated permissions, and enable public client and native authentication flows
  • Create a user flow in the Microsoft Entra admin centre. Under Identity providers, select the Email one-time-passcode option
  • Associate your app registration with the user flow
  • If you haven’t already done so, enable the email one-time passcode functionality

Gotchas

The user that you use to sign in has to be created via a email with OTP user flow. Use theNo account? Create one” option on the login screen.

It will not work with a user created via an email / password flow or a user created via the portal or a user created via Graph API. All these cases will result in a response of “redirect”.

Step 1

Image of Postman screen with details as below

The URL is:

https://tenant.ciamlogin.com/tenant.onmicrosoft.com/oauth2/v2.0/initiate

with the form containing:

client_id=61...9b
&challenge_type=oob redirect
&username=email address

The following is returned:

{
"continuation_token": "AQA...SAA"
}

Step 2

Image of Postman screen with details as below

The URL is:

https://tenant.ciamlogin.com/tenant.onmicrosoft.com/oauth2/v2.0/challenge

with the form containing:

client_id=61...9b
&challenge_type=oob redirect
&continuation_token=AQA...qZw

The following is returned:

{
"continuation_token": "AQA...iAA",
"challenge_type": "oob",
"binding_method": "prompt",
"challenge_channel": "email",
"challenge_target_label": "email address",
"code_length": 8
}

You should get this email sent to the address you specified above:

Image of email with OTP verification code

Step 3

Image of Postman screen with details as below

The URL is:

https://tenant.ciamlogin.com/tenant.onmicrosoft.com/oauth2/v2.0/token

with the form containing:

continuation_token=AQA...043
&client_id=61...9b
&grant_type=oob
&oob={otp_code}
&scope= openid offline_access

The following is returned:

{
"token_type": "Bearer",
"scope": "openid profile email 00000003-...00000/User.Read",
"expires_in": 5347,
"ext_expires_in": 5347,
"access_token": "eyJ...I0A",
"refresh_token": "0.A...O18",
"id_token": "eyJ...0wg"
}

where the id_token looks like:

{
"aud": "61d...29b",
"iss": "https://7f...bb.ciamlogin.com/7f...bb/v2.0",
"iat": 1716767973,
"nbf": 1716767973,
"exp": 1716771873,
"idp": "mail",
"rh": "0.Ab...ANk.",
"sub": "Sgi...gUs",
"tid": "7f...bb",
"uti": "NmW...DAA",
"ver": "2.0"
}

The user is now signed in.

All good!

--

--

Rory Braybrook
The new control plane

NZ Microsoft Identity dude and MVP. Azure AD/B2C/ADFS/Auth0/identityserver. StackOverflow: https://bit.ly/2XU4yvJ Presentations: http://bit.ly/334ZPt5