Module: Okta::Jwt

Defined in:
lib/okta/jwt.rb,
lib/okta/jwt/version.rb

Constant Summary collapse

JWKS_CACHE =

keys are cached under their kid value

{}
VERSION =
"0.2.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.auth_server_idObject

Returns the value of attribute auth_server_id.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def auth_server_id
  @auth_server_id
end

.clientObject

Returns the value of attribute client.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def client
  @client
end

.client_idObject

Returns the value of attribute client_id.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def client_id
  @client_id
end

.client_secretObject

Returns the value of attribute client_secret.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def client_secret
  @client_secret
end

.issuer_urlObject

Returns the value of attribute issuer_url.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def issuer_url
  @issuer_url
end

.loggerObject

Returns the value of attribute logger.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def logger
  @logger
end

.public_key_ttlObject

Returns the value of attribute public_key_ttl.



15
16
17
# File 'lib/okta/jwt.rb', line 15

def public_key_ttl
  @public_key_ttl
end

Class Method Details

.configure!(issuer_url:, auth_server_id:, client_id: nil, client_secret: nil, logger: Logger.new(IO::NULL)) ⇒ Object

configure the client



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/okta/jwt.rb', line 19

def configure!(issuer_url:, auth_server_id:, client_id: nil, client_secret: nil, logger: Logger.new(IO::NULL))
  @issuer_url     = issuer_url
  @auth_server_id = auth_server_id
  @client_id      = client_id
  @client_secret  = client_secret
  @logger         = logger
  
  @client = Faraday.new(url: issuer_url) do |f|
    f.use Faraday::Adapter::NetHttp
    f.headers['Accept'] = 'application/json'
  end
end

.get_jwk(token) ⇒ Object

extract public key from metadata’s jwks_uri using kid



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/okta/jwt.rb', line 49

def get_jwk(token)
  kid = JSON.parse(Base64.decode64(token.split('.').first))['kid']
  return JWKS_CACHE[kid] if JWKS_CACHE[kid] # cache hit
  
  logger.info("[Okta::Jwt] Fetching public key: kid => #{kid} ...")
  jwks_response = client.get do |req|
    req.url (token)['jwks_uri']
  end
  jwk = JSON.parse(jwks_response.body)['keys'].find do |key|
    key.dig('kid') == kid
  end
  
  # cache and return the key
  jwk.tap{JWKS_CACHE[kid] = jwk}
end

.get_metadata(token) ⇒ Object

fetch client metadata using cid/aud



66
67
68
69
70
71
72
73
# File 'lib/okta/jwt.rb', line 66

def (token)
  payload = JSON.parse(Base64.decode64(token.split('.')[1]))
  client_id = payload['cid'] || payload['aud'] # id_token has client_id value under aud key
   = client.get do |req|
    req.url "/oauth2/#{auth_server_id}/.well-known/oauth-authorization-server?client_id=#{client_id}"
  end
  JSON.parse(.body)
end

.sign_in(username:, password:) ⇒ Object

sign in user to get tokens



33
34
35
36
37
38
39
40
# File 'lib/okta/jwt.rb', line 33

def (username:, password:)
  client.post do |req|
    req.url "/oauth2/#{auth_server_id}/v1/token"
    req.headers['Content-Type']   = 'application/x-www-form-urlencoded'
    req.headers['Authorization']  = 'Basic: ' + Base64.strict_encode64("#{client_id}:#{client_secret}")
    req.body = URI.encode_www_form username: username, password: password, scope: 'openid', grant_type: 'password'
  end
end

.verify_token(token) ⇒ Object

validate the token



43
44
45
46
# File 'lib/okta/jwt.rb', line 43

def verify_token(token)
  jwk = JSON::JWK.new(get_jwk(token))
  JSON::JWT.decode(token, jwk.to_key)
end