gomicrosoft-graph-api

msgraph-sdk-go example code for getting user's drive fails


The example code for the msgraph-sdk-go to get a user's drive fails with a 401 error below. It expects the request body to contain a client_secret, although there is no place in the example code to create a request body.

The example code does successfully authenticate to my registered application via a web browser.

What is required to use the msgraph-sdk-go?

Here's the code that fails:

result, err := client.Me().Drive().Get(context.Background(), nil)
if err != nil {
    fmt.Printf("Error getting the drive: %v\n", err)
    printOdataError(err)
}
fmt.Printf("Found Drive : %v\n", *result.GetId())

Here's the error:

Error getting the drive: DeviceCodeCredential authentication failed

POST https://login.microsoftonline.com/efa4b4f3-5e38-4866-9206-79c604d86e7c/oauth2/v2.0/token

RESPONSE 401 Unauthorized

"error": "invalid_client",
"error_description": "AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.

Trace ID: b6f28bb4-6bed-4dfe-a275-c0343fb91e01
Correlation ID: c06d2257-b3ab-4df3-ba58-ab271cf97508
Timestamp: 2023-02-14 14:18:22Z"
"error_codes": [ 7000218 ],
"timestamp": "2023-02-14 14:18:22Z",
"trace_id": "b6f28bb4-6bed-4dfe-a275-c0343fb91e01",
"correlation_id": "c06d2257-b3ab-4df3-ba58-ab271cf97508",
"error_uri": "https://login.microsoftonline.com/error?code=7000218"

Edit: adding more detail for the answer from baywet

I have the client and device code credentials created as baywet shows but I added the TenantID field.

In point 5 I selected mobile/desktop application but with redirect URI of http://localhost. I have different options for Redirect URIs than he has.

Redirect URIs

Point 6 was the key to getting it to work. Once I selected Yes for Enable the following mobile and desktop flows my application worked.

Allow public client flows

I also had these API permissions.

API permissions


Solution

  • Assuming you setup your client using the device code credentials given the error message you're getting with code similar to this

    cred, err := azidentity.NewDeviceCodeCredential(&azidentity.DeviceCodeCredentialOptions{
        ClientID: "CLIENT_ID",
        UserPrompt: func(ctx context.Context, message azidentity.DeviceCodeMessage) error {
            fmt.Println(message.Message)
            return nil
        },
    })
    
    client := msgraphsdk.NewGraphServiceClientWithCredentials(cred, []string{"User.Read"})
    

    The registered application needs to be configured properly to allow for the device close flow. For that:

    1. Go to the azure portal
    2. Navigate to the application registrations (Azure Active Directory, then Application registrations).
    3. Find your application registration in the list.
    4. Click on the authentication tab
    5. Make sure the mobile and desktop applications platform is select with the https://login.microsoftonline.com/common/oauth2/nativeclient URL checked.
    6. Make sur "Enable the following mobile and desktop flows" is set to "yes".
    7. Click "save".

    A couple of screenshots to guide you through.

    authentication platforms device code flow