Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This tutorial teaches you how to build a Go console app that uses the Microsoft Graph API to access data using app-only authentication. App-only authentication is a good choice for background services or applications that need to access data for all users in an organization.
Note
To learn how to use Microsoft Graph to access data on behalf of a user, see this user (delegated) authentication tutorial.
In this tutorial, you will:
Tip
As an alternative to following this tutorial, you can download or clone the GitHub repository and follow the instructions in the README to register an application and configure the project.
Prerequisites
Before you start this tutorial, you should have Go installed on your development machine.
You should also have a Microsoft work or school account with the Global administrator role. If you don't have a Microsoft 365 tenant, you might qualify for one through the Microsoft 365 Developer Program; for details, see the FAQ. Alternatively, you can sign up for a one-month free trial or purchase a Microsoft 365 plan.
Note
This tutorial was written with Go version 1.19.3. The steps in this guide might work with other versions, but that hasn't been tested.
Register application for app-only authentication
Register an application that supports app-only authentication using client credentials flow.
Open a browser and navigate to the Microsoft Entra admin center and sign in using a Global administrator account.
Select Microsoft Entra ID in the left-hand navigation, expand Identity, expand Applications, then select App registrations.
Select New registration. Enter a name for your application, for example,
Graph App-Only Auth Tutorial
.Set Supported account types to Accounts in this organizational directory only.
Leave Redirect URI empty.
Select Register. On the application's Overview page, copy the value of the Application (client) ID and Directory (tenant) ID and save them. You'll need these values in the next step.
Select API permissions under Manage.
Remove the default User.Read permission under Configured permissions by selecting the ellipses (...) in its row and selecting Remove permission.
Select Add a permission, then Microsoft Graph.
Select Application permissions.
Select User.Read.All, then select Add permissions.
Select Grant admin consent for..., then select Yes to provide admin consent for the selected permission.
Select Certificates and secrets under Manage, then select New client secret.
Enter a description, choose a duration, and select Add.
Copy the secret from the Value column, you'll need it in the next steps.
Important
This client secret is never shown again, so make sure you copy it now.
Note
Notice that, unlike the steps when registering for user authentication, in this section you did configure Microsoft Graph permissions on the app registration. App-only auth uses the client credentials flow, which requires that permissions be configured on the app registration. See The .default scope for details.
Create a Go console app
Begin by initializing a new Go module using the Go CLI. Open your command-line interface (CLI) in a directory where you want to create the project. Run the following command.
go mod init graphapponlytutorial
Install dependencies
Before moving on, add dependencies that you use later.
- Azure Identity Client Module for Go to authenticate the user and acquire access tokens.
- Microsoft Graph SDK for Go to make calls to the Microsoft Graph.
- GoDotEnv for reading environment variables from .env files.
To install the dependencies, run the following commands in your CLI.
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
go get github.com/microsoftgraph/msgraph-sdk-go
go get github.com/joho/godotenv
Load application settings
Add the details of your app registration to the project.
Create a file in the same directory as go.mod named .env and add the following code.
CLIENT_ID=YOUR_CLIENT_ID_HERE CLIENT_SECRET=YOUR_CLIENT_SECRET_HERE TENANT_ID=YOUR_TENANT_ID_HERE
Update the values according to the following table.
Setting Value CLIENT_ID
The client ID of your app registration CLIENT_SECRET
The client secret of your app registration TENANT_ID
The tenant ID of your organization Tip
Optionally, you can set these values in a separate file named .env.local.
Design the app
Create a console-based menu.
Create a new directory in the same directory as go.mod named graphhelper.
Add a new file in the graphhelper directory named graphhelper.go and add the following code.
package graphhelper import ( "context" "os" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" auth "github.com/microsoft/kiota-authentication-azure-go" msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go" "github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/users" ) type GraphHelper struct { clientSecretCredential *azidentity.ClientSecretCredential appClient *msgraphsdk.GraphServiceClient } func NewGraphHelper() *GraphHelper { g := &GraphHelper{} return g }
This code creates a basic GraphHelper type that you extend in later sections to use Microsoft Graph.
Create a file in the same directory as go.mod named graphapponlytutorial.go. Add the following code.
package main import ( "fmt" "graphapponlytutorial/graphhelper" "log" "github.com/joho/godotenv" ) func main() { fmt.Println("Go Graph App-Only Tutorial") fmt.Println() // Load .env files // .env.local takes precedence (if present) godotenv.Load(".env.local") err := godotenv.Load() if err != nil { log.Fatal("Error loading .env") } graphHelper := graphhelper.NewGraphHelper() initializeGraph(graphHelper) var choice int64 = -1 for { fmt.Println("Please choose one of the following options:") fmt.Println("0. Exit") fmt.Println("1. Display access token") fmt.Println("2. List users") fmt.Println("3. Make a Graph call") _, err = fmt.Scanf("%d", &choice) if err != nil { choice = -1 } switch choice { case 0: // Exit the program fmt.Println("Goodbye...") case 1: // Display access token displayAccessToken(graphHelper) case 2: // List users listUsers(graphHelper) case 3: // Run any Graph code makeGraphCall(graphHelper) default: fmt.Println("Invalid choice! Please try again.") } if choice == 0 { break } } }
Add the following placeholder methods at the end of the file. You implement them in later steps.
func initializeGraph(graphHelper *graphhelper.GraphHelper) { // TODO } func displayAccessToken(graphHelper *graphhelper.GraphHelper) { // TODO } func listUsers(graphHelper *graphhelper.GraphHelper) { // TODO } func makeGraphCall(graphHelper *graphhelper.GraphHelper) { // TODO }
This implements a basic menu and reads the user's choice from the command line.