Add sample for auxiliary header#35097
Merged
HarveyLink merged 7 commits intoAzure:mainfrom Apr 4, 2023
Merged
Conversation
Member
Author
|
Sample for #26719 |
Collaborator
|
API change check API changes are not detected in this pull request. |
Member
ArcturusZhang
left a comment
There was a problem hiding this comment.
We should not use var in examples. Please use its actual types or proper interfaces as variable types.
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/samples/Sample4_MultiTenant.md
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/Sample4_MultiTenant.cs
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/Sample4_MultiTenant.cs
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/Sample4_MultiTenant.cs
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/AuxiliaryPoilcy.cs
Outdated
Show resolved
Hide resolved
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/Sample4_MultiTenant.cs
Outdated
Show resolved
Hide resolved
…4_MultiTenant.cs Co-authored-by: Dapeng Zhang <ufo54153@gmail.com>
sdk/resourcemanager/Azure.ResourceManager/tests/Samples/AuxiliaryPoilcy.cs
Show resolved
Hide resolved
ArcturusZhang
approved these changes
Apr 4, 2023
MaryGao
added a commit
to Azure/azure-sdk-for-js
that referenced
this pull request
May 10, 2023
### Background Add a policy for external tokens to `x-ms-authorization-auxiliary` header in core lib. This header will be used when creating a cross-tenant application we may need to handle authentication requests for resources that are in different tenants. You can learn [more here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant). Here I collect two use cases: - Create a virtual network peering between virtual networks across tenants ([see here](https://learn.microsoft.com/en-us/azure/virtual-network/create-peering-different-subscriptions?tabs=create-peering-portal#cli)) - Share images across tenants ([see here](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/share-images-across-tenants)) ### Usecase - create a virtual network peering across tenants We have two subscriptions cross two tenants: ``` subscriptionA = "75d6dc7b-9a8d-4f94-81ce-8a9437f3ce2c" in tenantA subscriptionB = "92f95d8f-3c67-4124-91c7-8cf07cdbf241" in tenantB ``` Prepare the app register and grant permission in both subscriptions, please note we'll have one app register with two service principals in two tenants. ``` # Create app registration named `appRegisterB` which allows to be used in any orgnaizational directory located in `tenantB` # Create a service principal for `appRegisterB` in `tenantA` by login url: [https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id={client-id}](https://login.microsoftonline.com/%7Btenant-id%7D/adminconsent?client_id=%7Bclient-id%7D) # Add roles for `appRegisterB` in both `subscriptionA` and `subscriptionB` ``` Prepare the virtual network in both subscriptions: ``` # Switch to subscription A az account set -s $subscriptionA # Create resource group A az group create --name myResourceGroupA --location eastus # Create virtual network A az network vnet create --name myVnetA --resource-group myResourceGroupA --location eastus --address-prefix 10.0.0.0/16 # Switch to subscription B az account set -s $subscriptionB # Create resource group B az group create --name myResourceGroupB --location eastus # Create virtual network B az network vnet create --name myVnetB --resource-group myResourceGroupB --location eastus --address-prefix 10.1.0.0/16 ``` Create a virtual network peering between these two virtual networks. We could build this peer relationship from myVnetA to myVnetB, or from myVnetB to myVnetA. If we build a client under subscriptionB then we could create this peer from myVnetB to myVnetA with below headers: | Header name | Description | Example value | | ----------- | ----------- | ------------ | | Authorization | Primary token, token got from credentialB | Bearer <primary-token> | | x-ms-authorization-auxiliary | Auxiliary tokens, token got from credentialA | Bearer <auxiliary-token1> | ```typescript const tenantA = "c029c2bd-5f77-48fd-b9b8-6dbc7c475125"; const tenantB = "72f988bf-86f1-41af-91ab-2d7cd011db47"; const subscriptionB = "92f95d8f-3c67-4124-91c7-8cf07cdbf241"; const myResourceGroupB = "myResourceGroupB"; const myVnetB = "myVnetB"; const virtualNetworkPeeringName = "myVnetA"; const virtualNetworkPeeringParameters: VirtualNetworkPeering = { allowForwardedTraffic: false, allowGatewayTransit: false, allowVirtualNetworkAccess: true, remoteVirtualNetwork: { id: "/subscriptions/75d6dc7b-9a8d-4f94-81ce-8a9437f3ce2c/resourceGroups/myResourceGroupA/providers/Microsoft.Network/virtualNetworks/myVnetA" }, useRemoteGateways: false }; ``` ### [Preferred] Option 1: Provide an extra policy `auxiliaryAuthenticationHeaderPolicy` Provide a new policy `auxiliaryAuthenticationHeaderPolicy` in core, then customer code could leverage that policy to add auxilary header. ```typescript async function createPeeringWithPolicy() { const credentialA = new DefaultAzureCredential({tenantId: tenantA}); const credentialB = new DefaultAzureCredential({tenantId: tenantB}); const client = new NetworkManagementClient(credentialB, subscriptionB, { // Add the extra policy when building client additionalPolicies: [{ policy: auxiliaryAuthenticationHeaderPolicy({ credentials: [credentialA], scopes: "https://management.core.windows.net//.default" }), position: "perRetry", }] }); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters, ); console.log(result); } ``` ### Option 2: Add `auxiliaryTenants` as a client option Similar the implementation in [Go](Azure/azure-sdk-for-go#19309), we could provide an option in `CommonClientOptions`. ```typescript /** * Auxiliary tenant ids which will be used to get token from */ auxiliaryTenants?: string[]; ``` And then enhance the current bearerTokenAuthenticationPolicy logic to detect if we have the `auxiliaryTenants` provided, if yes we could automatically get tokens and add `x-ms-authorization-auxiliary` header in request. And the customer code would be like: ```typescript async function createPeeringWithParam() { const credential = new ClientSecretCredential(tenantB, env.clientB, env.secretB, { // We would also add allowed tenant list into current credential so that we could get relevant tenant tokens additionallyAllowedTenants: [tenantA] }); const client = new NetworkManagementClient(credential, subscriptionB, { // If the parameter is provided the bearer policy would append the extra header auxiliaryTenants: [tenantA] }); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters ); console.log(result); } ``` ### Option 3: Add `auxiliaryCredentials` option in BearerTokenAuthenticationPolicyOptions Instead of providing new policy we could add a new option in `BearerTokenAuthenticationPolicyOptions` in original bearerTokenAuthenticationPolicy. Then in that policy we could detect if the parameter `auxiliaryCredentials` is provided, if yes append the header accordingly. ```typescript /** * Provide the auxiliary credentials to get tokens in header x-ms-authorization-auxiliary */ auxiliaryCredentials: TokenCredential[]; ``` But it would be more complex from customer side, because we add bearer policy by default so we have to remove that one first and then re-add a new one. ```typescript async function createPeeringWithNewBearerPolicy() { const credentialA = new ClientSecretCredential(tenantA, clientB, secretB); const credentialB = new ClientSecretCredential(tenantB, clientB, secretB); const client = new NetworkManagementClient(credentialB, subscriptionB); // Build a new policy with auxiliaryCredentials provide const customizedBearerPolicy = bearerTokenAuthenticationPolicy({ credential: credentialB, scopes: "https://management.core.windows.net//.default", auxiliaryCredentials: [credentialA] }); // Remove the original one client.pipeline.removePolicy({ name: bearerTokenAuthenticationPolicyName }); // Add our new policy client.pipeline.addPolicy(customizedBearerPolicy); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters ); console.log(result); } ``` Simply speaking I prefer the option 1, you could know more [here](#25270 (comment)). ### Reference Java: Azure/azure-sdk-for-java#14336 Python: Azure/azure-sdk-for-python#24585 Go: Azure/azure-sdk-for-go#19309 .Net: Azure/azure-sdk-for-net#35097 // Only add sample, didn't implement in core --------- Co-authored-by: Jeff Fisher <xirzec@xirzec.com>
minhanh-phan
pushed a commit
to minhanh-phan/azure-sdk-for-js
that referenced
this pull request
Jun 12, 2023
) ### Background Add a policy for external tokens to `x-ms-authorization-auxiliary` header in core lib. This header will be used when creating a cross-tenant application we may need to handle authentication requests for resources that are in different tenants. You can learn [more here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant). Here I collect two use cases: - Create a virtual network peering between virtual networks across tenants ([see here](https://learn.microsoft.com/en-us/azure/virtual-network/create-peering-different-subscriptions?tabs=create-peering-portal#cli)) - Share images across tenants ([see here](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/share-images-across-tenants)) ### Usecase - create a virtual network peering across tenants We have two subscriptions cross two tenants: ``` subscriptionA = "75d6dc7b-9a8d-4f94-81ce-8a9437f3ce2c" in tenantA subscriptionB = "92f95d8f-3c67-4124-91c7-8cf07cdbf241" in tenantB ``` Prepare the app register and grant permission in both subscriptions, please note we'll have one app register with two service principals in two tenants. ``` # Create app registration named `appRegisterB` which allows to be used in any orgnaizational directory located in `tenantB` # Create a service principal for `appRegisterB` in `tenantA` by login url: [https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id={client-id}](https://login.microsoftonline.com/%7Btenant-id%7D/adminconsent?client_id=%7Bclient-id%7D) # Add roles for `appRegisterB` in both `subscriptionA` and `subscriptionB` ``` Prepare the virtual network in both subscriptions: ``` # Switch to subscription A az account set -s $subscriptionA # Create resource group A az group create --name myResourceGroupA --location eastus # Create virtual network A az network vnet create --name myVnetA --resource-group myResourceGroupA --location eastus --address-prefix 10.0.0.0/16 # Switch to subscription B az account set -s $subscriptionB # Create resource group B az group create --name myResourceGroupB --location eastus # Create virtual network B az network vnet create --name myVnetB --resource-group myResourceGroupB --location eastus --address-prefix 10.1.0.0/16 ``` Create a virtual network peering between these two virtual networks. We could build this peer relationship from myVnetA to myVnetB, or from myVnetB to myVnetA. If we build a client under subscriptionB then we could create this peer from myVnetB to myVnetA with below headers: | Header name | Description | Example value | | ----------- | ----------- | ------------ | | Authorization | Primary token, token got from credentialB | Bearer <primary-token> | | x-ms-authorization-auxiliary | Auxiliary tokens, token got from credentialA | Bearer <auxiliary-token1> | ```typescript const tenantA = "c029c2bd-5f77-48fd-b9b8-6dbc7c475125"; const tenantB = "72f988bf-86f1-41af-91ab-2d7cd011db47"; const subscriptionB = "92f95d8f-3c67-4124-91c7-8cf07cdbf241"; const myResourceGroupB = "myResourceGroupB"; const myVnetB = "myVnetB"; const virtualNetworkPeeringName = "myVnetA"; const virtualNetworkPeeringParameters: VirtualNetworkPeering = { allowForwardedTraffic: false, allowGatewayTransit: false, allowVirtualNetworkAccess: true, remoteVirtualNetwork: { id: "/subscriptions/75d6dc7b-9a8d-4f94-81ce-8a9437f3ce2c/resourceGroups/myResourceGroupA/providers/Microsoft.Network/virtualNetworks/myVnetA" }, useRemoteGateways: false }; ``` ### [Preferred] Option 1: Provide an extra policy `auxiliaryAuthenticationHeaderPolicy` Provide a new policy `auxiliaryAuthenticationHeaderPolicy` in core, then customer code could leverage that policy to add auxilary header. ```typescript async function createPeeringWithPolicy() { const credentialA = new DefaultAzureCredential({tenantId: tenantA}); const credentialB = new DefaultAzureCredential({tenantId: tenantB}); const client = new NetworkManagementClient(credentialB, subscriptionB, { // Add the extra policy when building client additionalPolicies: [{ policy: auxiliaryAuthenticationHeaderPolicy({ credentials: [credentialA], scopes: "https://management.core.windows.net//.default" }), position: "perRetry", }] }); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters, ); console.log(result); } ``` ### Option 2: Add `auxiliaryTenants` as a client option Similar the implementation in [Go](Azure/azure-sdk-for-go#19309), we could provide an option in `CommonClientOptions`. ```typescript /** * Auxiliary tenant ids which will be used to get token from */ auxiliaryTenants?: string[]; ``` And then enhance the current bearerTokenAuthenticationPolicy logic to detect if we have the `auxiliaryTenants` provided, if yes we could automatically get tokens and add `x-ms-authorization-auxiliary` header in request. And the customer code would be like: ```typescript async function createPeeringWithParam() { const credential = new ClientSecretCredential(tenantB, env.clientB, env.secretB, { // We would also add allowed tenant list into current credential so that we could get relevant tenant tokens additionallyAllowedTenants: [tenantA] }); const client = new NetworkManagementClient(credential, subscriptionB, { // If the parameter is provided the bearer policy would append the extra header auxiliaryTenants: [tenantA] }); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters ); console.log(result); } ``` ### Option 3: Add `auxiliaryCredentials` option in BearerTokenAuthenticationPolicyOptions Instead of providing new policy we could add a new option in `BearerTokenAuthenticationPolicyOptions` in original bearerTokenAuthenticationPolicy. Then in that policy we could detect if the parameter `auxiliaryCredentials` is provided, if yes append the header accordingly. ```typescript /** * Provide the auxiliary credentials to get tokens in header x-ms-authorization-auxiliary */ auxiliaryCredentials: TokenCredential[]; ``` But it would be more complex from customer side, because we add bearer policy by default so we have to remove that one first and then re-add a new one. ```typescript async function createPeeringWithNewBearerPolicy() { const credentialA = new ClientSecretCredential(tenantA, clientB, secretB); const credentialB = new ClientSecretCredential(tenantB, clientB, secretB); const client = new NetworkManagementClient(credentialB, subscriptionB); // Build a new policy with auxiliaryCredentials provide const customizedBearerPolicy = bearerTokenAuthenticationPolicy({ credential: credentialB, scopes: "https://management.core.windows.net//.default", auxiliaryCredentials: [credentialA] }); // Remove the original one client.pipeline.removePolicy({ name: bearerTokenAuthenticationPolicyName }); // Add our new policy client.pipeline.addPolicy(customizedBearerPolicy); const result = await client.virtualNetworkPeerings.beginCreateOrUpdateAndWait( myResourceGroupB, myVnetB, virtualNetworkPeeringName, virtualNetworkPeeringParameters ); console.log(result); } ``` Simply speaking I prefer the option 1, you could know more [here](Azure#25270 (comment)). ### Reference Java: Azure/azure-sdk-for-java#14336 Python: Azure/azure-sdk-for-python#24585 Go: Azure/azure-sdk-for-go#19309 .Net: Azure/azure-sdk-for-net#35097 // Only add sample, didn't implement in core --------- Co-authored-by: Jeff Fisher <xirzec@xirzec.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contributing to the Azure SDK
Please see our CONTRIBUTING.md if you are not familiar with contributing to this repository or have questions.
For specific information about pull request etiquette and best practices, see this section.