Microsoft Secure Tech Accelerator
Apr 03 2024, 07:00 AM - 11:00 AM (PDT)
Microsoft Tech Community
Manage your authentication phone numbers and more in new Microsoft Graph beta APIs
Published May 28 2020 09:00 AM 36.9K Views

Howdy folks!

 

We’ve had a ton of requests for APIs to manage users’ authentication methods. That’s why it is so cool that today I get to announce that the first set of these APIs has reached beta in Microsoft Graph! Michael McLaughlin, one of our Identity team program managers, has written a guest blog post with information about the new APIs and how to get started.

 

As always, we’d love to hear any feedback or suggestions you may have. Please let us know what you think in the comments below or on the Azure Active Directory (Azure AD) feedback forum.

 

Best Regards,

Alex Simons

Corporate Vice President Program Management

Microsoft Identity Division

---------------------------------------

Hi everyone,

 

I’m thrilled to tell you about the new Azure AD authentication method APIs. These APIs are a key tool to manage your users’ authentication methods. Now you can programmatically pre-register and manage the authenticators used for MFA and self-service password reset (SSPR). This has been one of the most-requested features in the Azure MFA, SSPR, and Microsoft Graph spaces.

 

The new APIs we’ve released in this wave give you the ability to:

 

  • Read, add, update, and remove a user’s authentication phones.
  • Reset a user’s password.
  • Turn on and off SMS sign-in.

We will be adding support for all authentication methods in the coming months.

 

These come at a crucial time. The shift to remote work driven by the COVID-19 pandemic has created unique complications for getting users registered for MFA and SSPR. Admins tell us that they don’t want users registering from potentially unsafe locations, but they do need to get users registered as soon as possible to get them protected. These APIs give you the ability to register your users and set them up to do MFA via SMS immediately without requiring them to register themselves from beyond your corporate network.

 

These APIs can be called by Global administrators, Privileged authentication administrators, Authentication administrators (recommended), and Global readers (can only use the read APIs). The ability to manage other users’ authentication methods is very powerful, so be sure to require MFA for these roles!

 

Here’s an example of adding a phone number for a user by posting to a user’s phone methods URL:

https://graph.microsoft.com/beta/users/<UPN>/authentication/phoneMethods

 

In the body, you pass in the type of phone (for example, “mobile”) and the number, and in the response you get back the full phone number entity:

 

API.png

 

Check out this tutorial to get you started, and to learn more, check out the Azure AD authentication methods API overview.

 

Thanks for reading. We hope these APIs help you in the work you’re doing today, and we’re hard at work expanding the range of authentication method APIs available to make them even more useful for you.

 

All the best,

Michael McLaughlin

Program Manager

Microsoft Identity Division

 

59 Comments

When can we expect support for application permissions?

@Vasil Michev - no ETA I can share but it's in development.

Steel Contributor

@Vasil Michev @Michael McLaughlin I was going to ask the exact same question :smile:

Any tips to automate this in the meantime? 

Iron Contributor

Would this feature eventually be added to the AzureAD module? 

 

I could probably write something up to do it out of PoSH but a cmdlet would be easier :)

@Vasil Michev Even though documentation says not supported for application permission, I do see it as an available permission, haven't tested yet but its there:

 

UserAuthMethodAppPermission.png

Steel Contributor

@Jan Vidar Elven I've tested this. You'll get: "user not authenticated"  when you run the API's. :sad:

Yes, I've tested now myself @JanBakkerOrphaned.

 

@Michael McLaughlin another issue I see, I've used delegated permission with my B2B Guest account to a tenant where I am Global Administrator. In this case I also get "user not authenticated". Is this by design or should this work?

Copper Contributor

when i try to run this as Global Admin i get this:

 

"error": {
"code": "directory_read_unauthorized",
"message": "User does not have permissions to manage this data.",
"innerError": {
"request-id": "a0ccc2ef-64dc-49b8-9a03-6d0e9a71d2cf",
"date": "2020-06-04T16:24:53"
}
Steel Contributor

@Mark_Steele you should first assign the right permissions to the user. 

UserAuthenticationMethod.ReadWrite.All 

Copper Contributor

Im trying to figure that part out now.  Under permissions i don't see UserAuthenticationMethod.ReadWrite.All  available for consent.

 

@Mark_Steele - are you using Graph Explorer? We've become aware that the permissions aren't showing up there and we're working on that right now. I'll update this space when that's fixed.

 

@Jan Vidar Elven - I'm reaching out privately re: your error.

 

@JanBakkerOrphaned - best plan for automation is wait for app-only! 

Brass Contributor

Thanks @Michael McLaughlin I can confirm that I also can't see any UserAuthenticationMethod.ReadWrite.All-permissions. I'll be sure to try this again later when it's working again. :smile:

Copper Contributor

@Michael McLaughlin yes I'm using Graph Explorer. 

 

Also, Any chance we will be able to update their contact email in the future?

 

Thanks.

Copper Contributor

Is this a sign that we soon will be able to, via the GUI, stage all our users mobile numbers in to MFA and then maybe mandate sms as default/starting MFA method (which would be used for further MFA access and registration of the other MFA methods)?

Thanks

It is not working for the POST method, im able to get input for GET method

 

Post method is just loop and no data

@Michael McLaughlin In the post method, it keeps run query and it failed after some time . Get is working not post

@Simon Håkansson @Mark_Steele - Graph Explorer should have all of the required permissions available now!

 

@Mark_Steele - we're working on making all authentication methods available via this API set. That includes the authentication email, which is used solely for self-service password reset.

 

@Aengus Moran - you'll definitely be able to do those things via the API! We're still working out specific plans for what will and won't be built into the UX.

 

@Sankarasubramanian Parameswaran - that's a really odd issue, we haven't heard any similar reports. Could you reach out to me directly in a private message with more details?

@Michael McLaughlin  Thank you. It worked after some time. Do you have option for the bulk register. we have more than 5000 users not registered for MFA

@Sankarasubramanian Parameswaran great to hear, thanks for the update. With this API, if you have the usernames and phone numbers, you can script that registration. It's also available in the Microsoft Graph Powershell module if you're more comfortable working in Powershell. 

Copper Contributor

@Michael McLaughlin  I can confirm this works now as well.  Awesome

 

Now as @Sankarasubramanian Parameswaran asked what would be the best way to bulk update about 7,000 users.

 

Thanks,

Markus

 

@Michael McLaughlin I will check the option in Graph api. As we said, we have more than 5000 users and we need to automate this

Brass Contributor

Does this work for application permission? we have an automated process between HR and AzureAD which updates users mobile number, we would like to automate this part using application permissions,  is it solved?

Copper Contributor

I'm able to connect to graph now an update authentication methods for phone number via Graph PowerShell.  I just can't find any information on what -"PhoneAuthenticationMethodId <String>" .  When i look up  detail for the command im provided a link that is dead: https://docs.microsoft.com/en-us/powershell/module/microsoft.graph.identity.authenticationmethods/up....

When i run the command i do see a phone ID and it appears to be same for all:

 

Get-MgUserAuthenticationPhoneMethod -UserId 259089c6-10b8-4164-b537-XXXXXXXX

Id PhoneNumber PhoneType SmsSignInState
-- ----------- --------- --------------
3179e48a-750b-4051-897c-87b9720928f7 +1 5xx9xxxx55 mobile notAllowedByPolicy

Copper Contributor

When i try to get using  application permissions i get following error:

 

httpGet:

https://graph.microsoft.com/beta/users/objectId/authentication/phoneMethods

 

{
  "error": {
    "code""unauthenticated",
    "message""The user is unauthenticated.",
    "innerError": {
      "message""The user is unauthenticated.",
      "date""2020-06-22T15:38:47",
      "request-id""8e93deea-7e34-4f56-8c3c-3be41e086751"
    }
  }
}
Copper Contributor

Mark_Steele_0-1592841818376.png

@Maqsood Ali Bhatti   Make sure to consent permissions.

@Maqsood Ali Bhatti and @belaie - app-only permissions aren't ready yet, but we're working on them.

 

@Mark_Steele - each auth method has an ID that's unique in the context of the user. Some are reused for each user/method, and some are globally unique.

Copper Contributor

@Michael McLaughlin  Thanks for updates; we will do with app permissons so what is ETA?

@Maqsood Ali Bhatti No ETA I can share today, but I'll update here when it's ready!

Copper Contributor

@Michael McLaughlin  Fantastic ! Looking forward

Copper Contributor

@Michael McLaughlin is there a list of global authentication methods?

 

Also, are there examples of using Graph Powershell with Update-MgUserAuthenticationPhoneMethod?

Copper Contributor

Hi All, 

 

Is it normal for the phone number be obfuscated? I mean I added a phone number to an user and now when I request the List endpoint I get the phone number like this "phoneNumber":"+XX XXXXXXXX01","phoneType":"mobile","smsSignInState":"notSupported".

I can only see the last two digits of the number, and I also get notSupported for smsSignInState. So, I'm unsure if the number was added correctly or I did something wrong.

Yes, the number is obfuscated for authentication admins. It should be visible for global admins, privileged authentication admins, and global readers.

Copper Contributor

@Michael McLaughlin Thank you for the update. I do have only authentication admin role, this explains the obfuscation.

Another question I have is in regards the SSPR. For the user I've mentioned before, I can see in Azure that the column SSPR Registered displays "Not Registered", however, the column SSPR Enabled display "Enabled".

Is there a way to pre-register the user for SSPR using the API?

It is worth mentioning that the columns MFA Registered displays "Registered" and the Methods Registered displays "Mobile phone".


 

@JeffersonGomes When you use the API to register a number for the user, it should be available for use in SSPR if the SSPR policy has "Mobile phone" and/or "Office phone" checked on as appropriate. For your user, I suspect one of two things. Either 1) your SSPR policy is set to two methods required to reset, or 2) your user is an admin, in which case the built-in admin policy applies. In either case, the user needs two methods to reset a password, and registering just one thing won't get them to a "registered" state. If neither apply here, let me know.

Copper Contributor

@Michael McLaughlin  I'm trying to figure out how to right this Graph PowerShell Command to update Contact Method command but have been unable to fine any examples on how to do it.  I believe I want to use this command to add or replace users phone number.

 

Update-MgUserAuthenticationPhoneMethod -UserId 259089c6-10b8-4164-b537-0058b24459b7 -Id 3179e48a-750b-4051-897c-87b9720928f7 -phonenumber "+1 5409446666"

 

Supply values for the following parameters:
PhoneAuthenticationMethodId:  

 

I'm not sure what the difference is from "-ID" vs "-PhoneAuthenticationMethodId"

 

 

Brass Contributor

@Michael McLaughlin Looking forward to read /write Authentication phone on all users through Powershell Graph API in the near future :)  When the Graph permissions have been fixed. 
( i tried to assign & admin concent to all userauthmethods in both Delegation & Application scope. but nothing wordked :(

Copper Contributor

I have had no luck trying to get this to work, not sure if anyone else has?

 

Update-MgUserAuthenticationPhoneMethod -PhoneAuthenticationMethodId "3179e48a-750b-4051-897c-87b9720928f7" -UserId "259089c6-10b8-4164-b537-0058b24459b7" -PhoneNumber "+1 5404444444" -PhoneType "mobile"

Update-MgUserAuthenticationPhoneMethod : {"Message":"No HTTP resource was found that matches the request URI 'https://mface.windowsazure.com/odata/users('259089c6-10b8-4164-b537-0058b24459b7%407fef86bb-a3b9-46e... type was found that matches the controller named 'users'."}
At line:1 char:1
+ Update-MgUserAuthenticationPhoneMethod -PhoneAuthenticationMethodId " ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ UserId = 2590...icationMethod }:<>f__AnonymousType12`3) [Update-MgU
serAu..._UpdateExpanded], Exception
+ FullyQualifiedErrorId : UnknownError,Microsoft.Graph.PowerShell.Cmdlets.UpdateMgUserAuthenticationPhoneMethod_Up

dateExpanded

Copper Contributor

@Mark_Steele I get the same error. I guess we have to use the REST API directly until it gets resolved.

Copper Contributor

I'm trying to create users in B2C and set a mobile phone for authentication method all using delgated authority.  The first step works and the user is created, but the step to create the mobile phone authentication method fails with "The user is unauthenticated".  I am authenticating the user with the scopes Directory.ReadWrite.All & UserAuthenticationMethod.ReadWrite.All.

 

I'm using the Microsoft.Graph.Beta package.  Here's the code:

                // Create the user in B2C
                var user = await graphServiceClient
                    .Users
                    .Request()
                    .AddAsync(new User {
                        DisplayName = request.Email,
                        PasswordProfile = new PasswordProfile {
                            ForceChangePasswordNextSignIn = true,
                            Password = password
                        },
                        Identities = new[] {
                        new ObjectIdentity {
                            SignInType = "emailAddress",
                            Issuer = "***.b2clogin.com",
                            IssuerAssignedId = request.Email
                        }
                        }
                    });

                // setup the mobile phone for MFA
                await graphServiceClient
                    .Users[user.Id]
                    .Authentication
                    .PhoneMethods
                    .Request()
                    .AddAsync(new PhoneAuthenticationMethod {
                        PhoneNumber = request.Mobile,
                        PhoneType = AuthenticationPhoneType.Mobile
                    });

 

Here's the full error details:

Microsoft.Graph.ServiceException: 'Code: unauthenticated
Message: The user is unauthenticated.
Inner error:
Message: The user is unauthenticated.
AdditionalData:
date: 2020-07-24T09:57:37
request-id: eee9ddb8-19df-49ad-a87f-8c393becb7e5
ClientRequestId: eee9ddb8-19df-49ad-a87f-8c393becb7e5

Am I doing something wrong?  Or is there an issue with the API?

Any help would be greatly appreciated!

Copper Contributor

@Russell Seamer Can you double check if the account used to authenticate in the API has one for these privileges roles? “Global administrators, Privileged authentication administrators, Authentication administrators (recommended)“


Setting the scopes is not enough. Your error seems to be related to privilege role.

Copper Contributor

@JeffersonGomes I was already global administrator, but I tried adding "Authentication administrators" as well, but I get the same response.

 

Steel Contributor

Interesting @JanBakkerOrphaned, great work and thanks for sharing!

Copper Contributor

@Alex Simons (AZURE) Great stuff. Any ETA to release this API?

Copper Contributor

I'm now getting the following error when trying to get the authentication methods for an account in our B2C domain,  not sure when this started but i know this was working a couple of months ago..

 

or": {
        "code": "badRequest",
        "message": "{\"odata.error\":{\"Code\":\"directory_error\",\"Message\":{\"Lang\":\"en\",\"Value\":\"$expand of back links is not supported for mega tenants.\"},\"Values\":[{\"Item\":\"subCode\",\"Value\":\"error_fail\"},{\"Item\":\"requestId\",\"Value\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"},{\"Item\":\"time\",\"Value\":\"08-13-2020 10:34:05Z\"}]}}",
        "innerError": {
            "message": "{\"odata.error\":{\"Code\":\"directory_error\",\"Message\":{\"Lang\":\"en\",\"Value\":\"$expand of back links is not supported for mega tenants.\"},\"Values\":[{\"Item\":\"subCode\",\"Value\":\"error_fail\"},{\"Item\":\"requestId\",\"Value\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"},{\"Item\":\"time\",\"Value\":\"08-13-2020 10:34:05Z\"}]}}",
            "date": "2020-08-13T10:34:05",
            "request-id": "fc6f237c-c565-4b80-a825-5b82deaf36b6"

 

 

Copper Contributor

@Michael McLaughlin Is there an ETA when we can change the authentication email registred to an user account? Or is there any otherway to clear the authentication e-mail (because we have 3k users registed with a faulty authentication e-mail).

Copper Contributor

When i call this method:

 

https://graph.microsoft.com/beta/users/b561df64-9d65-4579-927d-cbc40a4f2910/authentication/phoneMeth...

 

I get this output:

 

{
"value": []
}
 
i.e. nothing in value - even though i know that a phone auth method exists.  This is a B2C tenant.
 
Also, is there a way that we can be notified when the app version of this api is available?
Copper Contributor

A couple of weeks ago I had this working in Powershell :

 

New-MgUserAuthenticationPhoneMethod -userid $upn -phoneType "mobile" -phoneNumber $mobileNo

 

Now I get an error message of 'Object reference not set to an instance of an object'

 

+ CategoryInfo : NotSpecified: (:) [New-MgUserAuthe..._CreateExpanded], NullReferenceException
+ FullyQualifiedErrorId : Microsoft.Graph.PowerShell.Cmdlets.NewMgUserAuthenticationPhoneMethod_CreateExpanded

 

Has something changed with regards to the command?

 

I can still post a phone authentication number via graph explorer.

Copper Contributor

@Michael McLaughlin 

Any update on the application permissions for these APIs?

Copper Contributor

This is what I've used to bulk upload, using the Access Token

#Access token required to update the record
$accessToken = "API Access Key here"
$filename = '\usersdata.txt'
# Loop a csv here with the userID and mobile numbers
$records = import-csv $filename
foreach ($record in $records){
    $user = $record.USER_ID
    $mobile = $record.PHONE
    $uri = "https://graph.microsoft.com/beta/users/$user@<domain>/authentication/phoneMethods"
    $body = @"
    {
        "phoneType": "mobile",
        "phoneNumber": "$mobile"
    }
"@
if ($mobile -match '((\+[0-9]{1,3}[ ])[0-9]{4,})'){ # Check number is in correct format
    write-host "Checking Number:  $user, $mobile"
    if ((Invoke-RestMethod -Method Get -Uri $uri -Headers @{"Authorization"="Bearer $accessToken"}).value.phoneType -ne 'mobile') {
        write-host "Adding Number:  $user, $mobile" -foregroundcolor green
        try {
            Invoke-RestMethod -Method Post -Uri $uri -Headers @{"Authorization"="Bearer $accessToken"} -Body $body
            $setMobile = (Invoke-RestMethod -Method Get -Uri $uri -Headers @{"Authorization"="Bearer $accessToken"}).value.phoneNumber
            if ($setMobile -ne $mobile){
                write-host "$user has their phone listed as $mobile, but it is $setMobile in Azure" -foregroundcolor red
            }

        }
        catch {
            Write-Host "Something wrong with the phone number for $user, $mobile" -foregroundcolor red
        }
        
    }
    else{
        $existingMobile = (Invoke-RestMethod -Method Get -Uri $uri -Headers @{"Authorization"="Bearer $accessToken"}).value.phoneNumber
        if ($existingMobile -ne $mobile){
            write-host "Skipping: $user, $mobile as $existingMobile already exists but don't match" -ForegroundColor yellow
            }
        else {
            write-host "Skipping: $user, $mobile as $existingMobile already exists"    
        }
    }
}
else{
    $existingMobile = (Invoke-RestMethod -Method Get -Uri $uri -Headers @{"Authorization"="Bearer $accessToken"}).value.phoneNumber
    write-host "Skipping: $user, $mobile Unknown CountryCode or invalid number" -foregroundcolor Red
}
}
Version history
Last update:
‎Jul 24 2020 01:06 AM
Updated by: