[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