Azure / autorest

OpenAPI (f.k.a Swagger) Specification code generator. Supports C#, PowerShell, Go, Java, Node.js, TypeScript, Python
MIT License
4.63k stars 739 forks source link

Autorest generated SDK failing to authenticate to Azure using DefaultAzureCredential #4598

Open The-DevBlog opened 2 years ago

The-DevBlog commented 2 years ago

Describe the bug

I am attempting to use AutoRest to generate SDKs for our product (Azure AutoManage) and am facing authentication issues with the DefaultAzureCredential.

I have attempted to use the proposed arm-automanage PR and have also tried using the latest Automanage autorest-api-spec. I am receiving the same errors using both routes.

Tested SDKs:


C# Error

First, I use Autorest to generate an SDK using the autorest-api-spec I mentioned above in the bug description.

autorest --csharp --input-file=.\automanage.json --output-folder=C:\path\to\output\folder\sdk

Then, I create a local console app for testing purposes and add the SDK I generated in the previous step as a project reference.

using Automanage; // autorest generated sdk
using Azure.Identity;

var credential = new DefaultAzureCredential();
var automanageClient = new ConfigurationprofileClient("[subId]", credential);
var profile = await automanageClient.GetConfigurationProfileAsync("[rgName]" "[configProfileName]"); // throws exception

Exception:

[Informational] Azure-Identity: VisualStudioCredential.GetToken was unable to retrieve an access token. Scopes: [ user_impersonation ] 
ParentRequestId: 9920c034-dc2d-4f50-8128-4e9ff550b2e7 Exception: Azure.Identity.CredentialUnavailableException (0x80131500): 
Process "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\Asal\TokenService\Microsoft.Asal.TokenService.exe" has failed 
with unexpected error: TS003: Error, TS007: resource parameter must be a URI or a GUID.

Python Error

First, I use Autorest to generate a Python module using the autorest-api-spec I mentioned above in the bug description.

autorest --python --input-file=.\automanage.json --output-folder=C:\path\to\output\folder\sdk

Then, I create a local console app for testing purposes and import the python module I generated in the previous step.

from azure.identity import DefaultAzureCredential
from sdk import automanage

credential = DefaultAzureCredential()
automanage_client = automanage.Automanage("[sub_id]", credential)
automanage_client.configuration_profiles.get("[profile_name]", "[rg_name]") # throws exception

Exception:

Consent between first party application '[app id]' and first party resource '[resource]' must be configured via preauthorization - 
applications owned and operated by Microsoft must get approval from the API owner before requesting tokens for that API

It appears that something is going wrong with using the DefaultAzureCredential with this Autorest-generated SDK. I know that there is nothing wrong with my current DefaultAzureCredentials as I can use them successfully with other SDKs such as the Azure.Compute SDK.

timotheeguerin commented 2 years ago

Hey @AndrewCS149 this seems like an issue with how you have configured your First Party AAD application. I don't remember the details but I do remember as the error show you need to explicitly approve [app id] to be allowed to use [resource] from the [resource] config.

The-DevBlog commented 2 years ago

@timotheeguerin Thanks for commenting!

I don't believe that would be the actual issue since I am able to interact with my Azure resources using my DefaultAzureCredential with other SDKs such as the Azure Compute SDK. I can successfully create, delete or get VMs for example. It appears to be an issue with the way Autorest is generating the new SDK. Has there been any known issues around Autorest and authenticating to Azure with TokenCredentials?

timotheeguerin commented 2 years ago

There isn't anything that I know of and it seems unlikely that every generated language is not working. Autorest itself doesn't really generate much of the authentication it just consume the azure identity package. Can you make sure you can get a valid token for the service you are trying to authenticate using the identity SDK directly https://docs.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python (python one for example)

The-DevBlog commented 2 years ago

It seems that I can authenticate directly to the Identity SDK.

Heres my working example:

from azure.identity import DefaultAzureCredential
from azure.mgmt.resource import ResourceManagementClient

credential = DefaultAzureCredential()
client = ResourceManagementClient(credential, "[sub_id]")

client.resource_groups.create_or_update("test-rg", {"location": "eastus"})
iscai-msft commented 2 years ago

@AndrewCS149 can you share your generated Python SDK, I wonder if all of the authentication information is being passed during generation time. Thanks!

The-DevBlog commented 2 years ago

Yep! Heres the zip file and the swagger spec file used to generate the sdk

sdk.zip

swagger spec file

The-DevBlog commented 2 years ago

As both @iscai-msft and @timotheeguerin pointed out to me via DMs, I was missing the flag --azure-arm in my Autorest generation command. I was able to generate a Python SDK with this flag included and the SDK worked seamlessly. I'm running into some issues with the other SDKs, so I would love to keep this open until I can resolve those if possible (not sure if they are failing for the same reason or not yet).