Calling Microsoft graph api through flutter app return 401

Sumesh Chandran 41 Reputation points
2022-11-20T20:25:03.933+00:00

I am calling the graph api with the token returned from the app to create a user in the tenant. This api totally works fine when calling through postman but not when calling through the mobile app which is created using Flutter.
Here is my request to get the access token through my mobile app. The below code works as expected and returns an access token.

final response = await http.post(  
                            Uri.parse(  
                                'https://login.microsoft.com/tenant-id/oauth2/token'),  
                            headers: {  
                              "Content-Type":  
                                  "application/x-www-form-urlencoded",  
                            },  
                            body: {  
                              "grant_type": "client_credentials",  
                              "client_id":  
                                  "client-id",  
                              "client_secret":  
                                  "client-secret",  
                              "resource": "https://graph.microsoft.com"  
                            },  
                          );  

Now I use the access token to create a user, this returns 401 and does not create a user.

String url = "https://graph.microsoft.com/v1.0/users";  
                        Map<String, String> headers = {  
                          'Content-Type': 'application/json',  
                          'Accept': 'application/json',  
                          'Authorization':  
                              'Bearer $token'  
                        };  
                        final body = jsonEncode({  
                          "accountEnabled": true,  
                          "city": "Seattle",  
                          "country": "United States",  
                          "department": "Sales & Marketing",  
                          "displayName": "Melissa Darrow",  
                          "givenName": "Melissa",  
                          "jobTitle": "Marketing Director",  
                          "mailNickname": "MelissaD",  
                          "passwordPolicies": "DisablePasswordExpiration",  
                          "passwordProfile": {  
                            "password": "82510f31-1c89-d103-73c8-9fbedda45dcc",  
                            "forceChangePasswordNextSignIn": false  
                          },  
                          "officeLocation": "131/1105",  
                          "postalCode": "98052",  
                          "preferredLanguage": "en-US",  
                          "state": "WA",  
                          "streetAddress": "9256 Towne Center Dr., Suite 400",  
                          "surname": "Darrow",  
                          "mobilePhone": "+1 206 555 0110",  
                          "usageLocation": "US",  
                          "userPrincipalName": "MelissaD@myorg.onmicrosoft.com"  
                        });  
                          final response = await http.post(Uri.parse(url),  
                              headers: headers, body: body);  
                          print(response.statusCode);  

Please advise!

Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,956 questions
{count} votes

Accepted answer
  1. Shweta Mathur 30,101 Reputation points Microsoft Employee
    2022-11-21T07:15:27.417+00:00

    Hi @Sumesh Chandran ,

    Thanks for reaching out.

    The error you are getting is 401 which is an Unauthorized error. The access token you are getting does not have valid permissions to create the user.

    Did you tried to decode the token using jwt.ms to check the valid claims.

    As mentioned in your code, you are using client credential flow to get the access token which is usually called for daemon applications.

    Make sure you are passing application permissions User.ReadWrite.All, Directory.ReadWrite.All while registering the application and getting roles claim in your JWT token.

    Also, you need to make sure you have a token with the aud claim of https://graph.microsoft.com or 00000003-0000-0000-c000-000000000000. If you are getting https://graph.windows.net a.k.a. 00000002-0000-0000-c000-000000000000, that means the token is for AAD Graph API and not for Microsoft Graph.

    Hope this will help.

    Thanks,
    Shweta

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

    Please remember to "Accept Answer" if answer helped you.


1 additional answer

Sort by: Most helpful
  1. Corjan Bos 1 Reputation point
    2022-11-26T08:08:45.53+00:00
    1. If Postman works but Flutter http.post fails with 401 I am sure your Postman requests contains other data than your http.post request. You should thoroughly check Postman header data and add any lacking header info to your http.post command.
    2. Also make sure your $token is not a future and is 'available' at the time you invoke the http.post command (you can check by simple put a print($token); just before the http.post command. Make sure it is a String and not a Future<String> for example.
    3. Try to make use of HttpHeaders class to eliminate typos and make your code future proof. In your case for example use

    HttpHeaders.authorizationHeader: 'Bearer $token',

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.