diff --git a/.gitmodules b/.gitmodules index 8cdc33c02ec..7e13bf3d635 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,7 @@ path = autorest.powershell url = https://github.com/microsoftgraph/autorest.powershell branch = powershell_v2 +[submodule "azure-sdk-for-net"] + path = azure-sdk-for-net + url = https://github.com/Ndiritu/azure-sdk-for-net.git + branch = feat/extra-query-params diff --git a/azure-sdk-for-net b/azure-sdk-for-net new file mode 160000 index 00000000000..bf7d0ff8590 --- /dev/null +++ b/azure-sdk-for-net @@ -0,0 +1 @@ +Subproject commit bf7d0ff85902cbf1b47c411e3a338b19338eec39 diff --git a/config/ModuleMetadata.json b/config/ModuleMetadata.json index 02226b27a3b..81e50c37af7 100644 --- a/config/ModuleMetadata.json +++ b/config/ModuleMetadata.json @@ -26,16 +26,16 @@ ], "versions": { "authentication": { - "prerelease": "", - "version": "2.19.0" + "prerelease": "preview2", + "version": "2.22.0" }, "beta": { - "prerelease": "", - "version": "2.19.0" + "prerelease": "preview2", + "version": "2.22.0" }, "v1.0": { - "prerelease": "", - "version": "2.19.0" + "prerelease": "preview2", + "version": "2.22.0" } } } diff --git a/src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs b/src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs index d7060de2a46..bfaaf206e0f 100644 --- a/src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs +++ b/src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs @@ -52,5 +52,6 @@ public interface IAuthContext ContextScope ContextScope { get; set; } Version PSHostVersion { get; set; } SecureString ClientSecret { get; set; } + string SubClaim { get; set; } } } \ No newline at end of file diff --git a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj index c385a4f63ae..d11ec0a78f5 100644 --- a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj +++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj @@ -4,14 +4,15 @@ 9.0 netstandard2.0;net6.0;net472 Microsoft.Graph.PowerShell.Authentication.Core - 2.18.0 + 2.22.0 + preview2 true true - + diff --git a/src/Authentication/Authentication.Core/Models/JwtPayload.cs b/src/Authentication/Authentication.Core/Models/JwtPayload.cs index a439981875d..f9c3de588b4 100644 --- a/src/Authentication/Authentication.Core/Models/JwtPayload.cs +++ b/src/Authentication/Authentication.Core/Models/JwtPayload.cs @@ -50,5 +50,8 @@ internal partial class JwtPayload [JsonPropertyName("upn")] public string Upn { get; set; } + + [JsonPropertyName("sub")] + public string Sub { get; set; } } } diff --git a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs index 3d004336109..b0a1353ce89 100644 --- a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs +++ b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs @@ -11,6 +11,7 @@ using Microsoft.Identity.Client.Extensions.Msal; using System; using System.Diagnostics.Tracing; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -30,25 +31,24 @@ public static class AuthenticationHelpers /// /// The to get a token credential for. /// A based on provided . - public static async Task GetTokenCredentialAsync(IAuthContext authContext, CancellationToken cancellationToken = default) + public static async Task GetTokenCredentialAsync(IAuthContext authContext, bool safeRollOut, CancellationToken cancellationToken = default) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); - switch (authContext.AuthType) { case AuthenticationType.Delegated: if (authContext.TokenCredentialType == TokenCredentialType.InteractiveBrowser) - return await GetInteractiveBrowserCredentialAsync(authContext, cancellationToken).ConfigureAwait(false); - return await GetDeviceCodeCredentialAsync(authContext, cancellationToken).ConfigureAwait(false); + return await GetInteractiveBrowserCredentialAsync(authContext, safeRollOut, cancellationToken).ConfigureAwait(false); + return await GetDeviceCodeCredentialAsync(authContext, safeRollOut, cancellationToken).ConfigureAwait(false); case AuthenticationType.AppOnly: return authContext.TokenCredentialType == TokenCredentialType.ClientCertificate - ? await GetClientCertificateCredentialAsync(authContext).ConfigureAwait(false) - : await GetClientSecretCredentialAsync(authContext).ConfigureAwait(false); + ? await GetClientCertificateCredentialAsync(authContext, safeRollOut).ConfigureAwait(false) + : await GetClientSecretCredentialAsync(authContext, safeRollOut).ConfigureAwait(false); case AuthenticationType.ManagedIdentity: return await GetManagedIdentityCredentialAsync(authContext).ConfigureAwait(false); case AuthenticationType.EnvironmentVariable: - return await GetEnvironmentCredentialAsync(authContext).ConfigureAwait(false); + return await GetEnvironmentCredentialAsync(authContext, safeRollOut).ConfigureAwait(false); case AuthenticationType.UserProvidedAccessToken: return new UserProvidedTokenCredential(); default: @@ -56,16 +56,24 @@ public static async Task GetTokenCredentialAsync(IAuthContext a } } - private static async Task GetEnvironmentCredentialAsync(IAuthContext authContext) + private static async Task GetEnvironmentCredentialAsync(IAuthContext authContext, bool safeRollout) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); var tokenCredentialOptions = new TokenCredentialOptions { - AuthorityHost = new Uri(GetAuthorityUrl(authContext)) + AuthorityHost = new Uri(GetAuthorityUrl(authContext, false)) }; + if (safeRollout) + { + tokenCredentialOptions.ExtraQueryParameters = new Dictionary + { + { "safe_rollout", "apply:0238caeb-f6ca-4efc-afd0-a72e1273a8bc" } + }; + } + if (IsAuthFlowNotSupported()) { throw new Exception(string.Format(CultureInfo.InvariantCulture, ErrorConstants.Message.AuthNotSupported, "Username and password")); @@ -86,16 +94,23 @@ private static bool IsWamSupported() return GraphSession.Instance.GraphOption.EnableWAMForMSGraph && SharedUtilities.IsWindowsPlatform(); } - private static async Task GetClientSecretCredentialAsync(IAuthContext authContext) + private static async Task GetClientSecretCredentialAsync(IAuthContext authContext, bool safeRollout) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); var clientSecretCredentialOptions = new ClientSecretCredentialOptions { - AuthorityHost = new Uri(GetAuthorityUrl(authContext)), + AuthorityHost = new Uri(GetAuthorityUrl(authContext, false)), TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext) }; + if (safeRollout) + { + clientSecretCredentialOptions.ExtraQueryParameters = new Dictionary + { + { "safe_rollout", "apply:0238caeb-f6ca-4efc-afd0-a72e1273a8bc" } + }; + } var clientSecretCredential = new ClientSecretCredential(authContext.TenantId, authContext.ClientId, authContext.ClientSecret.ConvertToString(), clientSecretCredentialOptions); return await Task.FromResult(clientSecretCredential).ConfigureAwait(false); } @@ -109,16 +124,23 @@ private static async Task GetManagedIdentityCredentialAsync(IAu return await Task.FromResult(new ManagedIdentityCredential(userAccountId)).ConfigureAwait(false); } - private static async Task GetInteractiveBrowserCredentialAsync(IAuthContext authContext, CancellationToken cancellationToken = default) + private static async Task GetInteractiveBrowserCredentialAsync(IAuthContext authContext,bool safeRollOut, CancellationToken cancellationToken = default) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); var interactiveOptions = IsWamSupported() ? new InteractiveBrowserCredentialBrokerOptions(WindowHandleUtlities.GetConsoleOrTerminalWindow()) : new InteractiveBrowserCredentialOptions(); interactiveOptions.ClientId = authContext.ClientId; - interactiveOptions.TenantId = authContext.TenantId ?? "common"; - interactiveOptions.AuthorityHost = new Uri(GetAuthorityUrl(authContext)); + interactiveOptions.TenantId = authContext.TenantId ?? "common"; + interactiveOptions.AuthorityHost = new Uri(GetAuthorityUrl(authContext, safeRollOut)); + Console.WriteLine($"Got authority host {interactiveOptions.AuthorityHost}"); interactiveOptions.TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext); - + if (safeRollOut) + { + interactiveOptions.ExtraQueryParameters = new Dictionary + { + { "safe_rollout", "apply:0238caeb-f6ca-4efc-afd0-a72e1273a8bc" } + }; + } if (!File.Exists(Constants.AuthRecordPath)) { AuthenticationRecord authRecord; @@ -147,7 +169,7 @@ private static async Task GetInteractiveBrowserCre return new InteractiveBrowserCredential(interactiveOptions); } - private static async Task GetDeviceCodeCredentialAsync(IAuthContext authContext, CancellationToken cancellationToken = default) + private static async Task GetDeviceCodeCredentialAsync(IAuthContext authContext, bool safeRollOut, CancellationToken cancellationToken = default) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); @@ -156,7 +178,7 @@ private static async Task GetDeviceCodeCredentialAsync(IAu { ClientId = authContext.ClientId, TenantId = authContext.TenantId, - AuthorityHost = new Uri(GetAuthorityUrl(authContext)), + AuthorityHost = new Uri(GetAuthorityUrl(authContext, false)), TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext), DeviceCodeCallback = (code, cancellation) => { @@ -164,6 +186,13 @@ private static async Task GetDeviceCodeCredentialAsync(IAu return Task.CompletedTask; } }; + if (safeRollOut) + { + deviceCodeOptions.ExtraQueryParameters = new Dictionary + { + { "safe_rollout", "apply:0238caeb-f6ca-4efc-afd0-a72e1273a8bc" } + }; + } if (!File.Exists(Constants.AuthRecordPath)) { var deviceCodeCredential = new DeviceCodeCredential(deviceCodeOptions); @@ -176,17 +205,24 @@ private static async Task GetDeviceCodeCredentialAsync(IAu return new DeviceCodeCredential(deviceCodeOptions); } - private static async Task GetClientCertificateCredentialAsync(IAuthContext authContext) + private static async Task GetClientCertificateCredentialAsync(IAuthContext authContext, bool safeRollOut) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); var clientCredentialOptions = new ClientCertificateCredentialOptions { - AuthorityHost = new Uri(GetAuthorityUrl(authContext)), + AuthorityHost = new Uri(GetAuthorityUrl(authContext, false)), TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext), SendCertificateChain = authContext.SendCertificateChain }; + if (safeRollOut) + { + clientCredentialOptions.ExtraQueryParameters = new Dictionary + { + { "safe_rollout", "apply:0238caeb-f6ca-4efc-afd0-a72e1273a8bc" } + }; + } var clientCertificateCredential = new ClientCertificateCredential(authContext.TenantId, authContext.ClientId, GetCertificate(authContext), clientCredentialOptions); return await Task.FromResult(clientCertificateCredential).ConfigureAwait(false); } @@ -211,7 +247,7 @@ public static async Task GetAuthenticationProv return new AzureIdentityAccessTokenProvider(credential: tokenCrdential, scopes: GetScopes(authContext)); } - public static async Task AuthenticateAsync(IAuthContext authContext, CancellationToken cancellationToken) + public static async Task AuthenticateAsync(IAuthContext authContext, bool safeRollOut, CancellationToken cancellationToken) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); @@ -227,7 +263,7 @@ public static async Task AuthenticateAsync(IAuthContext authContex (args, message) => GraphSession.Instance.OutputWriter.WriteDebug($"{message}"), level: EventLevel.Informational)) { - signInAuthContext = await SignInAsync(authContext, cancellationToken).ConfigureAwait(false); + signInAuthContext = await SignInAsync(authContext, safeRollOut,cancellationToken).ConfigureAwait(false); retrySignIn = false; }; } @@ -272,11 +308,11 @@ public static async Task AuthenticateAsync(IAuthContext authContex return signInAuthContext; } - private static async Task SignInAsync(IAuthContext authContext, CancellationToken cancellationToken = default) + private static async Task SignInAsync(IAuthContext authContext, bool safeRollOut, CancellationToken cancellationToken = default) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); - var tokenCredential = await GetTokenCredentialAsync(authContext, cancellationToken).ConfigureAwait(false); + var tokenCredential = await GetTokenCredentialAsync(authContext, safeRollOut, cancellationToken).ConfigureAwait(false); var token = await tokenCredential.GetTokenAsync(new TokenRequestContext(GetScopes(authContext)), cancellationToken).ConfigureAwait(false); JwtHelpers.DecodeJWT(token.Token, account: null, ref authContext); return authContext; @@ -304,14 +340,14 @@ private static string[] GetScopes(IAuthContext authContext) /// /// The to get an authority URL for. /// - private static string GetAuthorityUrl(IAuthContext authContext) + private static string GetAuthorityUrl(IAuthContext authContext, bool safeRollOut) { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); string audience = authContext.TenantId ?? Constants.DefaultTenant; return GraphSession.Instance.Environment != null ? $"{GraphSession.Instance.Environment.AzureADEndpoint}/{audience}" - : $"{Constants.DefaultAzureADEndpoint}/{audience}"; + : $"{Constants.DefaultAzureADEndpoint}/{audience}"; } /// diff --git a/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs b/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs index 826cd1227d8..c4ec78ec3e0 100644 --- a/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs +++ b/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs @@ -42,6 +42,7 @@ internal static void DecodeJWT(string jwToken, IAccount account, ref IAuthContex authContext.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId; authContext.AppName = jwtPayload?.AppDisplayname; authContext.Account = jwtPayload?.Upn ?? account?.Username; + authContext.SubClaim = jwtPayload?.Sub; } /// diff --git a/src/Authentication/Authentication.Test/Microsoft.Graph.Authentication.Test.csproj b/src/Authentication/Authentication.Test/Microsoft.Graph.Authentication.Test.csproj index 8a3d6c004f8..63b93836d74 100644 --- a/src/Authentication/Authentication.Test/Microsoft.Graph.Authentication.Test.csproj +++ b/src/Authentication/Authentication.Test/Microsoft.Graph.Authentication.Test.csproj @@ -2,7 +2,8 @@ net6.0;net472 false - 2.8.0 + 2.22.0 + preview2 diff --git a/src/Authentication/Authentication.sln b/src/Authentication/Authentication.sln index 1e4002e7a0b..3eb3306ea2b 100644 --- a/src/Authentication/Authentication.sln +++ b/src/Authentication/Authentication.sln @@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Graph.Authenticat EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenApiInfoGenerator", "..\..\tools\OpenApiInfoGenerator\OpenApiInfoGenerator\OpenApiInfoGenerator.csproj", "{6437E29A-E398-48EE-B7BE-27A8C922F13E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Identity", "..\..\azure-sdk-for-net\sdk\identity\Azure.Identity\src\Azure.Identity.csproj", "{BDAFCAD5-1DAB-4C57-A7D4-140E396CCC83}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {6437E29A-E398-48EE-B7BE-27A8C922F13E}.Debug|Any CPU.Build.0 = Debug|Any CPU {6437E29A-E398-48EE-B7BE-27A8C922F13E}.Release|Any CPU.ActiveCfg = Release|Any CPU {6437E29A-E398-48EE-B7BE-27A8C922F13E}.Release|Any CPU.Build.0 = Release|Any CPU + {BDAFCAD5-1DAB-4C57-A7D4-140E396CCC83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDAFCAD5-1DAB-4C57-A7D4-140E396CCC83}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDAFCAD5-1DAB-4C57-A7D4-140E396CCC83}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDAFCAD5-1DAB-4C57-A7D4-140E396CCC83}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs b/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs index 3fd26ccb594..ab8bac696eb 100644 --- a/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs +++ b/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs @@ -56,6 +56,17 @@ public class ConnectMgGraph : PSCmdlet, IModuleAssemblyInitializer, IModuleAssem [Alias("SecretCredential", "Credential")] public PSCredential ClientSecretCredential { get; set; } + /* + Torus migration changes for client based rollout + */ + [Parameter(ParameterSetName = Constants.AccessTokenParameterSet, Mandatory = false, HelpMessage = HelpMessages.SafeRollout)] + [Parameter(Mandatory = false, ParameterSetName = Constants.AppCertificateParameterSet, HelpMessage = HelpMessages.Certificate)] + [Parameter(Mandatory = false, ParameterSetName = Constants.AppSecretCredentialParameterSet, HelpMessage = HelpMessages.ClientSecretCredential)] + [Parameter(ParameterSetName = Constants.UserParameterSet, Mandatory = false, HelpMessage = HelpMessages.SafeRollout)] + [Parameter(ParameterSetName = Constants.EnvironmentVariableParameterSet, Mandatory = false, HelpMessage = HelpMessages.Environment)] + [Alias("ValidateRollout")] + public bool SafeRollOut { get; set; } + [Parameter(ParameterSetName = Constants.AccessTokenParameterSet, Position = 1, Mandatory = true, HelpMessage = HelpMessages.AccessToken)] public SecureString AccessToken { get; set; } @@ -125,8 +136,17 @@ protected override void BeginProcessing() } else { - environment = GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Global]; + bool.TryParse(SafeRollOut.ToString().ToLower(), out bool safeRollOut); + if (safeRollOut) { + //Use Torus environment + environment = GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Torus]; + } + else{ + environment = GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Global]; + } + } + } protected override void ProcessRecord() { @@ -167,7 +187,7 @@ private async Task ProcessRecordAsync() IAuthContext authContext = new AuthContext { TenantId = TenantId, PSHostVersion = this.Host.Version, Environment = environment?.Name }; if (MyInvocation.BoundParameters.ContainsKey(nameof(ClientTimeout))) GraphSession.Instance.RequestContext.ClientTimeout = TimeSpan.FromSeconds(ClientTimeout); - + bool.TryParse(SafeRollOut.ToString().ToLower(), out bool safeRollOut); GraphSession.Instance.Environment = environment; GraphSession.Instance.GraphHttpClient = null; if (GraphSession.Instance.InMemoryTokenCache is null) @@ -247,7 +267,8 @@ private async Task ProcessRecordAsync() try { - GraphSession.Instance.AuthContext = await AuthenticationHelpers.AuthenticateAsync(authContext, _cancellationTokenSource.Token).ConfigureAwait(false); + GraphSession.Instance.AuthContext = await AuthenticationHelpers.AuthenticateAsync(authContext, safeRollOut,_cancellationTokenSource.Token).ConfigureAwait(false); + } catch (Exception) { @@ -270,6 +291,14 @@ private static string GetWelcomeMessage(string clientId, string authType) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"Welcome to Microsoft Graph!{System.Environment.NewLine}"); + //Show message that this is a torus test if environment is torus and the access token is user defined + if (GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Torus].Name == GraphSession.Instance.Environment.Name) + { + stringBuilder.AppendLine($"You are connected to the Torus environment. This is a test environment and should not be used for production scenarios.{System.Environment.NewLine}"); + //Show the azure endpoint for torus environment + stringBuilder.AppendLine($"Azure Endpoint: {GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Torus].AzureADEndpoint}{System.Environment.NewLine}"); + } + //Show torus migration message if safe rollout is enabled stringBuilder.AppendLine($"Connected via {authType.ToLower()} access using {clientId}"); stringBuilder.AppendLine($"Readme: {Constants.SdkReadmeLink}"); stringBuilder.AppendLine($"SDK Docs: {Constants.SdkDocsLink}"); diff --git a/src/Authentication/Authentication/Constants.cs b/src/Authentication/Authentication/Constants.cs index 47924df7842..7f9e9fd35bc 100644 --- a/src/Authentication/Authentication/Constants.cs +++ b/src/Authentication/Authentication/Constants.cs @@ -18,6 +18,7 @@ public static class Constants internal const string AppSecretCredentialParameterSet = nameof(AppSecretCredentialParameterSet); internal const string AccessTokenParameterSet = nameof(AccessTokenParameterSet); internal const string IdentityParameterSet = nameof(IdentityParameterSet); + internal const string SafeRolloutParameterSet = nameof(SafeRolloutParameterSet); internal const string EnvironmentVariableParameterSet = nameof(EnvironmentVariableParameterSet); internal static readonly string ContextSettingsPath = Path.Combine(Core.Constants.GraphDirectoryPath, "mg.context.json"); internal const int MAX_RETRY_DELAY_IN_SECONDS = 180; @@ -48,6 +49,9 @@ public static class HelpMessages public const string Identity = "Login using a Managed Identity."; public const string EnvironmentVariable = "Allows for authentication using environment variables configured on the host machine. See https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/identity/Azure.Identity#environment-variables."; public const string ManagedIdentityClientId = "The client id to authenticate for a user assigned managed identity. For more information on user assigned managed identities see: https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview#how-a-user-assigned-managed-identity-works-with-an-azure-vmId. To use the SystemAssigned identity, leave this field blank."; + + //Help message for safe rollout during torus migration + public const string SafeRollout = "Use this parameter to enable safe rollout of the app owners to use the app in destination tenant based on their deployment strategy. This will allow you to test the app without affecting the existing functionality. Once the migration has been finalized, you can remove this parameter."; } } } diff --git a/src/Authentication/Authentication/GraphEnvironmentConstants.cs b/src/Authentication/Authentication/GraphEnvironmentConstants.cs index b13710d234f..7f674caf4a0 100644 --- a/src/Authentication/Authentication/GraphEnvironmentConstants.cs +++ b/src/Authentication/Authentication/GraphEnvironmentConstants.cs @@ -14,6 +14,10 @@ internal static class GraphEnvironmentConstants /// public static class EnvironmentName { + /// + /// Environment used for tours tests. + /// + public const string Torus = "Torus"; /// /// The graph national cloud. /// @@ -103,7 +107,18 @@ public static class EnvironmentType AzureADEndpoint = "https://login.chinacloudapi.cn", GraphEndpoint = "https://microsoftgraph.chinacloudapi.cn" } - } + }, + + // Environment used for torus tests. + { + EnvironmentName.Torus, new GraphEnvironment + { + Name = EnvironmentName.Torus, + Type = EnvironmentType.BuiltIn, + AzureADEndpoint = "https://login.microsoftonline.com", + GraphEndpoint = "https://graph.microsoft.com" + } + }, }; } } diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj b/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj index 383f9e88005..fab65eee1a7 100644 --- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj +++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj @@ -10,7 +10,8 @@ Microsoft.Graph.Authentication.nuspec © Microsoft Corporation. All rights reserved. - 2.6.1 + 2.22.0 + preview2 true diff --git a/src/Authentication/Authentication/Models/AuthContext.cs b/src/Authentication/Authentication/Models/AuthContext.cs index 6538667da03..cc83e426325 100644 --- a/src/Authentication/Authentication/Models/AuthContext.cs +++ b/src/Authentication/Authentication/Models/AuthContext.cs @@ -28,6 +28,7 @@ public class AuthContext : IAuthContext public string ManagedIdentityId { get; set; } public SecureString ClientSecret { get; set; } public string Environment { get; set; } = GraphEnvironmentConstants.EnvironmentName.Global; + public string SubClaim { get; set; } public AuthContext() {