Functions/Authentication/New-PASSession.ps1
# .ExternalHelp psPAS-help.xml function New-PASSession { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Gen2')] param( [parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2' )] [parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [parameter( Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Gen1' )] [parameter( Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Gen1Radius' )] [ValidateNotNullOrEmpty()] [PSCredential]$Credential, [parameter( Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1' )] [parameter( Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [Parameter( Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1SAML' )] [Alias('UseClassicAPI')] [switch]$UseGen1API, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1' )] [SecureString]$newPassword, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2SAML' )] [switch]$SAMLAuth, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2SAML' )] [Parameter( Mandatory = $true, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1SAML' )] [Alias('SAMLToken')] [String]$SAMLResponse, [Parameter( Mandatory = $True, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'shared' )] [switch]$UseSharedAuthentication, [Parameter( Mandatory = $true, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [bool]$useRadiusAuthentication, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [ValidateSet('CyberArk', 'LDAP', 'Windows', 'RADIUS', 'PKI')] [string]$type = 'CyberArk', [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [string]$OTP, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [ValidateSet('Append', 'Challenge')] [string]$OTPMode, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [ValidateLength(1, 1)] [string]$OTPDelimiter, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [ValidateSet('Password', 'OTP')] [string]$RadiusChallenge, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'integrated' )] [switch]$UseDefaultCredentials, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2' )] [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2Radius' )] [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'integrated' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen2SAML' )] [Boolean]$concurrentSession, [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1' )] [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'Gen1Radius' )] [ValidateRange(1, 100)] [int]$connectionNumber, [parameter( Mandatory = $true, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true )] [string]$BaseURI, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true )] [string]$PVWAAppName = 'PasswordVault', [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $false )] [switch]$SkipVersionCheck, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $false )] [X509Certificate]$Certificate, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $false )] [string]$CertificateThumbprint, [parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelinebyPropertyName = $true )] [switch]$SkipCertificateCheck ) BEGIN { #Ensure URL is in expected format #Remove trailing space and PasswordVault if provided in BaseUri $baseURI = $baseURI -replace '/$', '' $baseURI = $baseURI -replace '/PasswordVault$', '' #Build URL $Uri = "$baseURI/$PVWAAppName" #Hashtable to hold Logon Request $LogonRequest = @{ } #Define Logon Request Parameters $LogonRequest['Method'] = 'POST' $LogonRequest['SessionVariable'] = 'PASSession' $LogonRequest['UseDefaultCredentials'] = $UseDefaultCredentials.IsPresent $LogonRequest['SkipCertificateCheck'] = $SkipCertificateCheck.IsPresent If ($PSBoundParameters['type'] -eq 'Windows') { $LogonRequest['Credential'] = $Credential } If ($CertificateThumbprint) { $LogonRequest['CertificateThumbprint'] = $CertificateThumbprint } If ($Certificate) { $LogonRequest['Certificate'] = $Certificate } }#begin PROCESS { Switch ($PSCmdlet.ParameterSetName) { 'integrated' { $LogonRequest['Uri'] = "$Uri/api/Auth/Windows/Logon" #hardcode Windows for integrated auth #Construct Request Body #The only expected parameter should be concurrentSessions $LogonRequest['Body'] = $PSBoundParameters | Get-PASParameter -ParametersToKeep concurrentSession | ConvertTo-Json break } 'shared' { $LogonRequest['Uri'] = "$Uri/WebServices/auth/Shared/RestfulAuthenticationService.svc/Logon" break } 'Gen1SAML' { $LogonRequest['Uri'] = "$Uri/WebServices/auth/SAML/SAMLAuthenticationService.svc/Logon" #add token to header $LogonRequest['Headers'] = @{'Authorization' = $SAMLResponse } break } 'Gen2SAML' { #*For SAML auth #The only expected parameter should be concurrentSession & SAMLResponse $boundParameters = $PSBoundParameters | Get-PASParameter -ParametersToKeep concurrentSession, SAMLResponse #add required parameters $boundParameters.Add('apiUse', $true) If ( -not ($PSBoundParameters.ContainsKey('SAMLResponse'))) { #If no SAMLResponse provided #Get SAML Response from IdP #*https://gist.github.com/infamousjoeg/b44faa299ec3de65bdd1d3b8474b0649 $SAMLResponse = Get-PASSAMLResponse -URL $Uri #add SAMLResponse to boundParameters $boundParameters.Add('SAMLResponse', $SAMLResponse) } $LogonRequest['Body'] = $boundParameters $LogonRequest['ContentType'] = 'application/x-www-form-urlencoded' $LogonRequest['Uri'] = "$Uri/api/auth/SAML/Logon" break } ( { $PSItem -match '^Gen2' } ) { $LogonRequest['Uri'] = "$Uri/api/Auth/$type/Logon" } ( { $PSItem -match '^Gen1' } ) { $LogonRequest['Uri'] = "$Uri/WebServices/auth/Cyberark/CyberArkAuthenticationService.svc/Logon" } ( { $PSItem -match '^Gen' } ) { #Get request parameters $boundParameters = $PSBoundParameters | Get-PASParameter -ParametersToRemove Credential, SkipVersionCheck, SkipCertificateCheck, UseDefaultCredentials, CertificateThumbprint, BaseURI, PVWAAppName, OTP, type, OTPMode, OTPDelimiter, RadiusChallenge, Certificate #Add user name from credential object $boundParameters['username'] = $($Credential.UserName) #Add decoded password value from credential object $boundParameters['password'] = $($Credential.GetNetworkCredential().Password) #RADIUS Auth If ($PSCmdlet.ParameterSetName -match 'Radius$') { #OTP in Append Mode If (($PSBoundParameters.ContainsKey('OTP')) -and ($PSBoundParameters['OTPMode'] -eq 'Append')) { If ($PSBoundParameters.ContainsKey('OTPDelimiter')) { #Use specified delimiter to append OTP $Delimiter = $OTPDelimiter } Else { #delimit with comma by default $Delimiter = ',' } #Append OTP to password $boundParameters['password'] = "$($boundParameters['password'])$Delimiter$OTP" } #RADIUS Challenge Mode ElseIf (($PSBoundParameters.ContainsKey('OTP')) -and ($PSBoundParameters['OTPMode'] -eq 'Challenge')) { If ($RadiusChallenge -eq 'Password') { #Send OTP first + then Password $boundParameters['password'] = $OTP $OTP = $($Credential.GetNetworkCredential().Password) } } } #deal with newPassword SecureString If ($PSBoundParameters.ContainsKey('newPassword')) { #Include decoded password in request $boundParameters['newPassword'] = $(ConvertTo-InsecureString -SecureString $newPassword) } #Construct Request Body $LogonRequest['Body'] = $boundParameters | ConvertTo-Json break } } if ($PSCmdlet.ShouldProcess($LogonRequest['Uri'], 'Logon')) { try { #Send Logon Request $PASSession = Invoke-PASRestMethod @LogonRequest If ($null -ne $PASSession.UserName) { #*$PASSession is expected to be a string value #*For IIS Windows/PKI auth: #*An object with a username property will be returned if a secondary authentication is required #Use WebSession from initial request $LogonRequest.Remove('SessionVariable') $LogonRequest['WebSession'] = $Script:WebSession #Prepare auth request switch ( $true ) { ($PSCmdlet.ParameterSetName -match 'Radius$') { #RADIUS Secondary auth $LogonRequest['Uri'] = "$Uri/api/Auth/RADIUS/Logon" break } ($type -eq 'PKI') { #LDAP Secondary auth $LogonRequest['Uri'] = "$Uri/api/Auth/LDAP/Logon" break } } #Submit secondary auth request $PASSession = Invoke-PASRestMethod @LogonRequest } } catch { if ($PSItem.FullyQualifiedErrorId -notmatch 'ITATS542I') { #Throw all errors not related to ITATS542I throw $PSItem } Else { #ITATS542I is expected for RADIUS Challenge #Use WebSession from initial request $LogonRequest.Remove('SessionVariable') $LogonRequest['WebSession'] = $Script:WebSession #Collect values required to respond to the challenge $RADIUSResponse = @{} $RADIUSResponse['LogonRequest'] = $LogonRequest $RADIUSResponse['Message'] = $($PSItem.Exception.Message) #Include any OTP value provided in the RADIUS Response If ($PSBoundParameters.ContainsKey('OTP')) { #!If $RadiusChallenge = Password, $OTP will be password value $RADIUSResponse['OTP'] = $OTP } #Respond to RADIUS challenge $PASSession = Send-RADIUSResponse @RADIUSResponse } } finally { #If Logon Result If ($PASSession) { If ($null -ne $PASSession.UserName) { throw "No Session Token for user $($PASSession.UserName)" } #Version 10 If ($PASSession.length -ge 180) { #V10 Auth Token. $CyberArkLogonResult = $PASSession } #Shared Auth ElseIf ($PASSession.LogonResult) { #Shared Auth LogonResult. $CyberArkLogonResult = $PASSession.LogonResult } #Classic Else { #Classic CyberArkLogonResult $CyberArkLogonResult = $PASSession.CyberArkLogonResult } #BaseURI set in Module Scope Set-Variable -Name BaseURI -Value $Uri -Scope Script #Auth token added to WebSession $Script:WebSession.Headers['Authorization'] = [string]$CyberArkLogonResult #Initial Value for Version variable [System.Version]$Version = '0.0' if ( -not ($SkipVersionCheck)) { Try { #Get CyberArk ExternalVersion number. [System.Version]$Version = Get-PASServer -ErrorAction Stop | Select-Object -ExpandProperty ExternalVersion } Catch { [System.Version]$Version = '0.0' } } #Version information available in module scope. Set-Variable -Name ExternalVersion -Value $Version -Scope Script } } } }#process END { }#end } |