Class: Talis::Authentication::Token

Inherits:
Resource show all
Defined in:
lib/talis/authentication/token.rb

Overview

Represents a JWT-based OAuth access token.

Optionally configure an ActiveSupport-based cache store for caching the public key and tokens. The default cache used is an in-memory one. See api.rubyonrails.org/classes/ActiveSupport/Cache.html for supported cache types.

Examples:

Using an in-memory cache.

store = ActiveSupport::Cache::MemoryStore.new
Talis::Authentication::Token.cache_store = store

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resource

handle_response, new_req_id

Constructor Details

#initialize(jwt:, public_key: nil) ⇒ Token

Create a new token object from an existing JWT.

Parameters:

  • jwt (String)

    the encoded JWT.

  • public_key (PublicKey) (defaults to: nil)

    (nil) Only used in unit tests.



24
25
26
27
# File 'lib/talis/authentication/token.rb', line 24

def initialize(jwt:, public_key: nil)
  @jwt = jwt
  @public_key = public_key || PublicKey.new(Token.cache_store)
end

Class Method Details

.generate(request_id: new_req_id, client_id:, client_secret:, host: base_uri) ⇒ Talis::Authentication::Token

Generate a new token for the given client. If a previous token has been generated for the client and has not expired then this will be returned from the cache.

Parameters:

  • request_id (String) (defaults to: new_req_id)

    (‘uuid’) unique ID for the remote request.

  • client_id (String)

    the client for whom this token is for.

  • client_secret (String)

    secret belonging to the client.

  • host (String) (defaults to: base_uri)

    Optional persona host override for service

Returns:

Raises:



116
117
118
119
120
121
122
123
124
# File 'lib/talis/authentication/token.rb', line 116

def generate(request_id: new_req_id, client_id:, client_secret:,
             host: base_uri)
  token = cached_token(client_id, host)
  if token
    new(jwt: token)
  else
    generate_remote_token(request_id, client_id, client_secret, host)
  end
end

Instance Method Details

#to_sString

Returns the encoded version of the token - a JWT string.

Returns:

  • (String)

    the encoded version of the token - a JWT string.



66
67
68
# File 'lib/talis/authentication/token.rb', line 66

def to_s
  @jwt
end

#validate(request_id: self.class.new_req_id, scopes: [], all: true) ⇒ Symbol, Nil

Validate the token, optionally against one or more required scopes.

Scope validation is performed locally unless there are too many tokens to list inside the token payload. When this is the case, a remote request is performed to validate the token against the scopes.

The validation error returned can be one of the following:

  • ‘:expired_token` if the token has expired.

  • ‘:insufficient_scope` if the provided scopes are not in the token.

  • ‘:invalid_token` if the token could not be verified by the public key.

  • ‘:invalid_token` if the token could not be decoded.

  • ‘:invalid_key` if the public key is corrupt.

Parameters:

  • request_id (String) (defaults to: self.class.new_req_id)

    (uuid) unique ID for the remote request.

  • scopes (Array) (defaults to: [])

    Scope(s) that the token needs in order to be valid.

  • all (Boolean) (defaults to: true)

    (true) Whether or not all scopes must be present within the token for validation to pass. If false, only one matching scope is required.

Returns:

  • (Symbol, Nil)

    nil iff the token is valid else a symbol error.

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/talis/authentication/token.rb', line 52

def validate(request_id: self.class.new_req_id, scopes: [], all: true)
  decoded = JWT.decode(@jwt, p_key(request_id), true, algorithm: 'RS256')
  validate_scopes(request_id, scopes, decoded[0], all)
rescue JWT::ExpiredSignature
  return :expired_token
rescue JWT::VerificationError, JWT::DecodeError
  return :invalid_token
rescue NoMethodError
  return :invalid_key
rescue Talis::ClientError
  :insufficient_scope
end