AzureAD / microsoft-identity-web

Helps creating protected web apps and web APIs with Microsoft identity platform and Azure AD B2C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] Local VS credentials for GraphServiceClient

andrueastman opened this issue · comments

Issue Transfer

This issue has been transferred from the Azure SDK for .NET repository, #44620.

Please be aware that @sanjaydebnath is the author of the original issue and include them for any questions or replies.

Details

Library name and version

Microsoft.Identity.Web 2.19.0
Azure.Identity 1.12.0
Microsoft.Graph 5.56.0

Describe the bug

When we configure authentication in asp.net we can specify to include the default GraphServiceClient object creation by calling AddMicrosoftGraph method. The default token config for GraphServiceClient is picked up from config as documented here.

There is no way in config I could figure that we can mention to use 'VS/VS code credentials' for local environment debugging purpose. You have to mention either certificate or secret for local environments which we want to avoid.

Expected behavior

There should be an easy option to use 'logged in user token' from VS or VS Code inside ClientCredentials so that for local environment you can still use the same config based approach for the default GraphServiceClient. E.g. for our scenario when we deploy inside AKS cluster we use federated credential flow to authenticate, that we can mention by adding source as SignedAssertionFilePath. For web apps we can use SignedAssertionFromManagedIdentity. But for local machine none of these works without using cert/secret. I would expect to have a type for local may be as **VSOBOIdentity**

I am aware of ways to customize the creation of the client, like mentioned here e.g. I can create custom wrapper using below code that will work in AKS or local machine, but that needs unnecessary custom code.

public class GraphService : IGraphService
    {
        private readonly HttpClient _httpClient;
        private readonly GraphOptions _graphOptions;

        public GraphService(IConfiguration configuration)
        {
            var handlers = GraphClientFactory.CreateDefaultHandlers();
            this._httpClient = GraphClientFactory.Create(handlers);
            _graphOptions = configuration.GetSection("Graph").Get<GraphOptions>()!;
        }

        public async Task<AADUser> GatUserGroups(IEnumerable<string> groupIds, string oboToken)
        {
            var onBehalfOfCredential = Debugger.IsAttached
                                                         ? new DefaultAzureCredential()
                                                         : new OnBehalfOfCredential(_graphOptions.TenantId, _graphOptions.ClientId, GetK8ServiceAccountAssertion, oboToken)
            var authProvider = new AzureIdentityAuthenticationProvider(onBehalfOfCredential, scopes: _graphOptions.Scopes);
            var graphServiceClient = new GraphServiceClient(_httpClient, authProvider);
            // ... use graphServiceClient object now and register IGraphService as singleton
            // ... get user groups etc...
        }

       // e.g. documented here: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/samples/OtherCredentialSamples.md#onbehalfofcredential-with-managed-identity-fic-example
       public static Task<string> GetK8ServiceAccountAssertion(CancellationToken cancellationToken)
       {
              // get existing workload assertion and return
       }
    }

Actual behavior

N/A

Reproduction Steps

Enable authentication in code as

builder.Services
    .AddAuthentication()
    .AddMicrosoftIdentityWebApi()
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddMicrosoftGraph()
    .AddDistributedTokenCaches();

In appsettings.json add below config (only kept necessary configs for downstream api call

"AzureAd": {
    "TenantId": "common",
    "ClientId": "...", 
    "Instance": "https://login.microsoftonline.com/",
    "ValidIssuers": [
        "..."
    ],
    "ValidAudiences": [
        "..."
    ],
    "ClientCredentials": [
        {
            "SourceType": "SignedAssertionFilePath",
            "SignedAssertionFileDiskPath": "/var/run/secrets/azure/tokens/azure-identity-token"
        },
        {
            "SourceType": "SignedAssertionFromManagedIdentity",
            "ManagedIdentityClientId": "...."
        },
        {
            "SourceType": "VSOBOIdentity" // does NOT exist today
        }
    ]
}

Environment

No response