azuregooauth-2.0microsoft-graph-apiazure-ad-msal

Is it possible to use delegated access with a confidential client, in the Microsoft Authentication Library?


When I use a client secret authentication flow with a confidential client, how could I authenticate a user (one that connects as an HTTP client to my website, or any other method of network access) and use delegated access?

I understand how to do so with a public client. I could also use a public client flow on this server, but that would make little sense as my server should technically be a confidential client.

Minimal working example (if "MY.\{-}" is replaced with valid a valid set of client secret, client ID, and tenant ID):

package main

import (
        "context"
        "fmt"

        "github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)

func main() {
        cred, err := confidential.NewCredFromSecret("MY_CLIENT_SECRET")
        if err != nil {
                panic(err)
        }

        confidential_client, err := confidential.New(
                "https://login.microsoftonline.com/"+"MY_TENANT_ID",
                "MY_CLIENT_ID",
                cred,
        )
        if err != nil {
                panic(err)
        }

        result, err := confidential_client.AcquireTokenByCredential(
                context.Background(),
                []string{"User.Read"},
        )
        if err != nil {
                panic(err)
        }

        fmt.Println(result)
}

Results:

{
        "error": "invalid_scope",
        "error_description": "AADSTS1002012: The provided value for scope User.
Read openid offline_access profile is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI). Trace ID: REDACTED Correlation ID: REDACTED Timestamp: 2024-08-16 03:46:42Z",
        "error_codes": [1002012],
        "timestamp": "2024-08-16 03:46:42Z",
        "trace_id": "REDACTED",
        "correlation_id":"REDACTED" 
}

Solution

  • Note that: Confidential client only works with Application type API permissions and with no user interaction involved.

    For sample, I tried to generate token via postman and got the same error as you:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
    
    client_id:ClientID
    client_secret:ClientSecret
    scope↵:https://graph.microsoft.com/.default
    grant_type:client_credentials
    

    enter image description here

    The error "The provided value for scope User.Read is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI)" usually occurs if the scope while using Confidential client is not suffixed by /.default. To resolve the error use https://graph.microsoft.com/.default

    Confidential client doesn't suit your scenario as you want to pass scope as User.Read and do not want to pass client secret you can make use of public client flow.