Public/Get-OAuthAuthorization.ps1
function Get-OAuthAuthorization { <# .SYNOPSIS This function is used to create the signature and authorization headers needed to pass to OAuth It has been tested with v1.1 of the API. .EXAMPLE Get-OAuthAuthorization -ApiParameters @{'status' = 'hello' } -HttpVerb GET -HttpEndPoint 'https://api.twitter.com/1.1/statuses/update.json' This example gets the authorization string needed in the HTTP GET method to send send a tweet 'hello' .PARAMETER Api The Twitter API name. Currently, you can only use Timeline, DirectMessage or Update. .PARAMETER HttpEndPoint This is the URI that you must use to issue calls to the API. .PARAMETER HttpVerb The HTTP verb (either GET or POST) that the specific API uses. .PARAMETER ApiParameters A hashtable of parameters the specific Twitter API you're building the authorization string for needs to include in the signature #> [CmdletBinding(DefaultParameterSetName = 'None')] [OutputType('System.Management.Automation.PSCustomObject')] param ( [Parameter(Mandatory)] [string]$HttpEndPoint, [Parameter(Mandatory)] [ValidateSet('POST', 'GET')] [string]$HttpVerb, [Parameter(Mandatory)] [hashtable]$ApiParameters ) begin { $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop Set-StrictMode -Version Latest try { [Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null [Reflection.Assembly]::LoadWithPartialName("System.Net") | Out-Null if (!(Get-MyTwitterConfiguration)) { throw 'No MyTwitter configuration detected. Please run New-MyTwitterConfiguration' } else { $script:MyTwitterConfiguration = Get-MyTwitterConfiguration } } catch { Write-Error $_.Exception.Message } } process { try { ## Generate a random 32-byte string. I'm using the current time (in seconds) and appending 5 chars to the end to get to 32 bytes ## Base64 allows for an '=' but Twitter does not. If this is found, replace it with some alphanumeric character $OauthNonce = [System.Convert]::ToBase64String(([System.Text.Encoding]::ASCII.GetBytes("$([System.DateTime]::Now.Ticks.ToString())12345"))).Replace('=', 'g') Write-Verbose "Generated Oauth none string '$OauthNonce'" ## Find the total seconds since 1/1/1970 (epoch time) $EpochTimeNow = [System.DateTime]::UtcNow - [System.DateTime]::ParseExact("01/01/1970", "dd/MM/yyyy", [System.Globalization.CultureInfo]::InvariantCulture) Write-Verbose "Generated epoch time '$EpochTimeNow'" $OauthTimestamp = [System.Convert]::ToInt64($EpochTimeNow.TotalSeconds).ToString(); Write-Verbose "Generated Oauth timestamp '$OauthTimestamp'" ## Build the signature $SignatureBase = "$([System.Uri]::EscapeDataString($HttpEndPoint))&" $SignatureParams = @{ 'oauth_consumer_key' = $MyTwitterConfiguration.ApiKey; 'oauth_nonce' = $OauthNonce; 'oauth_signature_method' = 'HMAC-SHA1'; 'oauth_timestamp' = $OauthTimestamp; 'oauth_token' = $MyTwitterConfiguration.AccessToken; 'oauth_version' = '1.0'; } $AuthorizationParams = $SignatureParams.Clone() ## Add API-specific params to the signature foreach ($Param in $ApiParameters.GetEnumerator()) { $SignatureParams[$Param.Key] = $Param.Value } ## Create a string called $SignatureBase that joins all URL encoded 'Key=Value' elements with a & ## Remove the URL encoded & at the end and prepend the necessary 'POST&' verb to the front $SignatureParams.GetEnumerator() | Sort-Object -Property Name | foreach { $SignatureBase += [System.Uri]::EscapeDataString("$($_.Key)=$($_.Value)&") } $SignatureBase = $SignatureBase.TrimEnd('%26') $SignatureBase = "$HttpVerb&" + $SignatureBase Write-Verbose "Base signature generated '$SignatureBase'" ## Create the hashed string from the base signature $SignatureKey = [System.Uri]::EscapeDataString($MyTwitterConfiguration.ApiSecret) + "&" + [System.Uri]::EscapeDataString($MyTwitterConfiguration.AccessTokenSecret); $hmacsha1 = new-object System.Security.Cryptography.HMACSHA1; $hmacsha1.Key = [System.Text.Encoding]::ASCII.GetBytes($SignatureKey); $OauthSignature = [System.Convert]::ToBase64String($hmacsha1.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($SignatureBase))); Write-Verbose "Using signature '$OauthSignature'" ## Build the authorization headers. This is joining all of the 'Key=Value' elements again ## and only URL encoding the Values this time while including non-URL encoded double quotes around each value $AuthorizationParams.Add('oauth_signature', $OauthSignature) $AuthorizationString = 'OAuth ' $AuthorizationParams.GetEnumerator() | Sort-Object -Property name | foreach { $AuthorizationString += $_.Key + '="' + [System.Uri]::EscapeDataString($_.Value) + '", ' } $AuthorizationString = $AuthorizationString.TrimEnd(', ') Write-Verbose "Using authorization string '$AuthorizationString'" $AuthorizationString } catch { Write-Error $_.Exception.Message } } } |