Public/New-TppToken.ps1
<# .SYNOPSIS Get a new access token or refresh an existing one .DESCRIPTION Get an access token and refresh token (if enabled) to be used with New-VenafiSession or other scripts/utilities that take such a token. You can also refresh an existing access token if you have the associated refresh token. Authentication can be provided as integrated, credential, or certificate. .PARAMETER AuthServer Auth server or url, eg. venafi.company.com .PARAMETER ClientId Applcation Id configured in Venafi for token-based authentication .PARAMETER Scope Hashtable with Scopes and privilege restrictions. The key is the scope and the value is one or more privilege restrictions separated by commas. A privilege restriction of none or read, use a value of $null. Scopes include Agent, Certificate, Code Signing, Configuration, Restricted, Security, SSH, and statistics. See https://docs.venafi.com/Docs/current/TopNav/Content/SDK/AuthSDK/r-SDKa-OAuthScopePrivilegeMapping.php .PARAMETER Credential Username / password credential used to request API Token .PARAMETER State A session state, redirect URL, or random string to prevent Cross-Site Request Forgery (CSRF) attacks .PARAMETER Certificate Certificate used to request API token. Certificate authentication must be configured for remote web sdk clients, https://docs.venafi.com/Docs/current/TopNav/Content/CA/t-CA-ConfiguringInTPPandIIS-tpp.php. .PARAMETER RefreshToken Provide RefreshToken along with ClientId to obtain a new access and refresh token. Format should be a pscredential where the password is the refresh token. .PARAMETER VenafiSession VenafiSession object created from New-VenafiSession method. .EXAMPLE New-TppToken -AuthServer 'https://mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' -Credential $credential Get a new token with OAuth .EXAMPLE New-TppToken -AuthServer 'mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' Get a new token with Integrated authentication .EXAMPLE New-TppToken -AuthServer 'mytppserver.example.com' -Scope @{ Certificate = "manage,discover"; Configuration = "manage" } -ClientId 'MyAppId' -Certificate $cert Get a new token with certificate authentication .EXAMPLE New-TppToken -AuthServer 'mytppserver.example.com' -ClientId 'MyApp' -RefreshToken $refreshCred Refresh an existing access token by providing the refresh token directly .EXAMPLE New-TppToken -VenafiSession $mySession Refresh an existing access token by providing a VenafiSession object .INPUTS None .OUTPUTS PSCustomObject with the following properties: Server AccessToken RefreshToken Scope Identity TokenType ClientId Expires RefreshExpires (This property is null when TPP version is less than 21.1) #> function New-TppToken { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Integrated')] [OutputType([PSCustomObject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Generating cred from api call response data')] [OutputType([System.Boolean])] param ( [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [ValidateScript( { if ( $_ -match '^(https?:\/\/)?(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9\-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$' ) { $true } else { throw 'Please enter a valid server, https://venafi.company.com or venafi.company.com' } } )] [Alias('Server')] [string] $AuthServer, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [string] $ClientId, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [Parameter(ParameterSetName = 'Integrated', Mandatory)] [Parameter(ParameterSetName = 'Certificate', Mandatory)] [hashtable] $Scope, [Parameter(ParameterSetName = 'OAuth', Mandatory)] [System.Management.Automation.PSCredential] $Credential, [Parameter(ParameterSetName = 'Integrated')] [Parameter(ParameterSetName = 'OAuth')] [string] $State, [Parameter(ParameterSetName = 'Certificate', Mandatory)] [X509Certificate] $Certificate, [Parameter(ParameterSetName = 'RefreshToken', Mandatory)] [pscredential] $RefreshToken, [Parameter(ParameterSetName = 'RefreshSession', Mandatory)] [ValidateScript( { if ( -not $_.Token.RefreshToken ) { throw 'VenafiSession does not have a refresh token. To get a new access token, create a new session with New-VenafiSession.' } if ( $_.Token.RefreshExpires -and $_.Token.RefreshExpires -lt (Get-Date) ) { throw "The refresh token has expired. Retrieve a new access token with New-VenafiSession." } $true })] [VenafiSession] $VenafiSession ) $params = @{ Method = 'Post' UriRoot = 'vedauth' Body = @{} } if ( $PsCmdlet.ParameterSetName -eq 'RefreshSession' ) { $params.Server = $VenafiSession.Token.Server $params.UriLeaf = 'authorize/token' $params.Body = @{ client_id = $VenafiSession.Token.ClientId refresh_token = $VenafiSession.Token.RefreshToken.GetNetworkCredential().password } # workaround for bug pre 21.3 where client id needs to be lowercase if ( $VenafiSession.Version -lt [Version]::new('21', '3', '0') ) { $params.Body.client_id = $params.Body.client_id.ToLower() } } else { $AuthUrl = $AuthServer # add prefix if just server url was provided if ( $AuthServer -notlike 'https://*') { $AuthUrl = 'https://{0}' -f $AuthUrl } $params.Server = $AuthUrl if ( $PsCmdlet.ParameterSetName -eq 'RefreshToken' ) { $params.UriLeaf = 'authorize/token' $params.Body = @{ client_id = $ClientId refresh_token = $RefreshToken.GetNetworkCredential().Password } } else { # obtain new token $scopeString = @( $scope.GetEnumerator() | ForEach-Object { if ($_.Value) { '{0}:{1}' -f $_.Key, $_.Value } else { $_.Key } } ) -join ';' $params.Body = @{ client_id = $ClientId scope = $scopeString } $params.UriLeaf = 'authorize/{0}' -f $PSCmdlet.ParameterSetName.ToLower() switch ($PsCmdlet.ParameterSetName) { 'Integrated' { $params.UseDefaultCredentials = $true } 'OAuth' { $params.Body.username = $Credential.UserName $params.Body.password = $Credential.GetNetworkCredential().Password } 'Certificate' { $params.Certificate = $Certificate } Default { throw ('Unknown parameter set {0}' -f $PSCmdlet.ParameterSetName) } } if ( $State ) { $params.Body.state = $State } } } if ( $PSCmdlet.ShouldProcess($params.Server, 'New access token') ) { if ( $PsCmdlet.ParameterSetName -eq 'RefreshToken' ) { try { $response = Invoke-VenafiRestMethod @params } catch { # workaround bug pre 21.3 where client_id must be lowercase if ( $_ -like '*The client_id value being requested with the refresh token does not match the client_id of the access token making the call*') { $params.Body.client_id = $params.Body.client_id.ToLower() $response = Invoke-VenafiRestMethod @params } else { throw $_ } } } else { $response = Invoke-VenafiRestMethod @params } $response | Write-VerboseWithSecret $newToken = [PSCustomObject] @{ Server = $params.Server AccessToken = New-Object System.Management.Automation.PSCredential('AccessToken', ($response.access_token | ConvertTo-SecureString -AsPlainText -Force)) RefreshToken = $null Scope = $Scope Identity = $response.identity TokenType = $response.token_type ClientId = $params.Body.client_id Expires = ([datetime] '1970-01-01 00:00:00').AddSeconds($response.Expires) RefreshExpires = $null } if ( $response.refresh_token ) { $newToken.RefreshToken = New-Object System.Management.Automation.PSCredential('RefreshToken', ($response.refresh_token | ConvertTo-SecureString -AsPlainText -Force)) # refresh_until added in 21.1 if ($response.refresh_until) { $newToken.RefreshExpires = ([datetime] '1970-01-01 00:00:00').AddSeconds($response.refresh_until) } } $newToken } } |