Method: CF::UAA::TokenCoder.decode

Defined in:
lib/uaa/token_coder.rb

.decode(token, options = {}, obsolete1 = nil, obsolete2 = nil) ⇒ Hash

Decodes a JWT token and optionally verifies the signature. Both a symmetrical key and a public key can be provided for signature verification. The JWT header indicates what signature algorithm was used and the corresponding key is used to verify the signature (if verify is true).

Parameters:

  • token (String)

    A JWT token as returned by encode

  • options (Hash) (defaults to: {})

    Supported options:

    • :audience_ids [Array<String>, String] – An array or space separated string of values which indicate the token is intended for this service instance. It will be compared with tokens as they are decoded to ensure that the token was intended for this audience.

    • :skey [String] – used to sign and validate tokens using symmetrical key algoruthms

    • :pkey [String, File, OpenSSL::PKey::PKey] – may be a String or File in PEM or DER formats. May include public and/or private key data. The private key is used to sign tokens and the public key is used to validate tokens.

    • :algorithm [String] – Sets default used for encoding. May be HS256, HS384, HS512, RS256, RS384, RS512, or none.

    • :verify [String] – Verifies signatures when decoding tokens. Defaults to true.

    • :accept_algorithms [String, Array<String>] – An Array or space separated string of values which list what algorthms are accepted for token signatures. Defaults to all possible values of :algorithm except ‘none’.

Returns:

  • (Hash)

    the token contents

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/uaa/token_coder.rb', line 95

def self.decode(token, options = {}, obsolete1 = nil, obsolete2 = nil)
  unless options.is_a?(Hash) && obsolete1.nil? && obsolete2.nil?
    # deprecated: def self.decode(token, skey = nil, pkey = nil, verify = true)
    warn "#{self.class}##{__method__} is deprecated with these parameters. Please use options hash."
    options = {:skey => options }
    options[:pkey], options[:verify] = obsolete1, obsolete2
  end
  options = normalize_options(options)
  segments = token.split('.')
  raise InvalidTokenFormat, "Not enough or too many segments" unless [2,3].include? segments.length
  header_segment, payload_segment, crypto_segment = segments
  signing_input = [header_segment, payload_segment].join('.')
  header = Util.json_decode64(header_segment)
  payload = Util.json_decode64(payload_segment, (:sym if options[:symbolize_keys]))
  return payload unless options[:verify]
  raise SignatureNotAccepted, "Signature algorithm not accepted" unless
      options[:accept_algorithms].include?(algo = header["alg"])
  return payload if algo == 'none'
  signature = Util.decode64(crypto_segment)
  if ["HS256", "HS384", "HS512"].include?(algo)
    raise InvalidSignature, "Signature verification failed" unless
        options[:skey] && signature == OpenSSL::HMAC.digest(init_digest(algo), options[:skey], signing_input)
  elsif ["RS256", "RS384", "RS512"].include?(algo)
    raise InvalidSignature, "Signature verification failed" unless
        options[:pkey] && options[:pkey].verify(init_digest(algo), signature, signing_input)
  else
    raise SignatureNotSupported, "Algorithm not supported"
  end
  payload
end