Class: Koi::Identity::Assertion

Inherits:
Object
  • Object
show all
Defined in:
app/models/koi/identity/assertion.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token) ⇒ Assertion

Returns a new instance of Assertion.



12
13
14
15
16
# File 'app/models/koi/identity/assertion.rb', line 12

def initialize(token)
  @token           = token
  @claims, @header = JWT.decode(token, nil, false)
  @state           = :unverified
end

Instance Attribute Details

#principalObject (readonly)

Returns Principal.

Returns:

  • Principal



10
11
12
# File 'app/models/koi/identity/assertion.rb', line 10

def principal
  @principal
end

#tokenObject (readonly)

Returns String.

Returns:

  • String



7
8
9
# File 'app/models/koi/identity/assertion.rb', line 7

def token
  @token
end

Instance Method Details

#claimsObject



22
23
24
# File 'app/models/koi/identity/assertion.rb', line 22

def claims
  @claims
end

#headerObject



26
27
28
# File 'app/models/koi/identity/assertion.rb', line 26

def header
  @header
end

#inspectObject Also known as: to_s



72
73
74
# File 'app/models/koi/identity/assertion.rb', line 72

def inspect
  "<#{self.class.name} iss=#{iss.inspect} sub=#{sub.inspect}>"
end

#issObject Also known as: issuer



62
63
64
# File 'app/models/koi/identity/assertion.rb', line 62

def iss
  @claims["iss"]
end

#subObject Also known as: subject



67
68
69
# File 'app/models/koi/identity/assertion.rb', line 67

def sub
  @claims["sub"]
end

#verified?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'app/models/koi/identity/assertion.rb', line 18

def verified?
  @state == :verified
end

#verify!(provider) ⇒ Object

Raises:

  • (JWT::MissingRequiredClaim)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/models/koi/identity/assertion.rb', line 30

def verify!(provider)
  # The library validates required_claims after verify_jti, but
  # consume_jti derives its cache TTL from exp — so require it first.
  raise JWT::MissingRequiredClaim, "missing required claim exp" if claims["exp"].nil?

  JWT.decode(
    @token, nil, true,
    algorithms:      provider.algorithms,
    jwks:            provider.method(:key_set),
    aud:             provider.audience,
    leeway:          provider.leeway.to_i,
    required_claims: %w[exp],
    verify_aud:      true,
    verify_jti:      provider.method(:consume_jti)
  )

  if claims["exp"].to_i > provider.max_expiry.from_now.to_i
    raise JWT::InvalidPayload, "assertion expiry is more than #{provider.max_expiry.inspect} away"
  end

  # ensure that we can map the claim to a valid principal using the claim's subject
  @principal = Identity.principal_for(provider, self)

  if principal.blank? || principal.subject.blank?
    raise(JWT::InvalidSubError, "unknown subject #{subject} for provider #{provider.name}")
  end

  @state = :verified

  self
end