Closed sadasant closed 3 years ago
Any concerns with subsequent interfaces extending ServiceClientOptions and redeclaring the baseUri
property?
@ramya-rao-a I don’t know of use cases like that. This approach is simpler than others we’ve talked, but it’s less considerate of edge cases. We could have something more automated, like a function on the adapter that gets called on getToken
and lets you replace the scope cc: @chradek
Oh I understood now that you meant if nothing breaks if the baseUri property is re-declared on constructors (I thought you meant late assignments). Testing to be sure!
Any concerns with subsequent interfaces extending ServiceClientOptions and redeclaring the baseUri property?
In our repo there are several instances where ServiceClientOptions is extended and the sub-interface defines baseUri?: string
. This is compatible with the change.
However I did notice that more common that baseUri
was endpoint
. endpoint
is used to help construct the baseUri
for the services that use it (cognitiveservices-entitysearch is an example).
https://github.com/Azure/azure-sdk-for-js/blob/ce2c1f5310bf0e71dbf8bc2b29d5731a9dfd961f/sdk/cognitiveservices/cognitiveservices-entitysearch/src/entitySearchClientContext.ts#L40-L48
super(credentials, options);
this.endpoint = 'https://api.cognitive.microsoft.com';
this.baseUri = "{Endpoint}/bing/v7.0";
this.requestContentType = "application/json; charset=utf-8";
this.credentials = credentials;
if (options.endpoint !== null && options.endpoint !== undefined) {
this.endpoint = options.endpoint;
}
So @sadasant, I don't know if you'll also need to make more changes to support clients that expose endpoint
. With regards to the IdentityAdapter, where does the scope
come from if you don't override it in the constructor?
@chradek In the AzureIdentityCredentialAdapter
(part of this repo) the scope is either the default one, or is assigned at the constructor.
On Identity, the scope is received on each getToken
call, which is why the translation is a bit weird. I think that if we wanted to do something robust that could work for every possible use case, we would allow the adapter to overwrite the constructor scope on getToken. However, since our target audience for this adapter is the generated SDKs, I believe the current approach of this PR to be a reasonable one, since baseUri
is always sent through by the children classes.
Let me know if I’m missing something 🤔
@chradek for the case you presented here: https://github.com/Azure/azure-sdk-for-js/blob/ce2c1f5310bf0e71dbf8bc2b29d5731a9dfd961f/sdk/cognitiveservices/cognitiveservices-entitysearch/src/entitySearchClientContext.ts#L40-L48
I believe that scope is specific to the service version they use. For them, the default scope is likely sufficient, unless they’re working on external clouds.
But to confirm I would need to test it, or speak with somebody owning the cognitive search client. Let me see if I can find someone.
I believe that scope is specific to the service version they use. For them, the default scope is likely sufficient, unless they’re working on external clouds.
For what it's worth, I don't think what cognitive services is doing with endpoint
precludes us from exposing baseUri
.
It's possible that for cognitive services, we'd have to construct the baseUri to pass to the ServiceClient if the user specified a custom endpoint, but we'd need to know what the scopes look like for non-public clouds for those services. But that can be done if needed and I don't think has to be part of this PR.
That is a good catch regarding endpoint in the cognitive services packages @chradek
@chradek for the case you presented here: https://github.com/Azure/azure-sdk-for-js/blob/ce2c1f5310bf0e71dbf8bc2b29d5731a9dfd961f/sdk/cognitiveservices/cognitiveservices-entitysearch/src/entitySearchClientContext.ts#L40-L48
I believe that scope is specific to the service version they use. For them, the default scope is likely sufficient, unless they’re working on external clouds.
@sadasant
I am assuming that by "default scope" you mean https://management.azure.com/.default
.
If so, then that will not work for non management plane packages that use @azure/ms-rest-js
.
I had missed the fact that we have Track 1 data plane auto generated packages when deprioritizing the need for the adapter to respect the baseUri that has been set after the base class ServiceClient is constructed.
For example, I took a quick look at the newer Text Analytics package. Looks like the baseUri is set to the endpoint and then in the core package the /.default
gets added to the baseUri to get the scopes.
Therefore, we need to respect the protected property baseUri in the adapter that gets updated after ServiceClient is constructed even if a customer is using the default Azure cloud.
We have one of two options here
@sadasant
On second thoughts, none of the older autogenerated cognitive services packages support AAD auth. So, one would not be trying to use the credentials from @azure/identity
with any of them. We need to look for other non management plane packages that are auto generated to find a proper repro case :(
@azure/batch
is a good candidate. I have logged https://github.com/Azure/azure-sdk-for-js/issues/16663 to update it to use credentials from @azure/identity
. Once that is done, please work with @deyaaeldeen to test whether the changes done in this PR is enough to use the @azure/batch
package in Azure public cloud
@ramya-rao-a sounds good! thank you!
On another set of second thoughts...
For other Azure clouds, the authority host needs to be set when creating the TokenCredential from @azure/identity
. If the authority host was made a read only property on the credential, then can we not do something like the below in the adapter?
switch (azureTokenCredential.authorityHost) {
case "https://login.chinacloudapi.cn":
this.scopes = "https://management.chinacloudapi.cn/.default"
break;
// and so on for other clouds
default:
break;
}
@deyaaeldeen has been experimenting with the @azure/batch
package and we concluded that we cannot reverse engineer the scope from the baseUri. Therefore, we are going to keep this @azure/identity
support in Track 1 code gen only for the mgmt plane packages. This would mean that us hardcoding the mgmt related scope in the adapter in ms-rest-js is ok as long as we find a way to deal with different clouds. And so comes my suggestion in the previous comment on utilizing the authority host passed to the credential constructor to determine the right scope for mgmt plane packages
@ramya-rao-a Ok I’ll work on a PR for v1
@ramya-rao-a @deyaaeldeen on second thought
From the perspective of Identity, authorityHost does not fully overlap with scopes. Scopes are about what one wants to gain access to, and authorityHost is about who we want to authenticate with.
I think that’s part of the problem on ms-rest-js, baseUri is not a reliable scope for the same reason. It would be better if we could derive the scope during the authentication request, and not at the constructor.
Fair enough
In that case, lets guard the changes in this PR to only take affect if the baseUri matches the ARM scope That way we atleast reduce the scope of this change to something we are sure should be updated.
We have logged https://github.com/Azure/autorest.typescript/issues/1153 to ensure that only the ARM packages get the TokenCredential support in the client constructor so that we don't have to worry what scope to use for data plane packages
I pushed a change that makes it so the baseUri is used as the scope only if it matches the management clouds. Please let me know if there’s anything else I can do!
Another nit: Is the term resource management endpoint
preferred over resource manager endpoints
?
https://github.com/Azure/ms-rest-azure-env/blob/master/lib/azureEnvironment.ts#L271 uses the latter
And official docs refer to the latter as well. See https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview
@ramya-rao-a I think I’ve addressed all the feedback through this commit: https://github.com/Azure/ms-rest-js/pull/457/commits/7224651161fbf7928a08f861a864d5dd34064ac1
Added a new property
baseUri
on theServiceClientOptions
, so that when aTokenCredential
is sent toServiceClient
, it now automatically sets the scope of future token requests based on theoptions.baseUri
property.This should address https://github.com/Azure/azure-sdk-for-js/issues/15945