Public/New-IDSession.ps1
# .ExternalHelp IdentityCommand-help.xml Function New-IDSession { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Actual legitimate use of Write-Host')] [CmdletBinding(SupportsShouldProcess)] param( #tenant_url [parameter( Mandatory = $true, ValueFromPipelinebyPropertyName = $true )] [ValidateNotNullOrEmpty()] [String]$tenant_url, #User Creds [Parameter( Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Credential' )] [ValidateNotNullOrEmpty()] [PSCredential]$Credential, #SAML Assertion [Parameter( Mandatory = $true, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'SAML' )] [String]$SAMLResponse ) Begin { #Remove WebSession which may exist in module scope $ISPSSSession.WebSession = $null $LogonRequest = @{ } $LogonRequest['Method'] = 'POST' $LogonRequest['SessionVariable'] = 'IDSession' } Process { #Ensure URL is in expected format #Remove trailing space if provided in Url $tenant_url = $tenant_url -replace '/$', '' #Set Module Scope variables $ISPSSSession.tenant_url = $tenant_url Set-Variable -Name Version -Value '1.0' -Scope Script $LogonRequest['Headers'] = @{'accept' = '*/*' } #Must be passed in order to get the parameters needed for OOB IdP auth $LogonRequest['Headers'].Add('OobIdPAuth', $true) switch ($PSCmdlet.ParameterSetName) { 'Credential' { #*Start Authentication $IDSession = $LogonRequest | Start-Authentication -Credential $Credential break } 'SAML' { #*Send SAML Assertion $IDSession = $LogonRequest | Start-SamlAuthentication -SAMLResponse $SAMLResponse break } } #Set request properties for Next authentication stage. $LogonRequest.Remove('SessionVariable') $LogonRequest['Headers'].Add('X-IDAP-NATIVE-CLIENT', $true) #Set Module Scope variables $ISPSSSession.TenantId = $IDSession.TenantId $ISPSSSession.SessionId = $IDSession.SessionId #? does SessionId need to be available in script scope? switch ($PSCmdlet.ParameterSetName) { 'Credential' { #IdpRedirectShortUrl is only included in the response if the OobIdPAuth header is set to true if ($IDSession.IdpRedirectShortUrl) { Write-Host @" You are being redirected to your browser in order to authenticate to your external identity provider. If your browser does not open, click on the below URL to navigate to your identity provider. $($IDSession.IdpRedirectShortUrl) "@ #Launches the user's default browser and navigates it to the external identity provider Start-Process $IDSession.IdpRedirectShortUrl $OobAuthStatusRequest = @{ } $OobAuthStatusRequest['Method'] = 'POST' #Undocumented endpoint for checking the IdpLoginSessionId's status. Sniffed out from the ark-sdk-python project $OobAuthStatusRequest['Uri'] = "$tenant_url/Security/OobAuthStatus" #We need the cookies the server provides in the same response it provides the IdpAuth information $OobAuthStatusRequest['WebSession'] = $ISPSSSession.WebSession $OobAuthStatusRequest['Body'] = @{SessionId = $IDSession.IdpLoginSessionId} | ConvertTo-Json $IDSession = Invoke-IDRestMethod @OobAuthStatusRequest while ($IDSession.State -ne 'Success') { Start-Sleep 2 $IDSession = Invoke-IDRestMethod @OobAuthStatusRequest } break } #The MFA Bit - keep a reference to $IDSession for the MFA Package $ThisSession = $IDSession for ($Challenge = 0; $Challenge -lt $(($ThisSession.Challenges).Count); $Challenge++) { #Iterate through presented challenges if ($($IDSession.Summary) -eq 'NewPackage') { #Initialise loop and $ThisSession if NewPackage Challenges are presented $Challenge = 0 $ThisSession = $IDSession if ($null -ne $ThisSession.EventDescription) { Write-Warning -Message $ThisSession.EventDescription } } #Get Current Challenge Mechanisms $Mechanisms = $ThisSession.Challenges[$Challenge] | Select-Object -ExpandProperty Mechanisms #select challenge mechanism $Mechanism = Select-ChallengeMechanism -Mechanisms $Mechanisms try { #answer challenge mechanism $Answer = Get-MechanismAnswer -Mechanism $Mechanism -Credential $Credential #*Advance Authentication $IDSession = $LogonRequest | Start-AdvanceAuthentication -Mechanism $Mechanism -Answer $Answer } catch { throw $PSItem } if ($($IDSession.Summary) -eq 'NewPackage') { #New Package Recieved, decrement counter so we go round the loop again to evaluate. $Challenge-- } } break } 'SAML' { #*Get Saml ID Token $IDSession = $LogonRequest | Complete-SamlAuthentication break } } switch ($IDSession.Summary) { 'NoncommitalSuccess' { Write-Host $IDSession.ClientMessage break } default { if ($null -ne $IDSession) { $result = $IDSession | Select-Object -Last 1 | Add-CustomType -Type IdCmd.ID.Session #Add GetWebSession ScriptMethod $result | Add-Member -MemberType ScriptMethod -Name GetWebSession -Value { (Get-IDSession).WebSession } -Force #Add GetToken ScriptMethod to output Bearer Token $result | Add-Member -MemberType ScriptMethod -Name GetToken -Value { Write-Output @{Authorization = "Bearer $($this.Token)" } } -Force #Record authenticated User name, Session Start Time & add Authorization header $ISPSSSession.User = $result.User $ISPSSSession.StartTime = Get-Date $ISPSSSession.WebSession.Headers.Add('Authorization', "Bearer $($result.Token)") #Return the result $result } break } } } #process End { } #end } |