Class: TokenValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/acs/token_validator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service_name, solution_name, trusted_audience, trusted_signing_key, token) ⇒ TokenValidator

service_name: Defined in the contants file solution_name: Name of the service created truste_audience: Applies_to url trusted_signing_key: Management key provided when the service was created token: service_name + “ ” + token received



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/acs/token_validator.rb', line 38

def initialize(service_name, solution_name, trusted_audience, trusted_signing_key, token)
  token_separator = ' '
  @issuer_label = "Issuer"
  @expires_label = "ExpiresOn"
  @audience_label = "Audience"
  @hmacSHA256_label = "HMACSHA256"
   
  @trusted_token_issuer = "https://" + solution_name + "." + DotNetServicesEnvironment.acm_host_name +
    "/" + service_name
  @trusted_audience = trusted_audience
  @trusted_signing_key = trusted_signing_key
  
  @token = CGI::unescape(token.split(token_separator).last)
  populate_claims(@token)
end

Instance Attribute Details

#claimsObject (readonly)

Returns the value of attribute claims.



31
32
33
# File 'lib/acs/token_validator.rb', line 31

def claims
  @claims
end

#tokenObject (readonly)

Returns the value of attribute token.



31
32
33
# File 'lib/acs/token_validator.rb', line 31

def token
  @token
end

#trusted_audienceObject (readonly)

Returns the value of attribute trusted_audience.



31
32
33
# File 'lib/acs/token_validator.rb', line 31

def trusted_audience
  @trusted_audience
end

#trusted_signing_keyObject (readonly)

Returns the value of attribute trusted_signing_key.



31
32
33
# File 'lib/acs/token_validator.rb', line 31

def trusted_signing_key
  @trusted_signing_key
end

#trusted_token_issuerObject (readonly)

Returns the value of attribute trusted_token_issuer.



31
32
33
# File 'lib/acs/token_validator.rb', line 31

def trusted_token_issuer
  @trusted_token_issuer
end

Instance Method Details

#audience_trusted?Boolean

Checks if the audience (applies to) in the token is the same as the trusted token issuer

Returns:

  • (Boolean)

Raises:

  • (StandardError)


109
110
111
112
113
# File 'lib/acs/token_validator.rb', line 109

def audience_trusted?
  raise StandardError.new("Claims not defined in the token.") if(@claims.empty?)
  audience = @claims[@audience_label]
  return ((!audience.empty?) || (audience == @trusted_audience))
end

#expired?Boolean

Checks if the token is expired or not

Returns:

  • (Boolean)

Raises:

  • (StandardError)


92
93
94
95
96
97
98
99
# File 'lib/acs/token_validator.rb', line 92

def expired?
  raise StandardError.new("Claims not defined in the token.") if(@claims.empty?)
  expires_on_seconds =  @claims[@expires_label]
  expiry_time = Time.at(expires_on_seconds.to_i)
  current_time = Time.new
  # Current timestamp must be less than expiration time stamp
  return (current_time > expiry_time)
end

#hmac_valid?Boolean

Checks the token against hmac key

Returns:

  • (Boolean)


66
67
68
69
70
71
72
# File 'lib/acs/token_validator.rb', line 66

def hmac_valid?
  @token_signature = @token.split('&' + @hmacSHA256_label + '=')
  return false if(@token_signature.size != 2)
  @computed_signature = Base64.encode64(HMAC::SHA256.digest(Base64.decode64(@trusted_signing_key), @token_signature.first))
  @computed_signature = @computed_signature.gsub("\n", "")
  return (@computed_signature == (CGI::unescape(@token_signature.last)))
end

#issuer_trusted?Boolean

Checks if the issuer in the token is the same as the trusted token issuer

Returns:

  • (Boolean)

Raises:

  • (StandardError)


102
103
104
105
106
# File 'lib/acs/token_validator.rb', line 102

def issuer_trusted?
  raise StandardError.new("Claims not defined in the token.") if(@claims.empty?)
  @issuer = @claims[@issuer_label]
  return ((@issuer.empty?) || (@issuer.casecmp(@trusted_token_issuer)  != 0))
end

#populate_claims(token_value) ⇒ Object

Extracts the claims from token

  • token_value: Token returned by the .NET services



86
87
88
89
# File 'lib/acs/token_validator.rb', line 86

def populate_claims(token_value)
  token_value.extend DotNetServices::HTTPRequests::ToHash
  @claims = token_value.to_hash
end

#validateObject

Validates the token based on hmac key, expiry, issuer and audience.



55
56
57
58
59
60
61
62
63
# File 'lib/acs/token_validator.rb', line 55

def validate
  return false if(@token[0..7] == "WRAPv0.8")
  return false unless hmac_valid?
  self.populate_claims(@token)
  return false if expired?
  return false unless issuer_trusted?
  return false unless audience_trusted?
  return true
end

#validate_claims(expected_claims) ⇒ Object

Validates claims received in the tokens with the expected claims

  • expected_claims: Hask containing key-value pairs of claims



76
77
78
79
80
81
82
# File 'lib/acs/token_validator.rb', line 76

def validate_claims(expected_claims)
  expected_claim_keys = expected_claims.keys
  expected_claim_keys.each do |key|
    return false unless @claims[key]
    return false unless (expected_claims[key] == @claims[key])
  end
end