Class: A2A::Client::Auth::JWT
- Inherits:
-
Object
- Object
- A2A::Client::Auth::JWT
- Defined in:
- lib/a2a/client/auth/jwt.rb
Instance Attribute Summary collapse
-
#algorithm ⇒ Object
readonly
Returns the value of attribute algorithm.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#payload ⇒ Object
readonly
Returns the value of attribute payload.
-
#secret ⇒ Object
readonly
Returns the value of attribute secret.
-
#token ⇒ Object
readonly
Returns the value of attribute token.
Instance Method Summary collapse
-
#apply_to_request(request) ⇒ Object
Apply authentication to a Faraday request.
-
#authorization_header ⇒ String
Get authorization header value.
-
#expires_at ⇒ Time?
Get token expiration time.
-
#generate_token ⇒ String
private
Generate a new JWT token.
-
#initialize(token: nil, secret: nil, algorithm: "HS256", payload: nil, headers: nil, expires_in: nil) ⇒ JWT
constructor
Initialize JWT authentication.
-
#jwt_token ⇒ String
Get a valid JWT token.
-
#regenerate_token! ⇒ String
Force regenerate the token (for dynamic tokens).
-
#token_expired?(token = nil) ⇒ Boolean
Check if the token is expired.
-
#validate_configuration! ⇒ Object
private
Validate the authentication configuration.
-
#validate_token(token = nil, verify_signature: true) ⇒ Hash
Validate the JWT token.
Constructor Details
#initialize(token: nil, secret: nil, algorithm: "HS256", payload: nil, headers: nil, expires_in: nil) ⇒ JWT
Initialize JWT authentication
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/a2a/client/auth/jwt.rb', line 27 def initialize(token: nil, secret: nil, algorithm: "HS256", payload: nil, headers: nil, expires_in: nil) @token = token @secret = secret @algorithm = algorithm @payload = payload || {} @headers = headers || {} @expires_in = expires_in @generated_token = nil @token_expires_at = nil @token_mutex = Mutex.new validate_configuration! end |
Instance Attribute Details
#algorithm ⇒ Object (readonly)
Returns the value of attribute algorithm.
16 17 18 |
# File 'lib/a2a/client/auth/jwt.rb', line 16 def algorithm @algorithm end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
16 17 18 |
# File 'lib/a2a/client/auth/jwt.rb', line 16 def headers @headers end |
#payload ⇒ Object (readonly)
Returns the value of attribute payload.
16 17 18 |
# File 'lib/a2a/client/auth/jwt.rb', line 16 def payload @payload end |
#secret ⇒ Object (readonly)
Returns the value of attribute secret.
16 17 18 |
# File 'lib/a2a/client/auth/jwt.rb', line 16 def secret @secret end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
16 17 18 |
# File 'lib/a2a/client/auth/jwt.rb', line 16 def token @token end |
Instance Method Details
#apply_to_request(request) ⇒ Object
Apply authentication to a Faraday request
71 72 73 |
# File 'lib/a2a/client/auth/jwt.rb', line 71 def apply_to_request(request) request.headers["Authorization"] = end |
#authorization_header ⇒ String
Get authorization header value
63 64 65 |
# File 'lib/a2a/client/auth/jwt.rb', line 63 def "Bearer #{jwt_token}" end |
#expires_at ⇒ Time?
Get token expiration time
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/a2a/client/auth/jwt.rb', line 136 def expires_at if @token_expires_at @token_expires_at elsif @token begin payload = validate_token(@token, verify_signature: false).first exp = payload["exp"] Time.zone.at(exp) if exp rescue A2A::Errors::AuthenticationError nil end end end |
#generate_token ⇒ String (private)
Generate a new JWT token
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/a2a/client/auth/jwt.rb', line 168 def generate_token raise ArgumentError, "Cannot generate token without secret" unless @secret # Build payload with expiration token_payload = @payload.dup if @expires_in now = Time.now.to_i token_payload["iat"] = now token_payload["exp"] = now + @expires_in @token_expires_at = Time.now + @expires_in end # Generate token @generated_token = ::JWT.encode(token_payload, @secret, @algorithm, @headers) rescue ::JWT::EncodeError => e raise A2A::Errors::AuthenticationError, "JWT generation failed: #{e.}" end |
#jwt_token ⇒ String
Get a valid JWT token
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/a2a/client/auth/jwt.rb', line 46 def jwt_token if @token # Static token @token else # Dynamic token generation @token_mutex.synchronize do generate_token if token_expired? @generated_token end end end |
#regenerate_token! ⇒ String
Force regenerate the token (for dynamic tokens)
124 125 126 127 128 129 130 |
# File 'lib/a2a/client/auth/jwt.rb', line 124 def regenerate_token! return @token if @token # Can't regenerate static tokens @token_mutex.synchronize do generate_token end end |
#token_expired?(token = nil) ⇒ Boolean
Check if the token is expired
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/a2a/client/auth/jwt.rb', line 98 def token_expired?(token = nil) return false unless @expires_in || token if @generated_token && @token_expires_at # Check generated token expiration Time.now >= (@token_expires_at - 30) # 30 second buffer elsif token || @token # Check token payload expiration begin payload = validate_token(token, verify_signature: false).first exp = payload["exp"] return false unless exp Time.now.to_i >= (exp - 30) # 30 second buffer rescue A2A::Errors::AuthenticationError true # Consider invalid tokens as expired end else false end end |
#validate_configuration! ⇒ Object (private)
Validate the authentication configuration
154 155 156 157 158 159 160 161 162 |
# File 'lib/a2a/client/auth/jwt.rb', line 154 def validate_configuration! raise ArgumentError, "Either token or secret must be provided" if @token.nil? && @secret.nil? raise ArgumentError, "Payload is required for dynamic token generation" if @token.nil? && @payload.empty? return if %w[HS256 HS384 HS512 RS256 RS384 RS512 ES256 ES384 ES512].include?(@algorithm) raise ArgumentError, "Unsupported JWT algorithm: #{@algorithm}" end |
#validate_token(token = nil, verify_signature: true) ⇒ Hash
Validate the JWT token
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/a2a/client/auth/jwt.rb', line 81 def validate_token(token = nil, verify_signature: true) token_to_validate = token || jwt_token if verify_signature && @secret ::JWT.decode(token_to_validate, @secret, true, { algorithm: @algorithm }) else ::JWT.decode(token_to_validate, nil, false) end rescue ::JWT::DecodeError => e raise A2A::Errors::AuthenticationError, "JWT validation failed: #{e.}" end |