Class: JSON::JWS

Inherits:
JWT
  • Object
show all
Defined in:
lib/json/jws.rb

Defined Under Namespace

Classes: InvalidFormat, UnexpectedAlgorithm, VerificationFailed

Constant Summary collapse

NUM_OF_SEGMENTS =
3

Constants inherited from JWT

JSON::JWT::VERSION

Instance Attribute Summary collapse

Attributes inherited from JWT

#blank_payload, #signature

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from JWT

#as_json, #encrypt, #pretty_generate, pretty_generate, #to_json, #to_s

Methods included from JOSE

#secure_compare, #with_jwk_support

Constructor Details

#initialize(jwt) ⇒ JWS

Returns a new instance of JWS.



11
12
13
# File 'lib/json/jws.rb', line 11

def initialize(jwt)
  update jwt
end

Instance Attribute Details

#signature_base_string=(value) ⇒ Object

Sets the attribute signature_base_string

Parameters:

  • value

    the value to set the attribute signature_base_string to.



9
10
11
# File 'lib/json/jws.rb', line 9

def signature_base_string=(value)
  @signature_base_string = value
end

Class Method Details

.decode_compact_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/json/jws.rb', line 176

def decode_compact_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false)
  unless input.count('.') + 1 == NUM_OF_SEGMENTS
    raise InvalidFormat.new("Invalid JWS Format. JWS should include #{NUM_OF_SEGMENTS} segments.")
  end
  header, claims, signature = input.split('.', NUM_OF_SEGMENTS).collect do |segment|
    Base64.urlsafe_decode64 segment.to_s
  end
  header = JSON.parse(header).with_indifferent_access
  if allow_blank_payload && claims == ''
    claims = nil
  else
    claims = JSON.parse(claims).with_indifferent_access
  end
  jws = new claims
  jws.header = header
  jws.signature = signature
  jws.signature_base_string = input.split('.')[0, NUM_OF_SEGMENTS - 1].join('.')
  jws.verify! public_key_or_secret, algorithms unless public_key_or_secret == :skip_verification
  jws
end

.decode_json_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/json/jws.rb', line 197

def decode_json_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false)
  input = input.with_indifferent_access
  header, payload, signature = if input[:signatures].present?
    [
      input[:signatures].first[:protected],
      input[:payload],
      input[:signatures].first[:signature]
    ].collect do |segment|
      segment
    end
  else
    [:protected, :payload, :signature].collect do |key|
      input[key]
    end
  end
  compact_serialized = [header, payload, signature].join('.')
  decode_compact_serialized compact_serialized, public_key_or_secret, algorithms, allow_blank_payload
end

Instance Method Details

#sign!(private_key_or_secret) ⇒ Object



15
16
17
18
19
# File 'lib/json/jws.rb', line 15

def sign!(private_key_or_secret)
  self.alg = autodetected_algorithm_from(private_key_or_secret) if alg == :autodetect
  self.signature = sign signature_base_string, private_key_or_secret
  self
end

#update(hash_or_jwt) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/json/jws.rb', line 33

def update(hash_or_jwt)
  super
  if hash_or_jwt.is_a? JSON::JWT
    self.header.update hash_or_jwt.header
    self.signature = hash_or_jwt.signature
    self.blank_payload = hash_or_jwt.blank_payload
  end
  self
end

#verify!(public_key_or_secret, algorithms = nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/json/jws.rb', line 21

def verify!(public_key_or_secret, algorithms = nil)
  if alg&.to_sym == :none
    raise UnexpectedAlgorithm if public_key_or_secret
    signature == '' or raise VerificationFailed
  elsif algorithms.blank? || Array(algorithms).include?(alg&.to_sym)
    public_key_or_secret && valid?(public_key_or_secret) or
    raise VerificationFailed
  else
    raise UnexpectedAlgorithm.new('Unexpected alg header')
  end
end