class Google::Auth::TokenValidator
Constants
- CLOCK_SKEW_SECONDS
- GOOGLE_SIGNON_CERTS_URL
- ISSUERS
- MAX_TOKEN_LIFETIME_SECONDS
- VERSION
Attributes
_cached_certs[RW]
client_id[R]
envelope[R]
payload[R]
signature[R]
signed[R]
Public Class Methods
_certs()
click to toggle source
# File lib/googleauth/token_validator.rb, line 80 def _certs @_cached_certs ||= begin uri = URI(GOOGLE_SIGNON_CERTS_URL) JSON.parse Net::HTTP.get(uri) end end
new(jwt, client_id)
click to toggle source
# File lib/googleauth/token_validator.rb, line 16 def initialize jwt, client_id segments = jwt.split(".") fail Error, "Wrong number of segments in token: #{jwt}" unless segments.size.eql? 3 @client_id = client_id @signed = "#{segments[0]}.#{segments[1]}" @signature = segments[2] @envelope = JSON.parse Base64.decode64(segments[0]) @payload = JSON.parse Base64.decode64(segments[1]) end
Public Instance Methods
validate(max_expiry = MAX_TOKEN_LIFETIME_SECONDS)
click to toggle source
# File lib/googleauth/token_validator.rb, line 30 def validate max_expiry = MAX_TOKEN_LIFETIME_SECONDS unless [@signed, @signature, @envelope, @payload].all? fail Error, "Validator was not properly initialized" end unless self.class._certs.keys.include? @envelope["kid"] fail Error, "No matching Google cert found for envelope: #{@envelope}" end pem = self.class._certs[envelope["kid"]] cert = OpenSSL::X509::Certificate.new pem digest = OpenSSL::Digest::SHA256.new verified = cert.public_key.verify(digest, Base64.urlsafe_decode64(@signature), @signed) fail Error, "Token signature invalid" unless verified fail Error, "No issue time in token" if @payload["iat"].to_s.empty? fail Error, "No expiration time in token" if @payload["exp"].to_s.empty? now = Time.now.to_i earliest = @payload["iat"] - CLOCK_SKEW_SECONDS latest = @payload["exp"] + CLOCK_SKEW_SECONDS fail Error, "Expiration time too far in future" if @payload["exp"] >= Time.now.to_i + max_expiry fail Error, "Token used too early" if now < earliest fail Error, "Token used too late" if now > latest unless ISSUERS.include? @payload["iss"] fail Error, "Invalid issuer. Expected one of #{ISSUERS}, but got #{@payload["iss"]}" end if @client_id.is_a? Array aud_verified = @client_id.include?(@payload["aud"]) elsif @client_id.is_a? String aud_verified = @payload["aud"] == @client_id else fail Error, "Invalid client id(s)" end unless aud_verified fail Error, "Wrong recipient - payload audience doesn't match required audience" end return true end