Public/New-GuacSession.ps1
|
function New-GuacSession { <# .SYNOPSIS Authenticates to an Apache Guacamole instance and returns a session object. .DESCRIPTION Performs the Guacamole REST login (POST /api/tokens) with the supplied credentials and returns a [N2C_GuacAdmin_GuacSession] object holding the authentication token, the authenticated username, the default data source (AuthenticationProvider identifier) from the token response, and all available data sources. The returned session object is the single source of authentication state for all other cmdlets: pass it via -Session, or rely on the module default (this cmdlet registers the new session as the default for its server, the "-CmsSession pattern"). Multiple servers and multiple users can be worked with in one process; each server keeps its own default session. The password is only accepted as part of a PSCredential; plaintext string passwords are deliberately not supported. If TOTP two-factor authentication is enabled on the instance, supply -TotpCode (a SecureString). Transport options (TLS client certificate, proxy, timeout) are carried by the session object and applied to every request made with it. Reference (Apache Guacamole 1.6.0): - guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java (POST /api/tokens; form parameters username, password, token) - extensions/guacamole-auth-totp/.../form/AuthenticationCodeField.java (the optional "guac-totp" form parameter) - guacamole/src/main/java/org/apache/guacamole/rest/auth/APIAuthenticationResult.java (response: authToken, username, dataSource, availableDataSources) .EXAMPLE $cred = Get-Credential $session = New-GuacSession -Server https://guac.example.com/guacamole -Credential $cred .EXAMPLE $session = New-GuacSession -Server https://guac.example.com/guacamole ` -Credential $cred -TotpCode (Read-Host -Prompt 'TOTP code' -AsSecureString) .EXAMPLE $session = New-GuacSession -Server https://guac.example.com/guacamole ` -Credential $cred -DataSource ldap #> [CmdletBinding()] [OutputType([N2C_GuacAdmin_GuacSession])] param ( [Parameter(Mandatory = $true, Position = 0)] [string] $Server, [Parameter(Mandatory = $true, Position = 1)] [System.Management.Automation.CredentialAttribute()] [System.Management.Automation.PSCredential] $Credential, [Parameter(Mandatory = $false)] [AllowNull()] [System.Security.SecureString] $TotpCode, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $DataSource = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $CertificateThumbprint = [string]::Empty, [Parameter(Mandatory = $false)] [AllowNull()] [System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Proxy = [string]::Empty, [Parameter(Mandatory = $false)] [AllowNull()] [System.Management.Automation.PSCredential] $ProxyCredential, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $NoProxy = [string]::Empty, [Parameter(Mandatory = $false)] [ValidateRange(1, 3600)] [int] $TimeoutSec = 30 ) $normalizedServer = ConvertTo-GuacServerUrl -Server $Server # Build the login form body (username/password, optional guac-totp). # The plaintext password exists only inside the form body and the # WebRequestSession; it is never stored on the session object. $password = ConvertFrom-GuacSecureString -SecureString $Credential.Password $formFields = [ordered]@{ 'username' = $Credential.UserName 'password' = $password } if ($null -ne $TotpCode) { $formFields['guac-totp'] = ConvertFrom-GuacSecureString -SecureString $TotpCode } $formBody = ConvertTo-GuacFormUrlEncoded -Fields $formFields Write-Verbose ("N2C.GuacAdmin: authenticating to {0} as '{1}'" -f ($normalizedServer, $Credential.UserName)) # Anonymous call (no token yet). The server base URL is passed directly. try { $authResult = Invoke-GuacRest -Server $normalizedServer -Method POST -Path '/api/tokens' ` -Body $formBody -ContentType 'application/x-www-form-urlencoded' ` -CertificateThumbprint $CertificateThumbprint -Certificate $Certificate ` -Proxy $Proxy -ProxyCredential $ProxyCredential -NoProxy $NoProxy -TimeoutSec $TimeoutSec } finally { # Wipe the local plaintext password as soon as it is no longer needed. $password = $null } if ($null -eq $authResult) { throw ($script:GuacRestExceptionType::new( 'Guacamole authentication failed: the server returned no authentication result.' )) } $authToken = $authResult.authToken $username = $authResult.username $defaultDataSource = $authResult.dataSource $availableDataSources = @($authResult.availableDataSources) if ($null -eq $availableDataSources) { $availableDataSources = @() } if ([string]::IsNullOrEmpty($authToken)) { throw ($script:GuacRestExceptionType::new( 'Guacamole authentication failed: the server returned no authToken.' )) } # Default the data source from the token response; -DataSource overrides. if ([string]::IsNullOrEmpty($DataSource)) { $DataSource = $defaultDataSource } elseif ($availableDataSources.Count -gt 0 -and $availableDataSources -notcontains $DataSource) { throw ($script:GuacRestExceptionType::new( ("Data source '{0}' is not available for this user. Available: {1}" -f $DataSource, ($availableDataSources -join ', ')) )) } $session = $script:GuacSessionType::new() $session.Server = $normalizedServer $session.Token = $authToken $session.DataSource = $DataSource $session.Username = $username $session.AvailableDataSources = $availableDataSources $session.CertificateThumbprint = $CertificateThumbprint $session.Certificate = $Certificate $session.Proxy = $Proxy $session.ProxyCredential = $ProxyCredential $session.NoProxy = $NoProxy $session.TimeoutSec = $TimeoutSec # Register as the default session for this server (the -CmsSession pattern). Set-GuacSessionState -Server $normalizedServer -Session $session Write-Verbose ("N2C.GuacAdmin: session established for user '{0}' (data source '{1}', token={2})" -f ($username, $DataSource, (ConvertTo-GuacMaskedSecret -Value $authToken))) return $session } |