Reputation: 5972
I'm trying to get service-to-service authentication working in Azure AD. I have it working when the two services (webapps) are running locally against an Azure AD app registration. But when the webapps are running in Azure (against the same Azure AD app registration), it doesn't work.
I've created two Azure App Service webapps (which are ASP.NET Core Web API projects) - one acting as the client and the other the server. The bit that breaks is the client webapp, where it requests an access token from AzureAD. It only breaks when requested a token with a custom scope. This same 'custom scope' token request works fine from a local webapp though.
In Azure, I've created an 'App Registration', and given it a custom scope called 'bob'...
In the client ASP.NET Core webapi app, I've added the Azure.Identity
nuget package, and am getting a token like this...
var tokenRequestContext = new TokenRequestContext(new[] {scope});
token = await new DefaultAzureCredential().GetTokenAsync(tokenRequestContext, cancellationToken);
(where the scope variable matches the name from the screenshot above)
Locally, this works fine and returns a token.
In Azure, I get this exception:
Azure.Identity.AuthenticationFailedException: DefaultAzureCredential failed to retrieve a token from the included credentials.
- ClientSecretCredential authentication failed: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope api://<guid>/bob is not valid.
(I've removed the GUID from that snippet)
When running this locally and in Azure, I'm setting the AZURE_CLIENT_ID
, AZURE_CLIENT_SECRET
, AZURE_TENANT_ID
environment variables to the same value. I don't understand why it would work differently locally than in Azure, given these environment variables are the same.
Note that my intention is to use a Managed Service Identity instead of setting those environment variables. But for the time being, by using those environment variables both locally and in Azure - both should be using the same "ClientSecretCredential" authentication - so I'd expect the same results.
Upvotes: 6
Views: 23121
Reputation: 6508
There are 2 parts of the answer:
Azure.Identity is currently meant to be ONLY for the native Azure Services SDK using new Azure.* client libraries. In your case, you are trying to use it for your custom web app auth with custom scope which is not officially supported or documented. For regular auth flow (like in this case Client Credential Grant for example) You should be still using MSAL, OR for easier integration with asp.net core apps, Microsoft Identity Web.
NOTE: Specifically for Client Credential Flow, it only allows .default scope. There is an open UserVoice and another thread for workaround.
Now coming to your problem of why it's is not working in Azure.Identity DefaultAzureCredential (regardless of the fact it's not officially supported). I suspect at your deployed Web App, it's probably one or more context missing (IDENTITY_ENDPOINT or AZURE_AUTHORITY_HOST would be my wild guess looking at code). But no idea unless we do little trial and error (again, I would only want to do it for experimental purpose, not in a real production application due to lack of official support). The DefaultAzureCredential
attempts to authenticate via the following mechanisms in order. In your local machine, it might be able to get the required context from one of mechanisms down in the chain (like VS or CLI) whereas in the deployed app, those are simply non-existent.
Upvotes: 8