0
votes

Using Microsoft graph API i am able to update the phone authentication method section with mobile number using PostMan tool.

Based the approach i have created a Web API method that has to update the phone authentication method section with mobile number for the user. But fails with error

The user is unauthenticated

This is to have the MFA where-in user is expected to input the one time passcode sent to the given mobile number.

The code i have written is:


>     using System;
>     using System.Collections.Generic;
>     using System.Net.Http.Headers;
>     using System.Threading.Tasks;
>     
>     using Microsoft.Extensions.Options;
>     using Microsoft.Graph;
>     using Microsoft.Graph.Auth;
>     using Microsoft.Identity.Client;
>     
>     using UseGraphAPI.Interfaces;
>     using UseGraphAPI.Models;
>     
>     namespace UseGraphAPI.Repository
>     {
>         public class UserManager : IUserManager
>         {
>             private readonly GraphServiceClient graphClient;
>             private readonly B2CUserSettings userSettings;
>             private readonly AuthenticationResult token;
>     
>             public UserManager(IOptions<B2CUserSettings> userSettings)
>             {
>                 // The client_id, client_secret, and tenant are pulled in from the appsettings.json from coach API
>                 this.userSettings = userSettings.Value;
>     
>                 // Initialize the client credential auth provider
>                 IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
>                     .Create(this.userSettings.Clientid)
>                     .WithTenantId(this.userSettings.Tenant)
>                     .WithClientSecret(this.userSettings.Clientsecret)
>                     //.WithRedirectUri("http://localhost:62569")
>                     //.WithAuthority("https://login.microsoftonline.com/29fdf6e9-53c9-4bc7-8927-fa50e62019bc/v2.0")
>                     .Build();
>     
>                 ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
>     
>                 // Set up the Microsoft Graph service client with client credentials
>                 GraphServiceClient graphClient = new GraphServiceClient(authProvider);
>     
>                 //string[] scopes = new string[] {
>                 //    "https://graph.microsoft.com/.default"
>                 //};
>     
>                 //token = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().Result;
>                 //GraphServiceClient graphClient = new GraphServiceClient("https://graph.microsoft.com/beta", 
>                 //    new DelegateAuthenticationProvider(async(requestMessage) => 
>                 //    {
>                 //    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token.AccessToken);
>                 //    }));
>     
>                 this.graphClient = graphClient;
>             }
>     
>             public async Task UpdateUserPhoneMethod(B2CUserPhoneAuth b2CUserPhoneAuth)
>             {
>                 var user = await GetUserByEmail(b2CUserPhoneAuth.Email);
>                 var userId = user.CurrentPage[0].Id;
>     
>                 try
>                 {
>                     PhoneAuthenticationMethod phoneAuthenticationMethod = new PhoneAuthenticationMethod()
>                     {
>                         PhoneNumber = b2CUserPhoneAuth.PhoneNumber,
>                         PhoneType = AuthenticationPhoneType.Mobile
>                     };
>     
>                     await graphClient.Users[userId].Authentication.PhoneMethods
>                         .Request()
>                         .AddAsync(phoneAuthenticationMethod);
>                 }
>                 catch (Exception ex)
>                 {
>                     throw ex;
>                 }
>             }
>         }
>     }

The permissions given on the application that is registered in Azure are:

Directory.AccessAsUser.All (Delegated) Directory.ReadWrite.All (Delegated & Application) Policy.Read.All (Delegated) Policy.ReadWrite.AuthenticationMethod (Delegated) User.ReadWrite.All (Delegated & Application) UserAuthenticationMethod.ReadWrite.All (Delegated & Application)

Please review and let me know if there is something missing in my code or permissions.

The requirement is to create user and add mobile phone with SMS signin flag to true.

regards,

Arjuna

1
ClientCredentialProvider use application permission, but the API doesn't support application permission, see here. You could only use the delegate permission as the doc shows.Pamela Peng
See my responses at following posting : stackoverflow.com/questions/64375532/…jdweng
@jdweng, I saw your posted URL and found it is using HttpClient. But if you see my code i am using the MS graph API beta version which does'nt have the option. Can you suggest if there is a way that can be achieved in my code.Mallikarjuna
Read notes on following page : github.com/microsoftgraph/uwp-csharp-connect-samplejdweng
@jdweng, I verified trying out your option before this line of code await graphClient.Users[userId].Authentication.PhoneMethods .Request() .AddAsync(phoneAuthenticationMethod); it throws the below error Code: unauthenticated Message: The user is unauthenticated. Inner error: Message: The user is unauthenticated. AdditionalData: date: 2020-10-19T10:16:41 request-id: 904355cc-df61-4428-89dc-b8dc08b27646 client-request-id: 904355cc-df61-4428-89dc-b8dc08b27646 ClientRequestId: 904355cc-df61-4428-89dc-b8dc08b27646Mallikarjuna

1 Answers

0
votes

As I said in the comment, the code ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication); is based on client credential flow with application permission. But the API only supports delegate permission.

You could use other methods(eg.AuthorizationCodeProvider) instead of it.

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithRedirectUri(redirectUri)
                .WithClientSecret(clientSecret) // or .WithCertificate(certificate)
                .Build();

AuthorizationCodeProvider authenticationProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);