Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5d0038c
[Identity] Adding AdditionallyAllowedTenants to constrain multi-tenan…
schaabs Aug 29, 2022
aaa4257
updating API spec
schaabs Aug 29, 2022
fdb98b1
adding dev-time credentials
schaabs Sep 7, 2022
3b64be6
adding user-auth credentials
schaabs Sep 7, 2022
57d6d1d
refactor additional tenants to base options
schaabs Sep 7, 2022
11a7298
adding default and environment credentials
schaabs Sep 7, 2022
8740be7
update/add tests
schaabs Sep 12, 2022
53ac2ff
update API spec
schaabs Sep 12, 2022
aad7710
update changelog and breaking_changes
schaabs Sep 12, 2022
8c00cd9
update assembly version
schaabs Sep 12, 2022
d651a03
Update sdk/identity/Azure.Identity/CHANGELOG.md
schaabs Sep 12, 2022
4663156
Update sdk/identity/Azure.Identity/CHANGELOG.md
schaabs Sep 12, 2022
1758a66
Update sdk/identity/Azure.Identity/src/Credentials/AuthorizationCodeC…
schaabs Sep 12, 2022
cf3f51d
Update sdk/identity/Azure.Identity/src/TenantIdResolver.cs
schaabs Sep 12, 2022
c70f042
Update sdk/identity/Azure.Identity/CHANGELOG.md
schaabs Sep 13, 2022
da48964
fb
schaabs Sep 14, 2022
8da2477
fb
schaabs Sep 14, 2022
2d90793
fb
schaabs Sep 14, 2022
b2a4235
fb
schaabs Sep 14, 2022
938f72c
fb
schaabs Sep 14, 2022
c0f2e4f
Update sdk/identity/Azure.Identity/src/Credentials/VisualStudioCreden…
schaabs Sep 14, 2022
a6208e9
Update sdk/identity/Azure.Identity/src/Credentials/ClientAssertionCre…
schaabs Sep 14, 2022
39a8ce8
Update sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCre…
schaabs Sep 14, 2022
038769f
Update sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCre…
schaabs Sep 14, 2022
98eb043
Update sdk/identity/Azure.Identity/src/Credentials/AzureCliCredential…
schaabs Sep 14, 2022
70dee65
Update sdk/identity/Azure.Identity/CHANGELOG.md
schaabs Sep 14, 2022
a9044bb
Update sdk/identity/Azure.Identity/src/Credentials/VisualStudioCreden…
schaabs Sep 14, 2022
507850e
Update sdk/identity/Azure.Identity/src/Credentials/VisualStudioCodeCr…
schaabs Sep 14, 2022
59cefbe
Update sdk/identity/Azure.Identity/src/Credentials/VisualStudioCodeCr…
schaabs Sep 14, 2022
a51788a
Update sdk/identity/Azure.Identity/src/Credentials/TokenCredentialOpt…
schaabs Sep 14, 2022
6b00e60
Update sdk/identity/Azure.Identity/src/Credentials/UsernamePasswordCr…
schaabs Sep 14, 2022
f62d4e7
Update sdk/identity/Azure.Identity/src/Credentials/OnBehalfOfCredenti…
schaabs Sep 14, 2022
f68371c
Update sdk/identity/Azure.Identity/src/Credentials/InteractiveBrowser…
schaabs Sep 14, 2022
c4f277f
Update sdk/identity/Azure.Identity/src/Credentials/DeviceCodeCredenti…
schaabs Sep 14, 2022
ced25a0
Update sdk/identity/Azure.Identity/src/Credentials/DefaultAzureCreden…
schaabs Sep 14, 2022
a0add20
Update sdk/identity/Azure.Identity/src/Credentials/DefaultAzureCreden…
schaabs Sep 14, 2022
a2df13b
Update sdk/identity/Azure.Identity/src/Credentials/DefaultAzureCreden…
schaabs Sep 14, 2022
d428fab
Update sdk/identity/Azure.Identity/src/Credentials/ClientSecretCreden…
schaabs Sep 14, 2022
74f50d7
Update sdk/identity/Azure.Identity/src/Credentials/ClientCertificateC…
schaabs Sep 14, 2022
48a3b9e
updating troubleshooting.md
schaabs Sep 14, 2022
c62ad15
Merge branch 'feature/additionaltenants' of https://github.com/schaab…
schaabs Sep 14, 2022
8bf00bd
update snippets
schaabs Sep 14, 2022
287bd02
undo snippet indent
schaabs Sep 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions sdk/identity/Azure.Identity/BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# Breaking Changes

## 1.7.0

### Behavioral change to credential types supporting multi-tenant authentication

As of `Azure.Identity` 1.7.0, the default behavior of credentials supporting multi-tenant authentication has changed. Each of these credentials will throw an `AuthenticationFailedException` if the requested `TenantId` doesn't match the tenant ID originally configured on the credential. Apps must now do one of the following things:

- Add all IDs, of tenants from which tokens should be acquired, to the `AdditionallyAllowedTenants` list in the credential options. For example:

```C# Snippet:Identity_BreakingChanges_AddExplicitAdditionallyAllowedTenants
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
AdditionallyAllowedTenants = { "<tenant_id_1>", "<tenant_id_2>" }
});
```

- Add `*` to enable token acquisition from any tenant. This is the original behavior and is compatible with versions 1.5.0 through 1.6.1. For example:

```C# Snippet:Identity_BreakingChanges_AddAllAdditionallyAllowedTenants
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
AdditionallyAllowedTenants = { "*" }
});
```

Note: Credential types which do not require a `TenantId` on construction will only throw `AuthenticationFailedException` when the application has provided a value for `TenantId` either in the options or via a constructor overload. If no `TenantId` is specified when constructing the credential, the credential will acquire tokens for any requested `TenantId` regardless of the value of `AdditionallyAllowedTenants`.

## 1.4.0

### Changed `ExcludeSharedTokenCacheCredential` default value from __false__ to __true__ on `DefaultAzureCredentialsOptions`
Expand Down
25 changes: 25 additions & 0 deletions sdk/identity/Azure.Identity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Release History

## 1.7.0 (2022-09-13)

### Features Added
- Added `AdditionallyAllowedTenants` to the following credential options to force explicit opt-in behavior for multi-tenant authentication:
- `AuthorizationCodeCredentialOptions`
- `AzureCliCredentialOptions`
- `AzurePowerShellCredentialOptions`
- `ClientAssertionCredentialOptions`
- `ClientCertificateCredentialOptions`
- `ClientSecretCredentialOptions`
- `DefaultAzureCredentialOptions`
- `OnBehalfOfCredentialOptions`
- `UsernamePasswordCredentialOptions`
- `VisualStudioCodeCredentialOptions`
- `VisualStudioCredentialOptions`
- Added `TenantId` to `DefaultAzureCredentialOptions` to avoid having to set `InteractiveBrowserTenantId`, `SharedTokenCacheTenantId`, `VisualStudioCodeTenantId`, and `VisualStudioTenantId` individually.

### Breaking Changes
- Credential types supporting multi-tenant authentication will now throw `AuthenticationFailedException` if the requested tenant ID doesn't match the credential's tenant ID, and is not included in the `AdditionallyAllowedTenants` option. Applications must now explicitly add additional tenants to the `AdditionallyAllowedTenants` list, or add '*' to list, to enable acquiring tokens from tenants other than the originally specified tenant ID. See [BREAKING_CHANGES.md](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/BREAKING_CHANGES.md#170).

## 1.7.0-beta.1 (2022-08-09)

### Features Added
- `ManagedIdentityCredential` will now internally cache tokens. Apps can call `GetToken` or `GetTokenAsync` directly without needing to cache to avoid throttling.

## 1.6.1 (2022-08-08)

### Bugs Fixed
Expand Down
8 changes: 8 additions & 0 deletions sdk/identity/Azure.Identity/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This troubleshooting guide covers failure investigation techniques, common error
- [Troubleshoot VisualStudioCredential Authentication Issues](#troubleshoot-visualstudiocredential-authenticaton-issues)
- [Troubleshoot AzureCliCredential Authentication Issues](#troubleshoot-azureclicredential-authentication-issues)
- [Troubleshoot AzurePowerShellCredential Authentication Issues](#troubleshoot-azurepowershellcredential-authentication-issues)
- [Troubleshoot Multi Tenant Authentication Issues](#troubleshoot-multi-tenant-authentication-issues)
- [Get Additional Help](#get-additional-help)

## Handle Azure Identity Exceptions
Expand Down Expand Up @@ -246,6 +247,13 @@ Get-AzAccessToken -ResourceUrl "https://management.core.windows.net"
```
>Note that output of this command will contain a valid access token, and SHOULD NOT BE SHARED to avoid compromising account security.

## Troubleshoot Multi Tenant Authentication Issues
`AuthenticationFailedException`

| Error Message |Description| Mitigation |
|---|---|---|
|The current credential is not configured to acquire tokens for tenant <tenant ID>|The application must configure the credential to allow acquiring tokens from the requested tenant.|Add the requested tenant ID it to the AdditionallyAllowedTenants on the credential options, or add \"*\" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant.</p>This exception was added as part of functional a breaking change to multi tenant authentication in version `1.7.0`. Users experiencing this error after upgrading can find details on the change and migration in [BREAKING_CHANGES.md](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/BREAKING_CHANGES.md#170) |

## Get Additional Help

Additional information on ways to reach out for support can be found in the [SUPPORT.md](https://github.com/Azure/azure-sdk-for-net/blob/main/SUPPORT.md) at the root of the repo.
18 changes: 18 additions & 0 deletions sdk/identity/Azure.Identity/api/Azure.Identity.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public AuthorizationCodeCredential(string tenantId, string clientId, string clie
public partial class AuthorizationCodeCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public AuthorizationCodeCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public System.Uri RedirectUri { get { throw null; } set { } }
}
public static partial class AzureAuthorityHosts
Expand All @@ -58,6 +59,7 @@ public AzureCliCredential(Azure.Identity.AzureCliCredentialOptions options) { }
public partial class AzureCliCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public AzureCliCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public string TenantId { get { throw null; } set { } }
}
public partial class AzurePowerShellCredential : Azure.Core.TokenCredential
Expand All @@ -70,6 +72,7 @@ public AzurePowerShellCredential(Azure.Identity.AzurePowerShellCredentialOptions
public partial class AzurePowerShellCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public AzurePowerShellCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public string TenantId { get { throw null; } set { } }
}
public partial class ChainedTokenCredential : Azure.Core.TokenCredential
Expand All @@ -89,6 +92,7 @@ public ClientAssertionCredential(string tenantId, string clientId, System.Func<S
public partial class ClientAssertionCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public ClientAssertionCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
}
public partial class ClientCertificateCredential : Azure.Core.TokenCredential
{
Expand All @@ -105,6 +109,7 @@ public ClientCertificateCredential(string tenantId, string clientId, string clie
public partial class ClientCertificateCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public ClientCertificateCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public bool SendCertificateChain { get { throw null; } set { } }
public Azure.Identity.TokenCachePersistenceOptions TokenCachePersistenceOptions { get { throw null; } set { } }
}
Expand All @@ -120,6 +125,7 @@ public ClientSecretCredential(string tenantId, string clientId, string clientSec
public partial class ClientSecretCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public ClientSecretCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public Azure.Identity.TokenCachePersistenceOptions TokenCachePersistenceOptions { get { throw null; } set { } }
}
public partial class CredentialUnavailableException : Azure.Identity.AuthenticationFailedException
Expand All @@ -138,6 +144,7 @@ public DefaultAzureCredential(bool includeInteractiveCredentials = false) { }
public partial class DefaultAzureCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public DefaultAzureCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public bool ExcludeAzureCliCredential { get { throw null; } set { } }
public bool ExcludeAzurePowerShellCredential { get { throw null; } set { } }
public bool ExcludeEnvironmentCredential { get { throw null; } set { } }
Expand All @@ -147,12 +154,17 @@ public DefaultAzureCredentialOptions() { }
public bool ExcludeVisualStudioCodeCredential { get { throw null; } set { } }
public bool ExcludeVisualStudioCredential { get { throw null; } set { } }
public string InteractiveBrowserCredentialClientId { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public string InteractiveBrowserTenantId { get { throw null; } set { } }
public string ManagedIdentityClientId { get { throw null; } set { } }
public Azure.Core.ResourceIdentifier ManagedIdentityResourceId { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public string SharedTokenCacheTenantId { get { throw null; } set { } }
public string SharedTokenCacheUsername { get { throw null; } set { } }
public string TenantId { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public string VisualStudioCodeTenantId { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public string VisualStudioTenantId { get { throw null; } set { } }
}
public partial class DeviceCodeCredential : Azure.Core.TokenCredential
Expand All @@ -173,6 +185,7 @@ public DeviceCodeCredential(System.Func<Azure.Identity.DeviceCodeInfo, System.Th
public partial class DeviceCodeCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public DeviceCodeCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public Azure.Identity.AuthenticationRecord AuthenticationRecord { get { throw null; } set { } }
public string ClientId { get { throw null; } set { } }
public System.Func<Azure.Identity.DeviceCodeInfo, System.Threading.CancellationToken, System.Threading.Tasks.Task> DeviceCodeCallback { get { throw null; } set { } }
Expand Down Expand Up @@ -223,6 +236,7 @@ public InteractiveBrowserCredential(string tenantId, string clientId, Azure.Iden
public partial class InteractiveBrowserCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public InteractiveBrowserCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public Azure.Identity.AuthenticationRecord AuthenticationRecord { get { throw null; } set { } }
public string ClientId { get { throw null; } set { } }
public bool DisableAutomaticAuthentication { get { throw null; } set { } }
Expand Down Expand Up @@ -252,6 +266,7 @@ public OnBehalfOfCredential(string tenantId, string clientId, string clientSecre
public partial class OnBehalfOfCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public OnBehalfOfCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public bool SendCertificateChain { get { throw null; } set { } }
public Azure.Identity.TokenCachePersistenceOptions TokenCachePersistenceOptions { get { throw null; } set { } }
}
Expand Down Expand Up @@ -333,6 +348,7 @@ public UsernamePasswordCredential(string username, string password, string tenan
public partial class UsernamePasswordCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public UsernamePasswordCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public Azure.Identity.TokenCachePersistenceOptions TokenCachePersistenceOptions { get { throw null; } set { } }
}
public partial class VisualStudioCodeCredential : Azure.Core.TokenCredential
Expand All @@ -345,6 +361,7 @@ public VisualStudioCodeCredential(Azure.Identity.VisualStudioCodeCredentialOptio
public partial class VisualStudioCodeCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public VisualStudioCodeCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public string TenantId { get { throw null; } set { } }
}
public partial class VisualStudioCredential : Azure.Core.TokenCredential
Expand All @@ -357,6 +374,7 @@ public VisualStudioCredential(Azure.Identity.VisualStudioCredentialOptions optio
public partial class VisualStudioCredentialOptions : Azure.Identity.TokenCredentialOptions
{
public VisualStudioCredentialOptions() { }
public System.Collections.Generic.IList<string> AdditionallyAllowedTenants { get { throw null; } }
public string TenantId { get { throw null; } set { } }
}
}
4 changes: 2 additions & 2 deletions sdk/identity/Azure.Identity/src/Azure.Identity.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<PropertyGroup>
<Description>This is the implementation of the Azure SDK Client Library for Azure Identity</Description>
<AssemblyTitle>Microsoft Azure.Identity Component</AssemblyTitle>
<Version>1.6.1</Version>
<Version>1.7.0</Version>
<!--The ApiCompatVersion is managed automatically and should not generally be modified manually.-->
<ApiCompatVersion>1.6.0</ApiCompatVersion>
<ApiCompatVersion>1.6.1</ApiCompatVersion>
<PackageTags>Microsoft Azure Identity;$(PackageCommonTags)</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<NoWarn>$(NoWarn);3021;AZC0011</NoWarn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
Expand All @@ -25,6 +26,7 @@ public class AuthorizationCodeCredential : TokenCredential
private readonly MsalConfidentialClient _client;
private readonly string _redirectUri;
private readonly string _tenantId;
private readonly string[] _additionallyAllowedTenantIds;

/// <summary>
/// Protected constructor for mocking.
Expand Down Expand Up @@ -101,6 +103,8 @@ internal AuthorizationCodeCredential(string tenantId, string clientId, string cl
clientSecret,
_redirectUri,
options);

_additionallyAllowedTenantIds = TenantIdResolver.ResolveAddionallyAllowedTenantIds(options?.AdditionallyAllowedTenantsCore);
}

/// <summary>
Expand Down Expand Up @@ -134,7 +138,7 @@ private async ValueTask<AccessToken> GetTokenImplAsync(bool async, TokenRequestC
try
{
AccessToken token;
var tenantId = TenantIdResolver.Resolve(_tenantId, requestContext);
var tenantId = TenantIdResolver.Resolve(_tenantId, requestContext, _additionallyAllowedTenantIds);

if (_record is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT License.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
Expand All @@ -20,5 +22,10 @@ public class AuthorizationCodeCredentialOptions : TokenCredentialOptions
/// The redirect Uri that will be sent with the GetToken request.
/// </summary>
public Uri RedirectUri { get; set; }

/// <summary>
/// For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens. Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the application is installed.
/// </summary>
public IList<string> AdditionallyAllowedTenants => AdditionallyAllowedTenantsCore;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ public class AzureCliCredential : TokenCredential

private readonly CredentialPipeline _pipeline;
private readonly IProcessService _processService;
private readonly string _tenantId;
private readonly bool _logPII;
private readonly bool _logAccountDetails;
internal string TenantId { get; }
internal string[] AdditionallyAllowedTenantIds { get; }

/// <summary>
/// Create an instance of CliCredential class.
Expand All @@ -72,7 +73,8 @@ internal AzureCliCredential(CredentialPipeline pipeline, IProcessService process
_pipeline = pipeline;
_path = !string.IsNullOrEmpty(EnvironmentVariables.Path) ? EnvironmentVariables.Path : DefaultPath;
_processService = processService ?? ProcessService.Default;
_tenantId = options?.TenantId;
TenantId = options?.TenantId;
AdditionallyAllowedTenantIds = TenantIdResolver.ResolveAddionallyAllowedTenantIds(options?.AdditionallyAllowedTenantsCore);
}

/// <summary>
Expand Down Expand Up @@ -115,7 +117,7 @@ private async ValueTask<AccessToken> GetTokenImplAsync(bool async, TokenRequestC
private async ValueTask<AccessToken> RequestCliAccessTokenAsync(bool async, TokenRequestContext context, CancellationToken cancellationToken)
{
string resource = ScopeUtilities.ScopesToResource(context.Scopes);
string tenantId = TenantIdResolver.Resolve(_tenantId, context);
string tenantId = TenantIdResolver.Resolve(TenantId, context, AdditionallyAllowedTenantIds);

ScopeUtilities.ValidateScope(resource);

Expand Down Expand Up @@ -167,7 +169,7 @@ private async ValueTask<AccessToken> RequestCliAccessTokenAsync(bool async, Toke
if (_logAccountDetails)
{
var accountDetails = TokenHelper.ParseAccountInfoFromToken(token.Token);
AzureIdentityEventSource.Singleton.AuthenticatedAccountDetails(accountDetails.ClientId, accountDetails.TenantId ?? _tenantId, accountDetails.Upn, accountDetails.ObjectId);
AzureIdentityEventSource.Singleton.AuthenticatedAccountDetails(accountDetails.ClientId, accountDetails.TenantId ?? TenantId, accountDetails.Upn, accountDetails.ObjectId);
}

return token;
Expand Down
Loading