Internals/ADAL/Adal.Class.ps1
# ---------------------------------------------------------------------------- # AadContext (AAD Helper Class) # class AadContext { [string]$TenantName [string]$ClientID [string]$Redirect [string]$ResourceId [string]$AadInstance = "https://login.microsoftonline.com" [string]$AccessToken [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]$authContext = $null AadContext($authority) { #Build the auth context and get the result $TokenCache = New-Object -TypeName "Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache" $this.authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority, $TokenCache } # ---------------------------------------------------------------------------- # AcquireToken # Method to help get Azure AD tokens (Interactive flow) [string]AcquireToken([string]$_ResourceId, [string]$_ClientID, [string]$_RedirectURI, [string]$_PromptBehavior, [string]$_UserId, [string]$_ExtraQueryParams) { $ReturnObject = @{} $ReturnObject.Resource = $_ResourceId $ReturnObject.ClientID = $_ClientID $ReturnObject.PromptBehavior = $_PromptBehavior $ReturnObject.UserId = $_UserId $ReturnObject.ExtraQueryParams = $_ExtraQueryParams if($null -eq $_RedirectURI -or $_RedirectURI -eq "") { $_RedirectURI = "https://login.microsoftonline.com/common/oauth2/nativeclient" } if(-not $_PromptBehavior) { $_PromptBehavior = "Auto" } $promptBehavior = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior" # Set UserIdentifier $UserIdentifier = $null if($_UserId) { $UserType = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType]::RequiredDisplayableId $UserIdentifier = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList $_UserId,$UserType } # If UserIdentifier not set yet from above... if(-not $UserIdentifier) { $UserIdentifier = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier]::AnyUser } $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList $promptBehavior::$_PromptBehavior Try { if($_UserId -and $_ExtraQueryParams) { $RebuildQueryParams = @() $SplitQueryParams = $_ExtraQueryParams.Split("&") foreach($item in $SplitQueryParams) { if(-not ($item -match "login_hint")) { $RebuildQueryParams += $item } } $_ExtraQueryParams = $RebuildQueryParams -join "&" } if(-not $_RedirectURI) {$_RedirectURI = $null} $request = $this.authContext.AcquireTokenAsync($_ResourceId, $_ClientID, $_RedirectURI, $platformParameters, $UserIdentifier, $_ExtraQueryParams) $result = $request.GetAwaiter().GetResult() $ReturnObject.AccessToken = $result.AccessToken $ReturnObject.Authority = $result.Authority $ReturnObject.IdToken = $result.IdToken $ReturnObject.TenantId = $result.TenantId $ReturnObject.ExpiresOn = $result.ExpiresOn.ToString() $ReturnObject.DisplayableId = $result.UserInfo.DisplayableId $ReturnObject.UniqueId = $result.UserInfo.UniqueId } Catch #[System.Management.Automation.MethodInvocationException] { $ReturnObject.Error = $true $ReturnObject.ErrorDetails = $_ } #Return the authentication token return ($ReturnObject | ConvertTo-Json) } # ---------------------------------------------------------------------------- # AcquireToken - CLIENT CREDENTIALS [string]AcquireToken([string]$_ResourceId, [string]$_ClientID, [string]$_ClientSecret) { $ReturnObject = @{} $ReturnObject.Resource = $_ResourceId $ReturnObject.ClientID = $_ClientID $_AadInstance = $this.AadInstance if($null -eq $_ClientID -or $_ClientID -eq "") { throw "Client ID required!" } if($null -eq $_ClientSecret -or $_ClientSecret -eq "") { throw "Client Secret required!" } if($null -eq $_ResourceId -or $_ResourceId -eq "") { throw "Resource Id required!" } $AdClientCreds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential" -ArgumentList $_ClientID, $_ClientSecret Write-Verbose "Attempting client credentials authentication" $result = @{} try { $request = $this.authContext.AcquireTokenAsync($_ResourceId, $AdClientCreds) $result = $request.GetAwaiter().GetResult() $ReturnObject.AccessToken = $result.AccessToken $ReturnObject.Authority = $result.Authority $ReturnObject.IdToken = $result.IdToken $ReturnObject.TenantId = $result.TenantId $ReturnObject.ExpiresOn = $result.ExpiresOn.ToString() } Catch #[System.Management.Automation.MethodInvocationException] { $ReturnObject.Error = $true $ReturnObject.ErrorDetails = $_ } #Return the authentication token return ($ReturnObject | ConvertTo-Json) } # ---------------------------------------------------------------------------- # AcquireTokenUsingUsernameAndPassword # Method to help get Azure AD tokens (Interactive flow) [string]AcquireTokenUsingUsernameAndPassword([string]$_ResourceId, [string]$_ClientID, [string]$_UserId, [SecureString]$_Password) { "STARTING::AcquireTokenUsingUsernameAndPassword" | Log-AadSupportRunspace $ReturnObject = @{} $ReturnObject.Resource = $_ResourceId $ReturnObject.ClientID = $_ClientID $ReturnObject.UserId = $_UserId $UserPasswordCredential = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential]::new($_UserId, $_Password) Try { # Acquire Token $this.authContext | ConvertTo-Json | Log-AadSupportRunspace $request = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($this.authContext, $_ResourceId, $_ClientID, $UserPasswordCredential) $result = $request.GetAwaiter().GetResult() # Get Return Result Ready $ReturnObject.AccessToken = $result.AccessToken $ReturnObject.Authority = $result.Authority $ReturnObject.IdToken = $result.IdToken $ReturnObject.TenantId = $result.TenantId $ReturnObject.ExpiresOn = $result.ExpiresOn.ToString() $ReturnObject.DisplayableId = $result.UserInfo.DisplayableId $ReturnObject.UniqueId = $result.UserInfo.UniqueId } Catch #[System.Management.Automation.MethodInvocationException] { $ReturnObject.Error = $true $ReturnObject.ErrorDetails = $_ } #Return the authentication token return ($ReturnObject | ConvertTo-Json) } # ---------------------------------------------------------------------------- # AcquireToken - Acquire Token Silently [string]AcquireSilentToken([string]$_ResourceId, [string]$_ClientID, [string]$_UserId) { $ReturnObject = @{} $ReturnObject.Resource = $_ResourceId $ReturnObject.ClientID = $_ClientID $ReturnObject.UserId = $_UserId $_TenantName = $this.TenantName $_AadInstance = $this.AadInstance if($null -eq $_ClientID -or $_ClientID -eq "") { throw "Client ID required!" } if($null -eq $_ResourceId -or $_ResourceId -eq "") { throw "Resource Id required!" } # Set UserIdentifier if(-not $_UserId) { $UserIdentifier = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier]::AnyUser } else { $UserType = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType]::RequiredDisplayableId $UserIdentifier = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList $_UserId,$UserType } #Build the logon URL with the tenant name $authority = "$_AadInstance/$_TenantName" Write-Verbose "Attempting authentication" try { $request = $this.authContext.AcquireTokenSilentAsync($_ResourceId, $_ClientID, $UserIdentifier) $result = $request.GetAwaiter().GetResult() $ReturnObject.AccessToken = $result.AccessToken $ReturnObject.Authority = $result.Authority $ReturnObject.IdToken = $result.IdToken $ReturnObject.TenantId = $result.TenantId $ReturnObject.ExpiresOn = $result.ExpiresOn.ToString() $ReturnObject.DisplayableId = $result.UserInfo.DisplayableId $ReturnObject.UniqueId = $result.UserInfo.UniqueId } Catch #[System.Management.Automation.MethodInvocationException] { if($this.authContext.TokenCache.Count -gt 0) { "Cache is NOT empty. Silent failed probably because of different ClientId or UserId specified!" | Log-AadSupportRunspace } $ReturnObject.Error = $true $ReturnObject.ErrorDetails = $_ } #Return the authentication token return ($ReturnObject | ConvertTo-Json) } } <# ################################################## AAD SUPPORT FACING FUNCTIONS TO GET TOKEN #################################################### #> <# ## USER DELEGATED FLOW Get-AadSupportTokenForUser -Authority "https://login.microsoftonline.com/williamfiddes.onmicrosoft.com" -ClientId "83258bc7-b7fd-4627-ae9b-e3bd5d550572" -ResourceId "https://graph.microsoft.com" -RedirectURI "https://login.microsoftonline.com/common/oauth2/nativeclient" #> function Get-AadSupportTokenForUser { [CmdletBinding(DefaultParameterSetName="Default")] param ( [string]$Authority, [string]$ResourceId, [string]$ClientId, [string]$RedirectURI, [string]$PromptBehavior, [string]$UserId, [string]$ExtraQueryParameters ="" ) "STARTING::Get-AadSupportTokenForUser" | Log-AadSupportRunspace "Authority::$Authority" | Log-AadSupportRunspace "ResourceId::$ResourceId" | Log-AadSupportRunspace "ClientId::$ClientId" | Log-AadSupportRunspace "RedirectURI::$RedirectURI" | Log-AadSupportRunspace "PromptBehavior::$PromptBehavior" | Log-AadSupportRunspace "UserId::$UserId" | Log-AadSupportRunspace "ExtraQueryParameters::$ExtraQueryParameters" | Log-AadSupportRunspace $context = GetOrBuildAuthenticationContext -Authority $Authority $AuthenticationResult = "" try { if($PromptBehavior -ne "Always") { $AuthenticationResult = $context.AcquireSilentToken($ResourceId,$ClientId,$UserId) | ConvertFrom-Json $AuthenticationResult | ConvertTo-Json | Log-AadSupportRunspace } if($AuthenticationResult.Error -or $PromptBehavior -eq "Always") { $AuthenticationResult = $context.AcquireToken($ResourceId,$ClientId,$RedirectURI,$PromptBehavior,$UserId, $ExtraQueryParameters ) | ConvertFrom-Json $AuthenticationResult | ConvertTo-Json | Log-AadSupportRunspace } HandleAuthenticationResult -Authority $Authority -AuthenticationResult $AuthenticationResult } catch { try { $AuthenticationResult = $context.AcquireToken($ResourceId,$ClientId,$RedirectURI,$PromptBehavior,$UserId, $ExtraQueryParameters ) | ConvertFrom-Json $AuthenticationResult | ConvertTo-Json | Log-AadSupportRunspace } catch { return @{ Error = $true ErrorDetails = $_ } } } return $AuthenticationResult } <# ## ROPC/WIA (NON-INTERACTIVE) FLOW #> function Get-AadSupportTokenForUserWithPassword { [CmdletBinding(DefaultParameterSetName="Default")] param ( [string]$Authority, [string]$ResourceId, [string]$ClientId, [string]$UserId, [SecureString]$Password ) "STARTING::Get-AadSupportTokenForUserWithPassword" | Log-AadSupportRunspace "Authority::$Authority" | Log-AadSupportRunspace "ResourceId::$ResourceId" | Log-AadSupportRunspace "ClientId::$ClientId" | Log-AadSupportRunspace "UserId::$UserId" | Log-AadSupportRunspace [AadContext]$context = GetOrBuildAuthenticationContext -Authority $Authority try { $AuthenticationResult = $context.AcquireTokenUsingUsernameAndPassword($ResourceId,$ClientId, $UserId, $Password) | ConvertFrom-Json $AuthenticationResult | ConvertTo-Json | Log-AadSupportRunspace HandleAuthenticationResult -Authority $Authority -AuthenticationResult $AuthenticationResult return $AuthenticationResult } catch { return @{ Error = $true ErrorDetails = $_ } } } <# ## CLIENT CREDENTIAL #> function Get-AadSupportTokenForClient { [CmdletBinding(DefaultParameterSetName="Default")] param ( [string]$Authority, [string]$ResourceId, [string]$ClientId, [string]$ClientSecret ) $context = GetOrBuildAuthenticationContext -Authority $Authority $AuthenticationResult = "" try { $AuthenticationResult = $context.AcquireToken($ResourceId,$ClientId,$ClientSecret) | ConvertFrom-Json } catch { return @{ Error = $true ErrorDetails = $_ } } return $AuthenticationResult } <### HELPER FUNCTIONS ###> function GetOrBuildAuthenticationContext { Param($Authority) if(!$Global:AadSupportAuthenticationContext) { "GetOrBuildAuthenticationContext::Creating Authentication Context Hashtable" | Log-AadSupportRunspace $Global:AadSupportAuthenticationContext = [hashtable]::new() } if(!$Global:AadSupportAuthenticationContext[$Authority]) { "GetOrBuildAuthenticationContext::Creating Authentication Context for '$Authority'" | Log-AadSupportRunspace $Global:AadSupportAuthenticationContext[$Authority] = [AadContext]::new($Authority) } "GetOrBuildAuthenticationContext::Grabbed Authentication Context for '$Authority'" | Log-AadSupportRunspace $Global:AadSupportAuthenticationContext[$Authority] | ConvertTo-Json | Log-AadSupportRunspace return [AadContext]$Global:AadSupportAuthenticationContext[$Authority] } function HandleAuthenticationResult { Param( $Authority, $AuthenticationResult ) $Global:AadSupportAuthenticationContext[$AuthenticationResult.Authority] = $Global:AadSupportAuthenticationContext[$Authority] #$index = $Global:AadSupportAuthenticationContext.Keys.IndexOf($Authority) #$Global:AadSupportAuthenticationContext[$index] = $AuthenticationResult.Authority } |