Skip to content

Commit 4ec71ea

Browse files
authored
Enhance token management and add Disconnect-AzResourceGraph function (#5)
* Enhance token management and add Disconnect-AzResourceGraph function * Add tests and update changelog
1 parent 266bb3e commit 4ec71ea

File tree

6 files changed

+85
-5
lines changed

6 files changed

+85
-5
lines changed

AzResourceGraph/Private/Assert-AzureConnection.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function Assert-AzureConnection {
6565
# We can therefore safely remove the Interactive parameter from the local LocalTokenSplat
6666
if ($LocalTokenSplat.ContainsKey('Interactive')) {
6767
$LocalTokenSplat.Remove('Interactive')
68+
$LocalTokenSplat.Remove('ClientId')
6869
}
6970

7071
$NewToken = Get-AzToken @LocalTokenSplat -ErrorAction 'Stop'

AzResourceGraph/Private/Test-AzureToken.ps1

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ function Test-AzureToken {
4646
)
4747
return (
4848
$null -ne $Token -and
49-
$Token.ExpiresOn -ge [System.DateTimeOffset]::Now.AddMinutes($MinValid) -and
50-
$Token.Claims['aud'] -eq $Resource
49+
$Token.ExpiresOn.UtcDateTime -ge [System.DateTimeOffset]::Now.AddMinutes($MinValid).UtcDateTime -and
50+
(
51+
# Due to AzAuth not showing correct aud claim when using Interactive and TokenCache we check either aud or scope
52+
# https://github.com/PalmEmanuel/AzAuth/issues/137
53+
$Resource -eq $Token.Claims['aud'] -or
54+
$Token.Scopes -contains "$Resource/.default"
55+
)
5156
)
5257
}

AzResourceGraph/Public/Connect-AzResourceGraph.ps1

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Client secret string associated with the service principal.
3232
Switch indicating that the command should acquire a token using the
3333
Azure Managed Identity assigned to the current VM / App Service / container.
3434
35+
.PARAMETER ManagementEndpoint
36+
Endpoint used for management. This is used for the Audience claim when authenticating to Azure.
37+
For global Azure, this should be left as the default of 'https://management.azure.com'.
38+
For Azure China, use 'https://management.chinacloudapi.cn' and for US Government Cloud use 'https://management.usgovcloudapi.net'.
39+
3540
.EXAMPLE
3641
# 1. Interactive sign-in (prompts user)
3742
Connect-AzResourceGraph
@@ -82,13 +87,20 @@ function Connect-AzResourceGraph {
8287
[string]$ClientSecret,
8388

8489
[Parameter(Mandatory, ParameterSetName = 'ManagedIdentity')]
85-
[switch]$ManagedIdentity
90+
[switch]$ManagedIdentity,
91+
92+
[Parameter(ParameterSetName = 'ManagedIdentity')]
93+
[Parameter(ParameterSetName = 'Interactive')]
94+
[Parameter(ParameterSetName = 'Certificate')]
95+
[Parameter(ParameterSetName = 'ClientSecret')]
96+
$ManagementEndpoint = 'https://management.azure.com'
8697
)
8798

8899
# Set up module-scoped variables for getting tokens
89100
$script:TokenSplat = @{}
90101
$script:CertificatePath = $null
91102

103+
$script:TokenSplat['Resource'] = $ManagementEndpoint
92104
$script:TokenSplat['ClientId'] = $ClientId
93105
if ($PSBoundParameters.ContainsKey('Tenant')) {
94106
$script:TokenSplat['TenantId'] = $Tenant
@@ -109,6 +121,7 @@ function Connect-AzResourceGraph {
109121
}
110122
if ($PSCmdlet.ParameterSetName -eq 'Interactive') {
111123
$script:TokenSplat['Interactive'] = $true
124+
$script:TokenSplat['TokenCache'] = 'AzResourceGraph'
112125
}
113126
if ($ManagedIdentity.IsPresent) {
114127
$script:TokenSplat['ManagedIdentity'] = $true
@@ -117,4 +130,7 @@ function Connect-AzResourceGraph {
117130
$script:Token = Get-AzToken @script:TokenSplat
118131
# Save the source of the token to module scope for AssertAzureConnection to know how to refresh it
119132
$script:TokenSource = 'Module'
133+
if ($script:TokenSplat['Interactive'] -eq $true) {
134+
$script:TokenSplat['UserName'] = $script:Token.Identity
135+
}
120136
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<#
2+
.SYNOPSIS
3+
Disconnects the current PowerShell session from Azure Resource Graph and clears cached access token in memory.
4+
5+
.DESCRIPTION
6+
Disconnect-AzResourceGraph removes any stored session information and resets sessions configuration.
7+
8+
.EXAMPLE
9+
# 1. Disconnect and clear session information
10+
Disconnect-AzResourceGraph
11+
12+
#>
13+
function Disconnect-AzResourceGraph {
14+
[CmdletBinding()]
15+
param ()
16+
17+
$script:TokenSplat = @{}
18+
$script:TokenSource = 'Global'
19+
$script:Token = $null
20+
$script:CertificatePath = $null
21+
}

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
## [Unreleased]
77

8-
### Added
9-
- Initial release of AzResourceGraph module.
8+
### Fixed
9+
- Fixed Auth problems
10+
11+
## [0.1.1] - 2025-05-14
1012

1113
### Changed
1214
- Removed space from tags in module manifest
15+
16+
## [0.1.0] - 2025-05-14
17+
18+
### Added
19+
- Initial release of AzResourceGraph module.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
BeforeAll {
2+
Import-Module -FullyQualifiedName "$PSScriptRoot/../../../output/module/AzResourceGraph"
3+
}
4+
5+
Describe 'Disconnect-AzResourceGraph' {
6+
InModuleScope 'AzResourceGraph' {
7+
BeforeEach {
8+
# Mock the Get-AzToken function to avoid actual authentication
9+
Mock 'Get-AzToken' {
10+
@{
11+
Token = 'dummy'
12+
ExpiresOn = [System.DateTimeOffset]::Now.AddHours(1)
13+
Claims = @{
14+
aud = 'myApp'
15+
}
16+
}
17+
}
18+
}
19+
Context 'Successful token removal' {
20+
It 'Resets any token information' {
21+
Connect-AzResourceGraph
22+
Disconnect-AzResourceGraph
23+
$script:TokenSplat.Keys.Count | Should -be 0
24+
$null -eq $script:CertificatePath | Should -be $true
25+
$null -eq $script:Token | Should -be $true
26+
}
27+
}
28+
29+
}
30+
}

0 commit comments

Comments
 (0)