Functions/ConvertFrom-EncodedJsonWebToken.ps1
function ConvertFrom-EncodedJsonWebToken { <# .SYNOPSIS Decodes a JSON Web Token. .DESCRIPTION Decodes a structurally valid JSON Web Token, specifically the header and the payload. This function does not validate a JSON Web Token, it merely decodes the token for purposes of viewing the claims in the header and payload segments. .PARAMETER JsonWebToken A signed JSON Web Token that is to be decoded. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCNTMjU2IjoiYklYZkw1RmREaWkzR2E3QmlEWndrcUQ5RE5JIiwiamt1IjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tL0FjY291bnQvSndrQ29sbGVjdGlvbiJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9naXZlbm5hbWUiOiJUb255IiwiaXNzIjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc3VybmFtZSI6Ikd1aW1lbGxpIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbm1ldGhvZCI6Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9hdXRoZW50aWNhdGlvbm1ldGhvZC91bnNwZWNpZmllZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWVpZGVudGlmaWVyIjoidG9ueS5ndWltZWxsaUB5YWhvby5jb20iLCJhdWQiOiJ1cm46Zm1nOmlkZW50aXR5c2VydmVyLy9xYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvYXV0aGVudGljYXRpb25pbnN0YW50IjoiNy81LzIwMTYgOToxNjozMyBBTSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6InRvbnkuZ3VpbWVsbGlAeWFob28uY29tIiwiaWRlbnRpdHlwcm92aWRlciI6Imh0dHBzOi8vc3NvMi1zdGcuZm1nbG9iYWwuY29tIiwianRpIjoiNmI1ZGY4NjBGNDUxNDlEZjhERUZEM0NBZDFiRjA0ZjMiLCJpYXQiOjE0Njc3MjQ1OTksIm5iZiI6MTQ2NzcyNDU2OSwiZXhwIjoxNDY3NzI0ODk5fQ.RA3F6deEmZlq3RL2NDF07Nv5SrrY31Qfw1LfVoxNmdXlPcai1UH9ad80Oq66sMyJUMOtXMOA5RkwRZQ6L5gNFTAIApDjAlBFte1d5ziCSjBhxYzMZ-f_pFeBOmsMsSI5-BaAInYch7usZ2efEP8AdYKrZdkO5bgovL-7WD0Ts9gjVssWN_uhIcj-mM67xHartinKstPXUB4LUrJHHOoORCChs1eNS5xTq6q1xoPj-dYmlC56OaHKuzqUy9iByWssZ-0_DC6EfwIOqL4i43sNXPrSuDAisGPd_pxnYzqgdPAaWj9WTae7X1VHzvCiz21V7TGvDj37cwiXHj2dT93vAQ" ConvertFrom-EncodedJsonWebToken -JsonWebToken $jwt Decodes the JSON Web Token defined in the $jwt variable. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCNTMjU2IjoiYklYZkw1RmREaWkzR2E3QmlEWndrcUQ5RE5JIiwiamt1IjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tL0FjY291bnQvSndrQ29sbGVjdGlvbiJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9naXZlbm5hbWUiOiJUb255IiwiaXNzIjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc3VybmFtZSI6Ikd1aW1lbGxpIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbm1ldGhvZCI6Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9hdXRoZW50aWNhdGlvbm1ldGhvZC91bnNwZWNpZmllZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWVpZGVudGlmaWVyIjoidG9ueS5ndWltZWxsaUB5YWhvby5jb20iLCJhdWQiOiJ1cm46Zm1nOmlkZW50aXR5c2VydmVyLy9xYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvYXV0aGVudGljYXRpb25pbnN0YW50IjoiNy81LzIwMTYgOToxNjozMyBBTSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6InRvbnkuZ3VpbWVsbGlAeWFob28uY29tIiwiaWRlbnRpdHlwcm92aWRlciI6Imh0dHBzOi8vc3NvMi1zdGcuZm1nbG9iYWwuY29tIiwianRpIjoiNmI1ZGY4NjBGNDUxNDlEZjhERUZEM0NBZDFiRjA0ZjMiLCJpYXQiOjE0Njc3MjQ1OTksIm5iZiI6MTQ2NzcyNDU2OSwiZXhwIjoxNDY3NzI0ODk5fQ.RA3F6deEmZlq3RL2NDF07Nv5SrrY31Qfw1LfVoxNmdXlPcai1UH9ad80Oq66sMyJUMOtXMOA5RkwRZQ6L5gNFTAIApDjAlBFte1d5ziCSjBhxYzMZ-f_pFeBOmsMsSI5-BaAInYch7usZ2efEP8AdYKrZdkO5bgovL-7WD0Ts9gjVssWN_uhIcj-mM67xHartinKstPXUB4LUrJHHOoORCChs1eNS5xTq6q1xoPj-dYmlC56OaHKuzqUy9iByWssZ-0_DC6EfwIOqL4i43sNXPrSuDAisGPd_pxnYzqgdPAaWj9WTae7X1VHzvCiz21V7TGvDj37cwiXHj2dT93vAQ" ConvertFrom-EncodedJsonWebToken -JsonWebToken $jwt | Select-Object -ExpandProperty Payload | ConvertFrom-Json Decodes the JSON Web Token defined in the $jwt variable, expands the Payload segment and deserializes it via the ConvertFrom-Json cmdlet. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCNTMjU2IjoiYklYZkw1RmREaWkzR2E3QmlEWndrcUQ5RE5JIiwiamt1IjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tL0FjY291bnQvSndrQ29sbGVjdGlvbiJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9naXZlbm5hbWUiOiJUb255IiwiaXNzIjoiaHR0cHM6Ly9xYS5pZHBzcnYuZm1nbG9iYWwuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc3VybmFtZSI6Ikd1aW1lbGxpIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbm1ldGhvZCI6Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9hdXRoZW50aWNhdGlvbm1ldGhvZC91bnNwZWNpZmllZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWVpZGVudGlmaWVyIjoidG9ueS5ndWltZWxsaUB5YWhvby5jb20iLCJhdWQiOiJ1cm46Zm1nOmlkZW50aXR5c2VydmVyLy9xYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvYXV0aGVudGljYXRpb25pbnN0YW50IjoiNy81LzIwMTYgOToxNjozMyBBTSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6InRvbnkuZ3VpbWVsbGlAeWFob28uY29tIiwiaWRlbnRpdHlwcm92aWRlciI6Imh0dHBzOi8vc3NvMi1zdGcuZm1nbG9iYWwuY29tIiwianRpIjoiNmI1ZGY4NjBGNDUxNDlEZjhERUZEM0NBZDFiRjA0ZjMiLCJpYXQiOjE0Njc3MjQ1OTksIm5iZiI6MTQ2NzcyNDU2OSwiZXhwIjoxNDY3NzI0ODk5fQ.RA3F6deEmZlq3RL2NDF07Nv5SrrY31Qfw1LfVoxNmdXlPcai1UH9ad80Oq66sMyJUMOtXMOA5RkwRZQ6L5gNFTAIApDjAlBFte1d5ziCSjBhxYzMZ-f_pFeBOmsMsSI5-BaAInYch7usZ2efEP8AdYKrZdkO5bgovL-7WD0Ts9gjVssWN_uhIcj-mM67xHartinKstPXUB4LUrJHHOoORCChs1eNS5xTq6q1xoPj-dYmlC56OaHKuzqUy9iByWssZ-0_DC6EfwIOqL4i43sNXPrSuDAisGPd_pxnYzqgdPAaWj9WTae7X1VHzvCiz21V7TGvDj37cwiXHj2dT93vAQ" ConvertFrom-EncodedJsonWebToken -JsonWebToken $jwt | Select IssuedAt, NotBefore Returns the iat and exp claims in the payload deserialized as "IssuedAt" and "Expiration" as DateTime. .INPUTS System.String A string is received by the JsonWebToken parameter. .OUTPUTS PSJsonWebToken.DecodedJsonWebToken An object containing the decoded header and payload segments. The signature segment remains encoded. . .LINK https://tools.ietf.org/html/rfc7519 New-JsonWebToken ConvertFrom-Json #> [CmdletBinding()] [Alias('DecodeJwt')] [OutputType([PSJsonWebToken.DecodedJsonWebToken])] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)] [ValidateLength(16,8192)][Alias("JWT", "Token")][String]$JsonWebToken ) BEGIN { $decodeExceptionMessage = "Unable to decode JWT." $ArgumentException = New-Object -TypeName ArgumentException -ArgumentList $decodeExceptionMessage } PROCESS { [bool]$isValidJwt = Test-JwtStructure -JsonWebToken $JsonWebToken if (-not($isValidJwt)) { Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } $deserializedHeader = $JsonWebToken | Get-JsonWebTokenHeader $deserializedPayload = $JsonWebToken | Get-JsonWebTokenPayload $serializedHeader = $deserializedHeader | ConvertTo-Json -Compress $serializedPayload = $deserializedPayload | ConvertTo-Json -Compress $signatureString = $JsonWebToken.Split(".")[2] <# if ($deserializedHeader.ContainsKey("typ")) { if ($deserializedHeader.Item("typ") -ne "JWT") { Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } } else { Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } #> $decodedJsonWebToken = [PSJsonWebToken.DecodedJsonWebToken]::new() $decodedJsonWebToken.Header = $serializedHeader $decodedJsonWebToken.Payload = $serializedPayload $decodedJsonWebToken.Signature = $signatureString [bool]$containsPotentialThumbprint = $false [string]$encodedThumbprint = "" [string]$decodedThumbprint = "" if ($deserializedHeader.ContainsKey("x5t")) { $containsPotentialThumbprint = $true $encodedThumbprint = $deserializedHeader.x5t } elseif ($deserializedHeader.ContainsKey("kid")) { $containsPotentialThumbprint = $true $encodedThumbprint = $deserializedHeader.kid } if ($containsPotentialThumbprint) { [bool]$thumbprintDecodes = $false try { $decodedThumbprint = ConvertFrom-EncodedJwtThumbprint -EncodedThumbprint $encodedThumbprint $thumbprintDecodes = $true } catch { $thumbprintDecodes = $false } if ($thumbprintDecodes) { $decodedJsonWebToken | Add-Member -MemberType NoteProperty -Name SigningCertificateThumbprint -Value $decodedThumbprint } } if ($deserializedPayload.ContainsKey("nbf")) { $notBefore = Convert-EpochToDateTime -Epoch $deserializedPayload.nbf $decodedJsonWebToken | Add-Member -MemberType NoteProperty -Name NotBefore -Value $notBefore } if ($deserializedPayload.ContainsKey("iat")) { $issuedAt = Convert-EpochToDateTime -Epoch $deserializedPayload.iat $decodedJsonWebToken | Add-Member -MemberType NoteProperty -Name IssuedAt -Value $issuedAt } if ($deserializedPayload.ContainsKey("exp")) { $expiration = Convert-EpochToDateTime -Epoch $deserializedPayload.exp $decodedJsonWebToken | Add-Member -MemberType NoteProperty -Name Expiration -Value $expiration } return $decodedJsonWebToken } } |