From d96db0631786b32ceb4178b18e160d5436b3dd51 Mon Sep 17 00:00:00 2001 From: Timothy Wamalwa Date: Wed, 26 Jun 2024 10:22:42 +0300 Subject: [PATCH 1/8] Rolled back devicemanagement to the one that 2.19.0 had. --- openApiDocs/beta/DeviceManagement.Actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openApiDocs/beta/DeviceManagement.Actions.yml b/openApiDocs/beta/DeviceManagement.Actions.yml index 1bb85dea98..13ba0d3e82 100644 --- a/openApiDocs/beta/DeviceManagement.Actions.yml +++ b/openApiDocs/beta/DeviceManagement.Actions.yml @@ -487,4 +487,4 @@ components: tokenUrl: https://login.microsoftonline.com/common/oauth2/v2.0/token scopes: { } security: - - azureaadv2: [ ] + - azureaadv2: [ ] \ No newline at end of file From 26496db7c0ae8f57e5b7b1ea914291927d898420 Mon Sep 17 00:00:00 2001 From: "Taofeek F. Obafemi-Babatunde" Date: Thu, 28 Dec 2023 10:52:21 -0800 Subject: [PATCH 2/8] adding "-AT PoP" option to "Set-MgGraphOptions" Adding AT PoP skeleton (#2511) * adding "-AT PoP" option to "Set-MgGraphOptions" --------- AT PoP Version 1 Fehintolaobafemi/methodanduri (#2751) * Making changes to how httpmethod and uri is processed --------- Fixing and updating the docs resolving build break fixing build issues related to docs resolving PR comments updating nuget packages removing unnecessary string assignment Resolving PR comments reverting test csproj changes --- docs/AT-Pop.md | 79 +++++++++++++++++++ docs/authentication.md | 20 +++++ .../Common/GraphSession.cs | 5 ++ .../Interfaces/IGraphOptions.cs | 5 +- .../Interfaces/IGraphRequestPopContext.cs | 21 +++++ .../Interfaces/IGraphSession.cs | 1 + ...Microsoft.Graph.Authentication.Core.csproj | 14 ++-- .../Utilities/AuthenticationHelpers.cs | 64 +++++++++++++-- .../Cmdlets/InvokeMgGraphRequest.cs | 2 + .../Cmdlets/SetMgGraphOption.cs | 8 ++ .../Common/GraphSessionInitializer.cs | 3 +- .../Handlers/AuthenticationHandler.cs | 32 +++++++- .../Authentication/Models/GraphOption.cs | 1 + .../Models/GraphRequestPopContext.cs | 23 ++++++ .../test/Get-MgGraphOption.Tests.ps1 | 2 +- .../test/Set-MgGraphOption.Tests.ps1 | 16 +++- src/Authentication/docs/Get-MgGraphOption.md | 2 +- src/Authentication/docs/Set-MgGraphOption.md | 15 +++- .../examples/Set-MgGraphOption.md | 8 +- 19 files changed, 293 insertions(+), 28 deletions(-) create mode 100644 docs/AT-Pop.md create mode 100644 src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs create mode 100644 src/Authentication/Authentication/Models/GraphRequestPopContext.cs diff --git a/docs/AT-Pop.md b/docs/AT-Pop.md new file mode 100644 index 0000000000..7793dd6c9e --- /dev/null +++ b/docs/AT-Pop.md @@ -0,0 +1,79 @@ +# Microsoft Graph PowerShell SDK: Access Token Proof of Possession (AT PoP) Capability + +## Overview + +This README provides comprehensive details on the Access Token Proof of Possession (AT PoP) functionality introduced in the Microsoft Graph PowerShell SDK. This feature enhances security by binding tokens to specific HTTP methods and URIs, ensuring they are used only for their intended purposes. + +## Table of Contents + +- [Key Features](#key-features) +- [Installation](#installation) +- [Configuration](#configuration) +- [Usage Examples](#usage-examples) +- [References](#references) + +## Key Features + +- **Access Token Proof of Possession (AT PoP)**: This feature binds tokens to specific HTTP methods and URIs, preventing misuse of tokens by ensuring they are used only for the intended HTTP requests. +- **Updated Dependencies**: Compatibility improvements with recent library changes. +- **Enhanced Token Acquisition Options**: Users can now specify the HTTP method and URI during token acquisition to further secure token usage. + +### Token acquisition behaviors + +| Condition | Unbound (default) | Bound (PoP) | +|-----------|-----------|-----------| +| First sign-in | New token, interactive| New token, interactive | +| Existing token, same URI | No new token, silent | No new token, silent | +| Existing token, different URI | No new token, silent | New token, silent | +| Existing expired token, below max token refreshes | New token, silent | New token, silent | +| Existing expired token, exceeded max refreshes | New token, interactive | New token, interactive | + +## Installation + +To install the Microsoft Graph PowerShell SDK with the latest updates, use the following command: + +```powershell +Install-Module -Name Microsoft.Graph -AllowClobber -Force +``` + +Ensure you are using the latest version to access the AT PoP functionality. + +## Configuration + +### Enabling Access Token Proof of Possession + +To enable AT PoP, configure the Microsoft Graph SDK options as follows: + +```powershell +Set-MgGraphOption -EnableATPoP $true + +Connect-MgGraph +``` + +This configuration ensures that the acquired token is only valid for the specified HTTP method and URI. + +## Usage Examples + +### Example 1: + +```powershell +Set-MgGraphOption -EnableATPoP $true + +Connect-MgGraph + +Invoke-MgGraphRequest -Method GET https://graph.microsoft.com/v1.0/me -Debug +``` + +### Example 2: + +```powershell +Set-MgGraphOption -EnableATPoP $true + +Connect-MgGraph + +Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/me/sendMail" -Method POST -Debug +``` + +## References + +This README provides a detailed guide on the new AT PoP functionality, offering users the ability to secure their token usage effectively. If you have any questions or need further assistance, please refer to the official [Microsoft Graph PowerShell SDK documentation](https://docs.microsoft.com/en-us/powershell/microsoftgraph/). diff --git a/docs/authentication.md b/docs/authentication.md index 6cfbfda695..4d58789849 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -112,6 +112,26 @@ When using `-AccessToken`, we won't have access to the refresh token and the cli Before using the provided `-AccessToken` to get Microsoft Graph resources, customers should ensure that the access token has the necessary scopes/ permissions needed to access/modify a resource. +### Access Token Proof of Possession (AT PoP) + +AT PoP is a security mechanism that binds an access token to a cryptographic key that only the token requestor has. This prevents unauthorized use of the token by malicious actors. AT PoP enhances data protection, reduces token replay attacks, and enables fine-grained authorization policies. + +Note: AT PoP requires Web Account Manager (WAM) to function. + +Microsoft Graph PowerShell module supports AT PoP in the following scenario: + +- To enable AT PoP on supported devices + +```PowerShell +Set-MgGraphOption -EnableATPoP $true +``` + +- To disable AT PoP on supported devices + +```PowerShell +Set-MgGraphOption -EnableATPoP $false +``` + ## Web Account Manager (WAM) WAM is a Windows 10+ component that acts as an authentication broker allowing the users of an app benefit from integration with accounts known to Windows, such as the account already signed into an active Windows session. diff --git a/src/Authentication/Authentication.Core/Common/GraphSession.cs b/src/Authentication/Authentication.Core/Common/GraphSession.cs index 6b893d4d1c..f094160840 100644 --- a/src/Authentication/Authentication.Core/Common/GraphSession.cs +++ b/src/Authentication/Authentication.Core/Common/GraphSession.cs @@ -56,6 +56,11 @@ public class GraphSession : IGraphSession /// public IGraphOption GraphOption { get; set; } + /// + /// Temporarily stores the user's Graph request details such as Method and Uri. Essential as part of the Proof of Possession efforts. + /// + public IGraphRequestPopContext GraphRequestPopContext { get; set; } + /// /// Represents a collection of Microsoft Graph PowerShell meta-info. /// diff --git a/src/Authentication/Authentication.Core/Interfaces/IGraphOptions.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphOptions.cs index 3dd2483694..de7f68f15d 100644 --- a/src/Authentication/Authentication.Core/Interfaces/IGraphOptions.cs +++ b/src/Authentication/Authentication.Core/Interfaces/IGraphOptions.cs @@ -2,14 +2,11 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. // ------------------------------------------------------------------------------ -using System; -using System.Security; -using System.Security.Cryptography.X509Certificates; - namespace Microsoft.Graph.PowerShell.Authentication { public interface IGraphOption { bool EnableWAMForMSGraph { get; set; } + bool EnableATPoPForMSGraph { get; set; } } } \ No newline at end of file diff --git a/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs new file mode 100644 index 0000000000..7a154ea9f4 --- /dev/null +++ b/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs @@ -0,0 +1,21 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using Azure.Core; +using Azure.Identity; +using System; +using System.Net.Http; + +namespace Microsoft.Graph.PowerShell.Authentication +{ + public interface IGraphRequestPopContext + { + Uri Uri { get; set; } + HttpMethod HttpMethod { get; set; } + AccessToken AccessToken { get; set; } + PopTokenRequestContext PopTokenContext { get; set; } + Request Request { get; set; } + InteractiveBrowserCredential PopInteractiveBrowserCredential { get; set; } + } +} \ No newline at end of file diff --git a/src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs index c7f8ba48c3..fc0fd19cbb 100644 --- a/src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs +++ b/src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs @@ -12,5 +12,6 @@ public interface IGraphSession IDataStore DataStore { get; set; } IRequestContext RequestContext { get; set; } IGraphOption GraphOption { get; set; } + IGraphRequestPopContext GraphRequestPopContext { 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 bcce1da629..b2a1da6c2a 100644 --- a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj +++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj @@ -1,21 +1,21 @@ - + 9.0 netstandard2.0;net8.0;net472 Microsoft.Graph.PowerShell.Authentication.Core - 2.25.0 - - true + 2.12.0 true true - - - + + + + + diff --git a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs index 71919594c4..60c23f9353 100644 --- a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs +++ b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------------ using Azure.Core; using Azure.Core.Diagnostics; +using Azure.Core.Pipeline; using Azure.Identity; using Azure.Identity.Broker; using Microsoft.Graph.Authentication; @@ -14,6 +15,8 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -114,23 +117,43 @@ private static async Task GetInteractiveBrowserCre { if (authContext is null) throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext); - var interactiveOptions = IsWamSupported() ? new InteractiveBrowserCredentialBrokerOptions(WindowHandleUtlities.GetConsoleOrTerminalWindow()) : new InteractiveBrowserCredentialOptions(); + 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.TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext); + var interactiveBrowserCredential = new InteractiveBrowserCredential(interactiveOptions); + if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) + { + GraphSession.Instance.GraphRequestPopContext.PopTokenContext = await CreatePopTokenRequestContext(authContext); + GraphSession.Instance.GraphRequestPopContext.PopInteractiveBrowserCredential = interactiveBrowserCredential; + } + if (!File.Exists(Constants.AuthRecordPath)) { AuthenticationRecord authRecord; - var interactiveBrowserCredential = new InteractiveBrowserCredential(interactiveOptions); if (IsWamSupported()) { - authRecord = await Task.Run(() => + // Adding a scenario to account for Access Token Proof of Possession + if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) { - // Run the thread in MTA. - return interactiveBrowserCredential.Authenticate(new TokenRequestContext(authContext.Scopes), cancellationToken); - }); + authRecord = await Task.Run(() => + { + // Run the thread in MTA. + return interactiveBrowserCredential.AuthenticateAsync(GraphSession.Instance.GraphRequestPopContext.PopTokenContext, cancellationToken); + }); + } + else + { + authRecord = await Task.Run(() => + { + // Run the thread in MTA. + return interactiveBrowserCredential.Authenticate(new TokenRequestContext(authContext.Scopes), cancellationToken); + }); + } } else { @@ -447,5 +470,34 @@ public static Task DeleteAuthRecordAsync() File.Delete(Constants.AuthRecordPath); return Task.CompletedTask; } + + private static async Task CreatePopTokenRequestContext(IAuthContext authContext) + { + // Creating a httpclient that would handle all pop calls + Uri popResourceUri = GraphSession.Instance.GraphRequestPopContext.Uri ?? new Uri("https://graph.microsoft.com/beta/organization"); + HttpClient popHttpClient = new(new HttpClientHandler()); + + // Find the nonce in the WWW-Authenticate header in the response. + var popMethod = GraphSession.Instance.GraphRequestPopContext.HttpMethod ?? HttpMethod.Get; + var popResponse = await popHttpClient.SendAsync(new HttpRequestMessage(popMethod, popResourceUri)); + + // Refresh token logic --- start + var popPipelineOptions = new HttpPipelineOptions(new PopClientOptions() + { + + }); + + var _popPipeline = HttpPipelineBuilder.Build(popPipelineOptions, new HttpPipelineTransportOptions()); + GraphSession.Instance.GraphRequestPopContext.Request = _popPipeline.CreateRequest(); + GraphSession.Instance.GraphRequestPopContext.Request.Method = RequestMethod.Parse(popMethod.Method.ToUpper()); + GraphSession.Instance.GraphRequestPopContext.Request.Uri.Reset(popResourceUri); + + // Refresh token logic --- end + var popContext = new PopTokenRequestContext(authContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(popResponse.Headers, "Pop").Nonce, request: GraphSession.Instance.GraphRequestPopContext.Request); + return popContext; + } + } + internal class PopClientOptions : ClientOptions + { } } \ No newline at end of file diff --git a/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs b/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs index 4e16b46248..b1360636f4 100644 --- a/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs +++ b/src/Authentication/Authentication/Cmdlets/InvokeMgGraphRequest.cs @@ -1026,6 +1026,8 @@ private async Task ProcessRecordAsync() try { PrepareSession(); + GraphSession.Instance.GraphRequestPopContext.Uri = Uri; + GraphSession.Instance.GraphRequestPopContext.HttpMethod = GetHttpMethod(Method); var client = HttpHelpers.GetGraphHttpClient(); ValidateRequestUri(); using (var httpRequestMessage = GetRequest(client, Uri)) diff --git a/src/Authentication/Authentication/Cmdlets/SetMgGraphOption.cs b/src/Authentication/Authentication/Cmdlets/SetMgGraphOption.cs index ad4f0f76a1..fc4da16a8e 100644 --- a/src/Authentication/Authentication/Cmdlets/SetMgGraphOption.cs +++ b/src/Authentication/Authentication/Cmdlets/SetMgGraphOption.cs @@ -13,6 +13,9 @@ public class SetMgGraphOption : PSCmdlet { [Parameter] public bool EnableLoginByWAM { get; set; } + + [Parameter] + public bool EnableATPoP { get; set; } protected override void BeginProcessing() { @@ -27,6 +30,11 @@ protected override void ProcessRecord() GraphSession.Instance.GraphOption.EnableWAMForMSGraph = EnableLoginByWAM; WriteDebug($"Signin by Web Account Manager (WAM) is {(EnableLoginByWAM ? "enabled" : "disabled")}."); } + if (this.IsParameterBound(nameof(EnableATPoP))) + { + GraphSession.Instance.GraphOption.EnableATPoPForMSGraph = EnableATPoP; + WriteDebug($"Access Token Proof of Posession (AT-PoP) is {(EnableATPoP ? "enabled" : "disabled")}."); + } File.WriteAllText(Constants.GraphOptionsFilePath, JsonConvert.SerializeObject(GraphSession.Instance.GraphOption, Formatting.Indented)); } diff --git a/src/Authentication/Authentication/Common/GraphSessionInitializer.cs b/src/Authentication/Authentication/Common/GraphSessionInitializer.cs index 4d3d527da1..ec165e5a94 100644 --- a/src/Authentication/Authentication/Common/GraphSessionInitializer.cs +++ b/src/Authentication/Authentication/Common/GraphSessionInitializer.cs @@ -47,7 +47,8 @@ internal static GraphSession CreateInstance(IDataStore dataStore = null) { DataStore = dataStore ?? new DiskDataStore(), RequestContext = new RequestContext(), - GraphOption = graphOptions ?? new GraphOption() + GraphOption = graphOptions ?? new GraphOption(), + GraphRequestPopContext = new GraphRequestPopContext() }; } /// diff --git a/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs b/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs index e57d74186b..b78ed1eb59 100644 --- a/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs +++ b/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs @@ -3,11 +3,15 @@ // ------------------------------------------------------------------------------ +using Azure.Core; using Microsoft.Graph.Authentication; +using Microsoft.Graph.PowerShell.Authentication.Core.Utilities; using Microsoft.Graph.PowerShell.Authentication.Extensions; +using Microsoft.Identity.Client; using System; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -21,6 +25,7 @@ internal class AuthenticationHandler : DelegatingHandler { private const string ClaimsKey = "claims"; private const string BearerAuthenticationScheme = "Bearer"; + private const string PopAuthenticationScheme = "Pop"; private int MaxRetry { get; set; } = 1; public AzureIdentityAccessTokenProvider AuthenticationProvider { get; set; } @@ -45,6 +50,12 @@ protected override async Task SendAsync(HttpRequestMessage HttpResponseMessage response = await base.SendAsync(httpRequestMessage, cancellationToken).ConfigureAwait(false); + // Continuous nonce extraction on each request + if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) + { + GraphSession.Instance.GraphRequestPopContext.PopTokenContext = new PopTokenRequestContext(GraphSession.Instance.AuthContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(response.Headers, PopAuthenticationScheme).Nonce, request: GraphSession.Instance.GraphRequestPopContext.Request); + } + // Check if response is a 401 & is not a streamed body (is buffered) if (response.StatusCode == HttpStatusCode.Unauthorized && httpRequestMessage.IsBuffered()) { @@ -63,9 +74,24 @@ private async Task AuthenticateRequestAsync(HttpRequestMessage httpRequestMessag { if (AuthenticationProvider != null) { - var accessToken = await AuthenticationProvider.GetAuthorizationTokenAsync(httpRequestMessage.RequestUri, additionalAuthenticationContext, cancellationToken: cancellationToken).ConfigureAwait(false); - if (!string.IsNullOrEmpty(accessToken)) - httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(BearerAuthenticationScheme, accessToken); + if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) + { + GraphSession.Instance.GraphRequestPopContext.Request.Method = RequestMethod.Parse(httpRequestMessage.Method.Method.ToUpper()); + GraphSession.Instance.GraphRequestPopContext.Request.Uri.Reset(httpRequestMessage.RequestUri); + foreach (var header in httpRequestMessage.Headers) + { + GraphSession.Instance.GraphRequestPopContext.Request.Headers.Add(header.Key, header.Value.First()); + } + + var accessToken = await GraphSession.Instance.GraphRequestPopContext.PopInteractiveBrowserCredential.GetTokenAsync(GraphSession.Instance.GraphRequestPopContext.PopTokenContext, cancellationToken).ConfigureAwait(false); + httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(PopAuthenticationScheme, accessToken.Token); + } + else + { + var accessToken = await AuthenticationProvider.GetAuthorizationTokenAsync(httpRequestMessage.RequestUri, additionalAuthenticationContext, cancellationToken: cancellationToken).ConfigureAwait(false); + if (!string.IsNullOrEmpty(accessToken)) + httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(BearerAuthenticationScheme, accessToken); + } } } diff --git a/src/Authentication/Authentication/Models/GraphOption.cs b/src/Authentication/Authentication/Models/GraphOption.cs index d8c48d7f70..e8c83e6ef0 100644 --- a/src/Authentication/Authentication/Models/GraphOption.cs +++ b/src/Authentication/Authentication/Models/GraphOption.cs @@ -9,6 +9,7 @@ namespace Microsoft.Graph.PowerShell.Authentication internal class GraphOption : IGraphOption { public bool EnableWAMForMSGraph { get; set; } + public bool EnableATPoPForMSGraph { get; set; } } } \ No newline at end of file diff --git a/src/Authentication/Authentication/Models/GraphRequestPopContext.cs b/src/Authentication/Authentication/Models/GraphRequestPopContext.cs new file mode 100644 index 0000000000..0092543bb3 --- /dev/null +++ b/src/Authentication/Authentication/Models/GraphRequestPopContext.cs @@ -0,0 +1,23 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using Azure.Core; +using Azure.Identity; +using System; +using System.IO; +using System.Net.Http; + +namespace Microsoft.Graph.PowerShell.Authentication +{ + internal class GraphRequestPopContext : IGraphRequestPopContext + { + public Uri Uri { get; set; } + public HttpMethod HttpMethod { get; set; } + public AccessToken AccessToken { get; set; } + public PopTokenRequestContext PopTokenContext { get; set; } + public Request Request { get; set; } + public InteractiveBrowserCredential PopInteractiveBrowserCredential { get; set; } + } + +} \ No newline at end of file diff --git a/src/Authentication/Authentication/test/Get-MgGraphOption.Tests.ps1 b/src/Authentication/Authentication/test/Get-MgGraphOption.Tests.ps1 index 786105807c..2708d2f7f4 100644 --- a/src/Authentication/Authentication/test/Get-MgGraphOption.Tests.ps1 +++ b/src/Authentication/Authentication/test/Get-MgGraphOption.Tests.ps1 @@ -13,7 +13,7 @@ Describe "Get-MgGraphOption Command" { $GetMgGraphOptionCommand = Get-Command Set-MgGraphOption $GetMgGraphOptionCommand | Should -Not -BeNullOrEmpty $GetMgGraphOptionCommand.ParameterSets | Should -HaveCount 1 - $GetMgGraphOptionCommand.ParameterSets.Parameters | Should -HaveCount 13 # PS common parameters. + $GetMgGraphOptionCommand.ParameterSets.Parameters | Should -HaveCount 14 # PS common parameters. } It 'Executes successfully' { diff --git a/src/Authentication/Authentication/test/Set-MgGraphOption.Tests.ps1 b/src/Authentication/Authentication/test/Set-MgGraphOption.Tests.ps1 index 6a2cb60693..775cdcaa62 100644 --- a/src/Authentication/Authentication/test/Set-MgGraphOption.Tests.ps1 +++ b/src/Authentication/Authentication/test/Set-MgGraphOption.Tests.ps1 @@ -9,14 +9,14 @@ Describe "Set-MgGraphOption" { Import-Module $ModulePath -Force -ErrorAction SilentlyContinue } Context "When executing the command" { - it 'Should have one ParameterSets' { + it 'Should have two ParameterSets' { $SetMgGraphOptionCommand = Get-Command Set-MgGraphOption $SetMgGraphOptionCommand | Should -Not -BeNullOrEmpty $SetMgGraphOptionCommand.ParameterSets | Should -HaveCount 1 - $SetMgGraphOptionCommand.ParameterSets.Parameters | Should -HaveCount 13 # PS common parameters. + $SetMgGraphOptionCommand.ParameterSets.Parameters | Should -HaveCount 14 # PS common parameters. } - It 'Executes successfully whren toggling WAM on' { + It 'Executes successfully when toggling WAM on' { { Set-MgGraphOption -EnableLoginByWAM $true -Debug | Out-Null } | Should -Not -Be $null { Set-MgGraphOption -EnableLoginByWAM $true -ErrorAction SilentlyContinue } | Should -Not -Throw } @@ -25,5 +25,15 @@ Describe "Set-MgGraphOption" { { Set-MgGraphOption -EnableLoginByWAM $false -Debug | Out-Null } | Should -Not -Be $null { Set-MgGraphOption -EnableLoginByWAM $false -ErrorAction SilentlyContinue } | Should -Not -Throw } + + It 'Executes successfully when toggling AT PoP on' { + { Set-MgGraphOption -EnableATPoP $true -Debug | Out-Null } | Should -Not -Be $null + { Set-MgGraphOption -EnableATPoP $true -ErrorAction SilentlyContinue } | Should -Not -Throw + } + + It 'Executes successfully when toggling AT PoP off' { + { Set-MgGraphOption -EnableATPoP $false -Debug | Out-Null } | Should -Not -Be $null + { Set-MgGraphOption -EnableATPoP $false -ErrorAction SilentlyContinue } | Should -Not -Throw + } } } \ No newline at end of file diff --git a/src/Authentication/docs/Get-MgGraphOption.md b/src/Authentication/docs/Get-MgGraphOption.md index f4ef0a7c25..7678d11d79 100644 --- a/src/Authentication/docs/Get-MgGraphOption.md +++ b/src/Authentication/docs/Get-MgGraphOption.md @@ -1,7 +1,7 @@ --- external help file: Microsoft.Graph.Authentication.dll-Help.xml Module Name: Microsoft.Graph.Authentication -online version: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/get-mgenvironment +online version: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/get-mggraphoption schema: 2.0.0 --- diff --git a/src/Authentication/docs/Set-MgGraphOption.md b/src/Authentication/docs/Set-MgGraphOption.md index 85ee3e9fca..99ef8e95a2 100644 --- a/src/Authentication/docs/Set-MgGraphOption.md +++ b/src/Authentication/docs/Set-MgGraphOption.md @@ -1,7 +1,7 @@ --- external help file: Microsoft.Graph.Authentication.dll-Help.xml Module Name: Microsoft.Graph.Authentication -online version: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/set-mgenvironment +online version: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/set-mggraphoption schema: 2.0.0 --- @@ -15,6 +15,9 @@ Sets global configurations that apply to the SDK. For example, toggle Web Accoun ``` Set-MgGraphOption [-EnableLoginByWAM ] [] ``` +``` +Set-MgGraphOption [-EnableATPoP ] [] +``` ## DESCRIPTION Sets global configurations that apply to the SDK. For example, toggle Web Account Manager (WAM) support. @@ -28,11 +31,21 @@ PS C:\> Set-MgGraphOption -EnableLoginByWAM $True Sets web account manager support +### Example 2: Set access token proof of possession support +```powershell +PS C:\> Set-MgGraphOption -EnableATPoP $True +``` + + Sets access token proof of possession support + ## PARAMETERS ### -EnableLoginByWAM {{ Fill EnableLoginByWAM Description }} +### -EnableATPoP +{{ Fill EnableATPoP Description }} + ```yaml Type: Boolean Parameter Sets: (All) diff --git a/src/Authentication/examples/Set-MgGraphOption.md b/src/Authentication/examples/Set-MgGraphOption.md index 055431b592..afc23d97cb 100644 --- a/src/Authentication/examples/Set-MgGraphOption.md +++ b/src/Authentication/examples/Set-MgGraphOption.md @@ -2,4 +2,10 @@ ```powershell PS C:\> Set-MgGraphOption -EnableLoginByWAM $True ``` - Sets web account manager support \ No newline at end of file + Sets web account manager support + +### Example 2: Set access token proof of possession support +```powershell +PS C:\> Set-MgGraphOption -EnableATPoP $True +``` + Sets access token proof of possession support \ No newline at end of file From 88788c13aed50e235dc64081dcbc6b38be92faaf Mon Sep 17 00:00:00 2001 From: "Taofeek F. Obafemi-Babatunde" Date: Mon, 15 Jul 2024 13:30:50 -0700 Subject: [PATCH 3/8] Resolving comments regarding static instance --- .../Interfaces/IGraphRequestPopContext.cs | 4 ++-- .../Utilities/AuthenticationHelpers.cs | 15 ++++++++------- .../Handlers/AuthenticationHandler.cs | 12 +++++++----- .../Models/GraphRequestPopContext.cs | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs index 7a154ea9f4..61551edb31 100644 --- a/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs +++ b/src/Authentication/Authentication.Core/Interfaces/IGraphRequestPopContext.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------------ using Azure.Core; +using Azure.Core.Pipeline; using Azure.Identity; using System; using System.Net.Http; @@ -14,8 +15,7 @@ public interface IGraphRequestPopContext Uri Uri { get; set; } HttpMethod HttpMethod { get; set; } AccessToken AccessToken { get; set; } - PopTokenRequestContext PopTokenContext { get; set; } - Request Request { get; set; } + HttpPipeline PopPipeline { get; set; } InteractiveBrowserCredential PopInteractiveBrowserCredential { get; set; } } } \ No newline at end of file diff --git a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs index 60c23f9353..fdb2dc8cc9 100644 --- a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs +++ b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs @@ -126,9 +126,10 @@ private static async Task GetInteractiveBrowserCre interactiveOptions.TokenCachePersistenceOptions = GetTokenCachePersistenceOptions(authContext); var interactiveBrowserCredential = new InteractiveBrowserCredential(interactiveOptions); + var popTokenRequestContext = new PopTokenRequestContext(); if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) { - GraphSession.Instance.GraphRequestPopContext.PopTokenContext = await CreatePopTokenRequestContext(authContext); + popTokenRequestContext = await CreatePopTokenRequestContext(authContext); GraphSession.Instance.GraphRequestPopContext.PopInteractiveBrowserCredential = interactiveBrowserCredential; } @@ -143,7 +144,7 @@ private static async Task GetInteractiveBrowserCre authRecord = await Task.Run(() => { // Run the thread in MTA. - return interactiveBrowserCredential.AuthenticateAsync(GraphSession.Instance.GraphRequestPopContext.PopTokenContext, cancellationToken); + return interactiveBrowserCredential.AuthenticateAsync(popTokenRequestContext, cancellationToken); }); } else @@ -487,13 +488,13 @@ private static async Task CreatePopTokenRequestContext(I }); - var _popPipeline = HttpPipelineBuilder.Build(popPipelineOptions, new HttpPipelineTransportOptions()); - GraphSession.Instance.GraphRequestPopContext.Request = _popPipeline.CreateRequest(); - GraphSession.Instance.GraphRequestPopContext.Request.Method = RequestMethod.Parse(popMethod.Method.ToUpper()); - GraphSession.Instance.GraphRequestPopContext.Request.Uri.Reset(popResourceUri); + GraphSession.Instance.GraphRequestPopContext.PopPipeline = HttpPipelineBuilder.Build(popPipelineOptions, new HttpPipelineTransportOptions()); + var popRequest = GraphSession.Instance.GraphRequestPopContext.PopPipeline.CreateRequest(); + popRequest.Method = RequestMethod.Parse(popMethod.Method.ToUpper()); + popRequest.Uri.Reset(popResourceUri); // Refresh token logic --- end - var popContext = new PopTokenRequestContext(authContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(popResponse.Headers, "Pop").Nonce, request: GraphSession.Instance.GraphRequestPopContext.Request); + var popContext = new PopTokenRequestContext(authContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(popResponse.Headers, "Pop").Nonce, request: popRequest); return popContext; } } diff --git a/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs b/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs index b78ed1eb59..362a262abf 100644 --- a/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs +++ b/src/Authentication/Authentication/Handlers/AuthenticationHandler.cs @@ -27,6 +27,8 @@ internal class AuthenticationHandler : DelegatingHandler private const string BearerAuthenticationScheme = "Bearer"; private const string PopAuthenticationScheme = "Pop"; private int MaxRetry { get; set; } = 1; + private PopTokenRequestContext popTokenRequestContext; + private Request popRequest = GraphSession.Instance.GraphRequestPopContext.PopPipeline.CreateRequest(); public AzureIdentityAccessTokenProvider AuthenticationProvider { get; set; } @@ -53,7 +55,7 @@ protected override async Task SendAsync(HttpRequestMessage // Continuous nonce extraction on each request if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) { - GraphSession.Instance.GraphRequestPopContext.PopTokenContext = new PopTokenRequestContext(GraphSession.Instance.AuthContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(response.Headers, PopAuthenticationScheme).Nonce, request: GraphSession.Instance.GraphRequestPopContext.Request); + popTokenRequestContext = new PopTokenRequestContext(GraphSession.Instance.AuthContext.Scopes, isProofOfPossessionEnabled: true, proofOfPossessionNonce: WwwAuthenticateParameters.CreateFromAuthenticationHeaders(response.Headers, PopAuthenticationScheme).Nonce, request: popRequest); } // Check if response is a 401 & is not a streamed body (is buffered) @@ -76,14 +78,14 @@ private async Task AuthenticateRequestAsync(HttpRequestMessage httpRequestMessag { if (GraphSession.Instance.GraphOption.EnableATPoPForMSGraph) { - GraphSession.Instance.GraphRequestPopContext.Request.Method = RequestMethod.Parse(httpRequestMessage.Method.Method.ToUpper()); - GraphSession.Instance.GraphRequestPopContext.Request.Uri.Reset(httpRequestMessage.RequestUri); + popRequest.Method = RequestMethod.Parse(httpRequestMessage.Method.Method.ToUpper()); + popRequest.Uri.Reset(httpRequestMessage.RequestUri); foreach (var header in httpRequestMessage.Headers) { - GraphSession.Instance.GraphRequestPopContext.Request.Headers.Add(header.Key, header.Value.First()); + popRequest.Headers.Add(header.Key, header.Value.First()); } - var accessToken = await GraphSession.Instance.GraphRequestPopContext.PopInteractiveBrowserCredential.GetTokenAsync(GraphSession.Instance.GraphRequestPopContext.PopTokenContext, cancellationToken).ConfigureAwait(false); + var accessToken = await GraphSession.Instance.GraphRequestPopContext.PopInteractiveBrowserCredential.GetTokenAsync(popTokenRequestContext, cancellationToken).ConfigureAwait(false); httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue(PopAuthenticationScheme, accessToken.Token); } else diff --git a/src/Authentication/Authentication/Models/GraphRequestPopContext.cs b/src/Authentication/Authentication/Models/GraphRequestPopContext.cs index 0092543bb3..4be69f16e7 100644 --- a/src/Authentication/Authentication/Models/GraphRequestPopContext.cs +++ b/src/Authentication/Authentication/Models/GraphRequestPopContext.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------------ using Azure.Core; +using Azure.Core.Pipeline; using Azure.Identity; using System; using System.IO; @@ -15,8 +16,7 @@ internal class GraphRequestPopContext : IGraphRequestPopContext public Uri Uri { get; set; } public HttpMethod HttpMethod { get; set; } public AccessToken AccessToken { get; set; } - public PopTokenRequestContext PopTokenContext { get; set; } - public Request Request { get; set; } + public HttpPipeline PopPipeline { get; set; } public InteractiveBrowserCredential PopInteractiveBrowserCredential { get; set; } } From 5b84550e6c0c3fd85ae2344017a90a4392c8ccb0 Mon Sep 17 00:00:00 2001 From: "Taofeek F. Obafemi-Babatunde" Date: Thu, 25 Jul 2024 14:37:37 -0700 Subject: [PATCH 4/8] resolving issues with PS 7.4.4 --- .../Microsoft.Graph.Authentication.Core.csproj | 9 +++++---- src/Authentication/Authentication/Helpers/HttpHelpers.cs | 1 + .../Authentication/Microsoft.Graph.Authentication.nuspec | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj index b2a1da6c2a..5fdb61d076 100644 --- a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj +++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj @@ -11,11 +11,12 @@ true - + + - - - + + + diff --git a/src/Authentication/Authentication/Helpers/HttpHelpers.cs b/src/Authentication/Authentication/Helpers/HttpHelpers.cs index e54612ba0b..26d5a5ead9 100644 --- a/src/Authentication/Authentication/Helpers/HttpHelpers.cs +++ b/src/Authentication/Authentication/Helpers/HttpHelpers.cs @@ -54,6 +54,7 @@ private static HttpClient GetGraphHttpClient(AzureIdentityAccessTokenProvider au new NationalCloudHandler(), new ODataQueryOptionsHandler(), new HttpVersionHandler(), + //new CompressionHandler(), new RetryHandler(new RetryHandlerOption{ Delay = requestContext.RetryDelay, MaxRetry = requestContext.MaxRetry, diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec b/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec index 6c2e698b02..c8cf6124e3 100644 --- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec +++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec @@ -50,12 +50,14 @@ + + From b7f7c7b171b08a1046dc887b6f0a915b66c9bc52 Mon Sep 17 00:00:00 2001 From: Microsoft Graph DevX Tooling Date: Fri, 26 Jul 2024 12:51:44 +0300 Subject: [PATCH 5/8] Fixed pester test expected messages --- .../Authentication/test/Connect-MgGraph.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 index 382ad62a98..1b09fbfa6c 100644 --- a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 +++ b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 @@ -69,7 +69,7 @@ Describe 'Connect-MgGraph In Delegated Mode' { Describe 'Connect-MgGraph In Environment Variable Mode' { It 'Should throw exception when supported environment variables are not specified' { - { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*EnvironmentCredential authentication unavailable. Environment variables are not fully configured*" + { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*ClientSecretCredential authentication failed*" } It 'Should attempt to use configured environment variables' { { @@ -77,7 +77,7 @@ Describe 'Connect-MgGraph In Environment Variable Mode' { $Env:AZURE_CLIENT_SECRET = "Not_Valid" $Env:AZURE_TENANT_ID = "common" Connect-MgGraph -EnvironmentVariable -ErrorAction Stop - } | Should -Throw -ExpectedMessage "ClientSecretCredential authentication failed: " + } | Should -Throw -ExpectedMessage "*ClientSecretCredential authentication failed*" } } @@ -95,7 +95,7 @@ Describe 'Connect-MgGraph In App Mode' { Describe 'Connect-MgGraph Dependency Resolution' { It 'Should load Mg module side by side with Az module.' { { Connect-AzAccount -ApplicationId $RandomClientId -CertificateThumbprint "Invalid" -Tenant "Invalid" -ErrorAction Stop } | Should -Throw -ExpectedMessage "*Could not find tenant id*" - { Connect-MgGraph -TenantId "thisdomaindoesnotexist.com" -ErrorAction Stop -UseDeviceAuthentication } | Should -Throw -ExpectedMessage "DeviceCodeCredential authentication failed: " + { Connect-MgGraph -TenantId "thisdomaindoesnotexist.com" -ErrorAction Stop -UseDeviceAuthentication } | Should -Throw -ExpectedMessage "*DeviceCodeCredential authentication failed*" } } From ae0b0bab1d4705a195806b9e18e724aef495cb7a Mon Sep 17 00:00:00 2001 From: Microsoft Graph DevX Tooling Date: Fri, 26 Jul 2024 13:52:11 +0300 Subject: [PATCH 6/8] Updated expected message --- src/Authentication/docs/Connect-MgGraph.md | 46 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Authentication/docs/Connect-MgGraph.md b/src/Authentication/docs/Connect-MgGraph.md index 9ef5d0af7c..5e793b1f14 100644 --- a/src/Authentication/docs/Connect-MgGraph.md +++ b/src/Authentication/docs/Connect-MgGraph.md @@ -16,38 +16,40 @@ Microsoft Graph PowerShell supports two types of authentication: delegated and a ``` Connect-MgGraph [[-Scopes] ] [[-ClientId] ] [-TenantId ] [-ContextScope ] [-Environment ] [-UseDeviceCode] [-ClientTimeout ] [-NoWelcome] - [] + [-ProgressAction ] [] ``` ### AppCertificateParameterSet ``` Connect-MgGraph [-ClientId] [[-CertificateSubjectName] ] [[-CertificateThumbprint] ] - [-Certificate ] [-TenantId ] [-ContextScope ] [-Environment ] - [-ClientTimeout ] [-NoWelcome] [] + [-SendCertificateChain ] [-Certificate ] [-TenantId ] + [-ContextScope ] [-Environment ] [-ClientTimeout ] [-NoWelcome] + [-ProgressAction ] [] ``` ### IdentityParameterSet ``` Connect-MgGraph [[-ClientId] ] [-ContextScope ] [-Environment ] - [-ClientTimeout ] [-Identity] [-NoWelcome] [] + [-ClientTimeout ] [-Identity] [-NoWelcome] [-ProgressAction ] [] ``` ### AppSecretCredentialParameterSet ``` Connect-MgGraph [-ClientSecretCredential ] [-TenantId ] [-ContextScope ] - [-Environment ] [-ClientTimeout ] [-NoWelcome] [] + [-Environment ] [-ClientTimeout ] [-NoWelcome] [-ProgressAction ] + [] ``` ### AccessTokenParameterSet ``` Connect-MgGraph [-AccessToken] [-Environment ] [-ClientTimeout ] [-NoWelcome] - [] + [-ProgressAction ] [] ``` ### EnvironmentVariableParameterSet ``` Connect-MgGraph [-ContextScope ] [-Environment ] [-ClientTimeout ] - [-EnvironmentVariable] [-NoWelcome] [] + [-EnvironmentVariable] [-NoWelcome] [-ProgressAction ] [] ``` ## DESCRIPTION @@ -351,6 +353,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Scopes An array of delegated permissions to consent to. @@ -366,6 +383,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -SendCertificateChain +Include x5c header in client claims when acquiring a token to enable subject name / issuer based authentication using given certificate. + +```yaml +Type: Boolean +Parameter Sets: AppCertificateParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -TenantId The id of the tenant to connect to. You can also use this parameter to specify your sign-in audience. From 551a5610cf2b1dd095c80093eba9e0e5cbaf1821 Mon Sep 17 00:00:00 2001 From: Microsoft Graph DevX Tooling Date: Fri, 26 Jul 2024 14:02:16 +0300 Subject: [PATCH 7/8] Updated error message --- .../Authentication/test/Connect-MgGraph.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 index 1b09fbfa6c..a98601d51b 100644 --- a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 +++ b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 @@ -69,7 +69,7 @@ Describe 'Connect-MgGraph In Delegated Mode' { Describe 'Connect-MgGraph In Environment Variable Mode' { It 'Should throw exception when supported environment variables are not specified' { - { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*ClientSecretCredential authentication failed*" + { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*EnvironmentCredential authentication unavailable*" } It 'Should attempt to use configured environment variables' { { From 7df1cc093b8b1f41d5bc1aebe7c9c33ff5c2b021 Mon Sep 17 00:00:00 2001 From: "Taofeek F. Obafemi-Babatunde" Date: Mon, 10 Feb 2025 10:41:43 -0800 Subject: [PATCH 8/8] Updating docs --- .../Microsoft.Graph.Authentication.Core.csproj | 14 ++++++++------ .../Authentication/Helpers/HttpHelpers.cs | 1 - .../test/Connect-MgGraph.Tests.ps1 | 6 +++--- src/Authentication/docs/Connect-MgGraph.md | 16 +++++++--------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj index 5fdb61d076..d345b76688 100644 --- a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj +++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj @@ -4,7 +4,9 @@ 9.0 netstandard2.0;net8.0;net472 Microsoft.Graph.PowerShell.Authentication.Core - 2.12.0 + 2.25.0 + + true true @@ -12,11 +14,11 @@ - - - - - + + + + + diff --git a/src/Authentication/Authentication/Helpers/HttpHelpers.cs b/src/Authentication/Authentication/Helpers/HttpHelpers.cs index 26d5a5ead9..e54612ba0b 100644 --- a/src/Authentication/Authentication/Helpers/HttpHelpers.cs +++ b/src/Authentication/Authentication/Helpers/HttpHelpers.cs @@ -54,7 +54,6 @@ private static HttpClient GetGraphHttpClient(AzureIdentityAccessTokenProvider au new NationalCloudHandler(), new ODataQueryOptionsHandler(), new HttpVersionHandler(), - //new CompressionHandler(), new RetryHandler(new RetryHandlerOption{ Delay = requestContext.RetryDelay, MaxRetry = requestContext.MaxRetry, diff --git a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 index a98601d51b..382ad62a98 100644 --- a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 +++ b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 @@ -69,7 +69,7 @@ Describe 'Connect-MgGraph In Delegated Mode' { Describe 'Connect-MgGraph In Environment Variable Mode' { It 'Should throw exception when supported environment variables are not specified' { - { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*EnvironmentCredential authentication unavailable*" + { Connect-MgGraph -EnvironmentVariable -ErrorAction Stop } | Should -Throw -ExpectedMessage "*EnvironmentCredential authentication unavailable. Environment variables are not fully configured*" } It 'Should attempt to use configured environment variables' { { @@ -77,7 +77,7 @@ Describe 'Connect-MgGraph In Environment Variable Mode' { $Env:AZURE_CLIENT_SECRET = "Not_Valid" $Env:AZURE_TENANT_ID = "common" Connect-MgGraph -EnvironmentVariable -ErrorAction Stop - } | Should -Throw -ExpectedMessage "*ClientSecretCredential authentication failed*" + } | Should -Throw -ExpectedMessage "ClientSecretCredential authentication failed: " } } @@ -95,7 +95,7 @@ Describe 'Connect-MgGraph In App Mode' { Describe 'Connect-MgGraph Dependency Resolution' { It 'Should load Mg module side by side with Az module.' { { Connect-AzAccount -ApplicationId $RandomClientId -CertificateThumbprint "Invalid" -Tenant "Invalid" -ErrorAction Stop } | Should -Throw -ExpectedMessage "*Could not find tenant id*" - { Connect-MgGraph -TenantId "thisdomaindoesnotexist.com" -ErrorAction Stop -UseDeviceAuthentication } | Should -Throw -ExpectedMessage "*DeviceCodeCredential authentication failed*" + { Connect-MgGraph -TenantId "thisdomaindoesnotexist.com" -ErrorAction Stop -UseDeviceAuthentication } | Should -Throw -ExpectedMessage "DeviceCodeCredential authentication failed: " } } diff --git a/src/Authentication/docs/Connect-MgGraph.md b/src/Authentication/docs/Connect-MgGraph.md index 5e793b1f14..57730953e7 100644 --- a/src/Authentication/docs/Connect-MgGraph.md +++ b/src/Authentication/docs/Connect-MgGraph.md @@ -16,40 +16,38 @@ Microsoft Graph PowerShell supports two types of authentication: delegated and a ``` Connect-MgGraph [[-Scopes] ] [[-ClientId] ] [-TenantId ] [-ContextScope ] [-Environment ] [-UseDeviceCode] [-ClientTimeout ] [-NoWelcome] - [-ProgressAction ] [] + [] ``` ### AppCertificateParameterSet ``` Connect-MgGraph [-ClientId] [[-CertificateSubjectName] ] [[-CertificateThumbprint] ] - [-SendCertificateChain ] [-Certificate ] [-TenantId ] - [-ContextScope ] [-Environment ] [-ClientTimeout ] [-NoWelcome] - [-ProgressAction ] [] + [-Certificate ] [-TenantId ] [-ContextScope ] [-Environment ] + [-ClientTimeout ] [-NoWelcome] [] ``` ### IdentityParameterSet ``` Connect-MgGraph [[-ClientId] ] [-ContextScope ] [-Environment ] - [-ClientTimeout ] [-Identity] [-NoWelcome] [-ProgressAction ] [] + [-ClientTimeout ] [-Identity] [-NoWelcome] [] ``` ### AppSecretCredentialParameterSet ``` Connect-MgGraph [-ClientSecretCredential ] [-TenantId ] [-ContextScope ] - [-Environment ] [-ClientTimeout ] [-NoWelcome] [-ProgressAction ] - [] + [-Environment ] [-ClientTimeout ] [-NoWelcome] [] ``` ### AccessTokenParameterSet ``` Connect-MgGraph [-AccessToken] [-Environment ] [-ClientTimeout ] [-NoWelcome] - [-ProgressAction ] [] + [] ``` ### EnvironmentVariableParameterSet ``` Connect-MgGraph [-ContextScope ] [-Environment ] [-ClientTimeout ] - [-EnvironmentVariable] [-NoWelcome] [-ProgressAction ] [] + [-EnvironmentVariable] [-NoWelcome] [] ``` ## DESCRIPTION