azureauthenticationgomicrosoft-graph-api

Microsoft Graph API: Create subscription - Exception: [Status Code: Unauthorized] [Go]


After sending the response with the validation token (Create subscription: Example), the following message received:

Operation: Create; Exception: [Status Code: Unauthorized; Reason: General exception while processing]

The issue seems related to how the client is created, but testing various scopes (https://graph.microsoft.com/.default / Subscription.Read.All / Sites.Read.All) and client creation options did not resolve the exception. It's also worth noting that GET subscriptions function correctly.

const (
    tenantId = "..."
    clientId = "..."
    clientSecret = "..."
    siteId = "..."
    listId = "..."
    appScopes = "https://graph.microsoft.com/.default"
    webhookBaseUrl = "..."
)

import (
    "fmt"
    "time"
    "strings"
    "context"
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
    graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
)

func initializeGraphForUserAuth() (*msgraphsdk.GraphServiceClient, error) {
    credential, _ := azidentity.NewClientSecretCredential(tenantId, clientId, clientSecret, nil)
    graphClient, _ := msgraphsdk.NewGraphServiceClientWithCredentials(credential, strings.Split(appScopes, ","))
    return graphClient, nil
}

func newSubscription(g *msgraphsdk.GraphServiceClient, listId string) (graphmodels.Subscriptionable, error) {
    changeType := "updated"
    notificationUrl := fmt.Sprintf("%s/webhook/resource-updates", webhookBaseUrl)
    // lifecycleNotificationUrl := fmt.Sprintf("%s/webhook/subscription-lifecycle", webhookBaseUrl)
    resource := fmt.Sprintf("/sites/%v/lists/%v", siteId, listId)
    expirationDateTime := time.Now().Add(time.Hour)
    clientState := "SecretClientState"

    requestBody := graphmodels.NewSubscription()
    requestBody.SetChangeType(&changeType) 
    requestBody.SetNotificationUrl(&notificationUrl) 
    // requestBody.SetLifecycleNotificationUrl(&lifecycleNotificationUrl) 
    requestBody.SetResource(&resource) 
    requestBody.SetExpirationDateTime(&expirationDateTime) 
    requestBody.SetClientState(&clientState) 

    subscription, err := g.Subscriptions().Post(context.Background(), requestBody, nil)
    return subscription, err
}


func main() {
    startWebhook()  // Handles subscription validation; no issues
    graphClient, _ := initializeGraphForUserAuth()
    
    getSubscriptions(graphClient)  // Returns an empty list with subscriptions (expected); no exceptions
    subscription, err := newSubscription(graphClient, listId)
    fmt.Println(">>> ", subscription, err)
    // >>>  <nil> Operation: Create; Exception: [Status Code: Unauthorized; Reason: General exception while processing]
}

Solution

  • Screenshot from tutorial

    Yeah, the application appeared registered under "delegated permissions," whereas creating a Sharepoint list subscription requires an "application subscription."
    https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http#permissions