Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
28 changes: 27 additions & 1 deletion sdk/identity/Azure.Identity/BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,30 @@ var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
});
```

More information on this change and the consideration behind it can be found [here](https://github.com/Azure/azure-sdk/issues/1970).
More information on this change and the consideration behind it can be found [here](https://github.com/Azure/azure-sdk/issues/1970).

## 1.7.0

### Changed Credential types supporting multi-tenant authentication to throw `AuthenticationFailedException` if the requested tenant id doesn't match the tenant id of the credential, and is not included in the `AdditionallyAllowedTenants` option.

Starting in Azure.Identity 1.7.0 the default behavior of credentials supporting multi-tenant authentication will be to throw a `AuthenticationFailedExcpetion` if the requested `TenantId` doesn't match the tenant id originally configured on the credential. Applications must now either explicitly add all expected tenant ids to the `AdditionallyAllowedTenants` list in the credential options, or add "*" to enable acquiring tokens from any tenant (the original behavior).

This is an example of explicitly adding tenants to allow acquiring tokens.

```C# Snippet:Identity_BreakingChanges_AddExplicitAdditionallyAllowedTenants
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
AdditionallyAllowedTenants = { "0000-0000-0000-0000", "1111-1111-1111-1111" }
});
```

Here is an example of using the wildcard to enable acquiring tokens from any tenant, to be compatible with versions 1.5.0 through 1.6.1.

```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`.
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 tenant id of the credential, and is not included in the `AdditionallyAllowedTenants` option. Applications must now explicitly add additional tenents 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, so applications can call `GetToken` and `GetTokenAsync` directly without needing to cache to avoid throttleling.

## 1.6.1 (2022-08-08)

### Bugs Fixed
Expand Down
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 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
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;

namespace Azure.Identity
{
/// <summary>
Expand All @@ -9,8 +11,15 @@ namespace Azure.Identity
public class AzureCliCredentialOptions : TokenCredentialOptions
{
/// <summary>
/// The Azure Active Directory tenant (directory) Id of the service principal
/// The tenant ID the credential will authenticate to by default. If not specified the credential will authenticate to any requested tenant, and will default to the tenant specified to the 'az login' command.
/// </summary>
public string TenantId { get; set; }

/// <summary>
/// Specifies tenants in addition to the specified <see cref="TenantId"/> for which the credential may acquire tokens.
/// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant the logged in account can access.
/// If no value is specified for <see cref="TenantId"/> this option will have no effect, and the credential will acquire tokens for any requested tenant.
/// </summary>
public IList<string> AdditionallyAllowedTenants => AdditionallyAllowedTenantsCore;
}
}
Loading