Class: SimpleWebToken::SimpleWebTokenHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/swt/simple_web_token_handler.rb

Overview

Handler for parsing, validating and creating (soon) Simple Web Tokens as it stated by the protocol under development of the IEFT v0.9.5.1.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ SimpleWebTokenHandler

Creates a new instance of the SimpleWebTokenHandler.

Valid options include:

-:shared_secret the HMAC:SHA256 key shared between parties. -:trusted_issuers the URI(s) of the issuers to be validated on the Issue value of the token. -:audiences the URI(s) of the audiences (apps) to be validated on the Audience value of the token.

__Only :shared_secret__ is required, the other values aren’t present then no check is performed.

Raises:



17
18
19
20
21
22
# File 'lib/swt/simple_web_token_handler.rb', line 17

def initialize(opts = {})
  raise InvalidOption, :shared_secret unless opts[:shared_secret]
  self.shared_secret = opts[:shared_secret]
  self.trusted_issuers = opts[:trusted_issuers]
  self.audiences = opts[:audiences]
end

Instance Attribute Details

#audiencesObject

Returns the value of attribute audiences.



5
6
7
# File 'lib/swt/simple_web_token_handler.rb', line 5

def audiences
  @audiences
end

#shared_secretObject

Returns the value of attribute shared_secret.



5
6
7
# File 'lib/swt/simple_web_token_handler.rb', line 5

def shared_secret
  @shared_secret
end

#trusted_issuersObject

Returns the value of attribute trusted_issuers.



5
6
7
# File 'lib/swt/simple_web_token_handler.rb', line 5

def trusted_issuers
  @trusted_issuers
end

Instance Method Details

#expired?(token) ⇒ Boolean

Returns a value indicating whether the __ExpiresOn__ value of the token is older than now.

Returns:

  • (Boolean)


51
52
53
54
# File 'lib/swt/simple_web_token_handler.rb', line 51

def expired?(token)
  expires_on = token[/&?ExpiresOn=([^&]+)/, 1]
  expires_on.to_i < Time.now.to_i
end

#parse(token) ⇒ Object

Returns a key-value pair (hash) with the token values parsed.

__NOTE__: multi-valued claims (provided as comma separated values, like checkboxes on HTML forms) are returned like arrays.

Raises:



70
71
72
73
74
# File 'lib/swt/simple_web_token_handler.rb', line 70

def parse(token)
  raise InvalidToken unless valid?(token)
  token.split('&').map{|p| p.split('=') } \
                  .inject({}){|t, i| t.merge!(CGI.unescape(i[0]) => value_for(CGI.unescape(i[1])))}
end

#valid?(token) ⇒ Boolean

Returns a value indicating whether the token is valid, the calculation is done as the sum of all the other validations (when values for checking are provided)

Returns:

  • (Boolean)


58
59
60
61
62
63
64
# File 'lib/swt/simple_web_token_handler.rb', line 58

def valid?(token)
  valid = valid_signature?(token)
  valid &&= valid_issuer?(token) if (trusted_issuers)
  valid &&= valid_audience?(token) if (audiences)
  valid &&= !expired?(token)
  return valid
end

#valid_audience?(token) ⇒ Boolean

Returns a value indicating whether the __Audience__ value of the token is contained on the audiences list of the application.

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/swt/simple_web_token_handler.rb', line 44

def valid_audience?(token)
  audience = token[/&?Audience=([^&]+)/, 1]
  [audiences].flatten.include?(CGI.unescape(audience))
end

#valid_issuer?(token) ⇒ Boolean

Returns a value indicating whether the __Issuer__ value of the token is contained on the trusted_issuer list for the application.

Returns:

  • (Boolean)


37
38
39
40
# File 'lib/swt/simple_web_token_handler.rb', line 37

def valid_issuer?(token)
  issuer = token[/&?Issuer=([^&]+)/, 1]
  [trusted_issuers].flatten.include?(CGI.unescape(issuer))
end

#valid_signature?(token) ⇒ Boolean

Validates the signature by doing a symmetric signature comparison, between the value sent as HMACSHA256 on the token and the generated using the shared_key provided.

Returns:

  • (Boolean)


27
28
29
30
31
32
33
# File 'lib/swt/simple_web_token_handler.rb', line 27

def valid_signature?(token)
  return false unless token =~ /&HMACSHA256=(.*)$/
  original_signature = CGI.unescape(token[/&HMACSHA256=(.*)$/, 1])
  bare_token = token.gsub(/&HMACSHA256=(.*)$/, '')
  signature = Base64.encode64(HMAC::SHA256.new(Base64.decode64(shared_secret)).update(bare_token.toutf8).digest).strip
  return original_signature == signature
end