403 error while calling google workspace user API with service account credentials in golang

I am getting a 403 error while trying to call google workspace list user API using service account credentials in Golang. I want to access list of all users in my google workspace programmatically in Golang. I have configured domain wide delegation for service account and has given necessary scopes as well.

Below is my go code to achieve this. I am able to get an access token using getAccessTokenFromServiceAccount() function but that token does not seem to work.

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "golang.org/x/oauth2/jwt"
)

func getAccessTokenFromServiceAccount(credentialFile string) (*oauth2.Token, error) {
    b, err := ioutil.ReadFile(credentialFile)
    if err != nil {
        return nil, err
    }
    var c = struct {
        Email      string `json:"client_email"`
        PrivateKey string `json:"private_key"`
    }{}
    json.Unmarshal(b, &c)
    config := &jwt.Config{
        Email:      c.Email,
        PrivateKey: []byte(c.PrivateKey),
        Scopes: []string{
            "https://www.googleapis.com/auth/admin.directory.user",
            "https://www.googleapis.com/auth/drive",
        },
        TokenURL: google.JWTTokenURL,
    }
    token, err := config.TokenSource(oauth2.NoContext).Token()
    if err != nil {
        return nil, err
    }
    return token, nil
}

func getUsersWithAccessKey(accessToken string) (string, error) {

    url := "https://admin.googleapis.com/admin/directory/v1/users?domain=example.com"
    method := "GET"

    client := &http.Client{}
    req, err := http.NewRequest(method, url, nil)

    if err != nil {
        fmt.Println(err)
        return "", err
    }
    req.Header.Add("Authorization", "Bearer "+accessToken)

    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
        return "", err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
        return "", err
    }
    return string(body), nil
}

func main() {
    token, err := getAccessTokenFromServiceAccount("creds.json") 
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(token.AccessToken)

    output, err := getUsersWithAccessKey(token.AccessToken)
    if err != nil {
        fmt.Println(err)
        fmt.Println(output)
        return
    }
    fmt.Println(output)
}

I have replaced domain with my own domain name.

I get 403 error while running this code

{
  "error": {
    "code": 403,
    "message": "Not Authorized to access this resource/api",
    "errors": [
      {
        "message": "Not Authorized to access this resource/api",
        "domain": "global",
        "reason": "forbidden"
      }
    ]
  }
}

Please let me know if more information is needed. Any help would be appreciated. Thanks

Share

Improve this question

Follow

asked May 12, 2023 at 8:30


zweack's user avatar

zweack

14111 silver badge1010 bronze badges