Class: Faraday::HttpSignature::Middleware

Inherits:
Middleware
  • Object
show all
Defined in:
lib/faraday/http_signature/middleware.rb

Overview

Faraday middleware for HTTP message signing and verification (RFC 9421).

When registered via request, signs outgoing requests (default). When registered via response, verifies incoming response signatures. When registered via use, signs requests by default; pass verify_response: true to also verify responses.

Verification result metadata

After response verification, the middleware stores results in env[:http_signature_verified] (true or false) and env[:http_signature] (the Linzer::Signature on success). These are accessible via response.env[:http_signature_verified].

Examples:

Sign requests

conn = Faraday.new(url: "https://example.com") do |f|
  f.request :http_signature, key: my_key, components: %w[@method @path]
end

Verify responses

conn = Faraday.new(url: "https://example.com") do |f|
  f.response :http_signature, verify_key: server_pubkey
end

Lenient verification (no exception on failure)

conn = Faraday.new(url: "https://example.com") do |f|
  f.response :http_signature, verify_key: server_pubkey, strict: false
end
response = conn.get("/")
response.env[:http_signature_verified]  # => true or false

See Also:

Direct Known Subclasses

Request, Response

Defined Under Namespace

Classes: Options, Request, Response

Constant Summary collapse

DEFAULT_OPTIONS =

Default options for the base middleware class (used by use and request registrations). Signs requests, does not verify responses, strict mode enabled.

{
  sign_request:    true,
  verify_response: false,
  strict:          true
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, options = nil) ⇒ Middleware

Creates a new middleware instance.

Merges class-level DEFAULT_OPTIONS with the user-provided options so that subclasses (Request, Response) can override defaults.

Parameters:

  • app (#call)

    the next middleware or adapter in the stack

  • options (Hash, nil) (defaults to: nil)

    middleware options

Options Hash (options):

  • :key (Linzer::Key)

    generic key for signing or verification

  • :sign_key (Linzer::Key)

    explicit signing key

  • :verify_key (Linzer::Key)

    explicit verification key

  • :components (Array<String>)

    components to sign

  • :params (Hash)

    additional signature parameters

  • :sign_request (Boolean) — default: +true+

    whether to sign requests

  • :verify_response (Boolean) — default: +false+

    whether to verify responses

  • :strict (Boolean) — default: +true+

    raise on verification failure



166
167
168
169
170
171
# File 'lib/faraday/http_signature/middleware.rb', line 166

def initialize(app, options = nil)
  super(app)
  defaults = self.class::DEFAULT_OPTIONS
  merged = defaults.merge(Hash(options))
  @options = Options.from(merged)
end

Instance Method Details

#on_complete(env) ⇒ Faraday::Env?

Verifies the response signature when Faraday::HttpSignature::Middleware::Options#verify_response? is true.

On success, sets env[:http_signature_verified] to true and env[:http_signature] to the verified Linzer::Signature.

On failure in strict mode (default), raises VerifyError. In lenient mode (+strict: false+), sets env[:http_signature_verified] to false and allows the response to continue through the middleware stack.

Parameters:

  • env (Faraday::Env)

    the middleware environment

Returns:

  • (Faraday::Env, nil)

    the modified env, or nil if verifying is disabled

Raises:

  • (VerifyError)

    if verification fails and strict is true

  • (Linzer::Error)

    if no valid verification key is available



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/faraday/http_signature/middleware.rb', line 213

def on_complete(env)
  env[:http_signature_verified] = false
  return unless options.verify_response?

  key = resolve_verify_key
  response = ::Faraday::Response.new(env)
  message = Linzer::Message.new(response)
  signature = Linzer::Signature.build(response.headers)

  Linzer.verify(key, message, signature)
  env[:http_signature_verified] = true
  env[:http_signature] = signature
  env
rescue Linzer::Error => e
  raise VerifyError.new(e, response: response) if options.strict?
end

#on_request(env) ⇒ Faraday::Env?

Signs the outgoing request when Faraday::HttpSignature::Middleware::Options#sign_request? is true.

Resolves the signing key, builds a Linzer::Message from the Faraday environment, generates a signature over the configured components, and merges the signature and signature-input headers into the request.

Parameters:

  • env (Faraday::Env)

    the middleware environment

Returns:

  • (Faraday::Env, nil)

    the modified env, or nil if signing is disabled

Raises:



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/faraday/http_signature/middleware.rb', line 184

def on_request(env)
  return unless options.sign_request?

  key = resolve_signing_key
  request = Linzer::Faraday::Utils.create_request(env)
  message = Linzer::Message.new(request)

  signature = Linzer.sign(key, message, options.components, options.params)
  env.request_headers.merge!(signature.to_h)
  env
rescue Linzer::Error => e
  raise SigningError, e if options.strict?
end