Class: Verikloak::Middleware

Inherits:
Object
  • Object
show all
Includes:
MiddlewareErrorMapping
Defined in:
lib/verikloak/middleware.rb

Overview

Rack middleware that verifies incoming JWT access tokens (Keycloak) using OpenID Connect discovery and JWKS. On success, it populates:

  • env` — the raw JWT string

  • env` — the decoded JWT claims Hash

Failures are converted to JSON error responses with appropriate status codes.

Constant Summary

Constants included from MiddlewareErrorMapping

Verikloak::MiddlewareErrorMapping::AUTH_ERROR_CODES, Verikloak::MiddlewareErrorMapping::INFRA_ERROR_CODES

Instance Method Summary collapse

Methods included from MiddlewareErrorMapping

#auth_error?, #dependency_error_tuple, #fallback_tuple, #forbidden?, #infra_error_tuple

Constructor Details

#initialize(app, discovery_url:, audience:, skip_paths: [], discovery: nil, jwks_cache: nil) ⇒ Middleware

Returns a new instance of Middleware.

Parameters:

  • app (#call)

    downstream Rack app

  • discovery_url (String)

    OIDC discovery endpoint URL

  • audience (String)

    Expected ‘aud` claim

  • skip_paths (Array<String>) (defaults to: [])

    Literal paths or wildcard patterns to bypass auth

  • discovery (Discovery, nil) (defaults to: nil)

    Custom discovery instance (for DI/tests)

  • jwks_cache (JwksCache, nil) (defaults to: nil)

    Custom JWKS cache instance (for DI/tests)



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/verikloak/middleware.rb', line 94

def initialize(app,
               discovery_url:,
               audience:,
               skip_paths: [],
               discovery: nil,
               jwks_cache: nil)
  @app           = app
  @audience      = audience
  @skip_paths    = skip_paths
  @discovery     = discovery || Discovery.new(discovery_url: discovery_url)
  @jwks_cache    = jwks_cache
  @issuer        = nil
  @mutex         = Mutex.new
end

Instance Method Details

#call(env) ⇒ Array(Integer, Hash, Array<String>)

Rack entrypoint.

Parameters:

  • env (Hash)

    Rack environment

Returns:

  • (Array(Integer, Hash, Array<String>))

    standard Rack response



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/verikloak/middleware.rb', line 113

def call(env)
  path = env['PATH_INFO']
  return @app.call(env) if skip?(path)

  token = extract_token(env)

  handle_request(env, token)
rescue Verikloak::Error => e
  code, status = map_error(e)
  error_response(code, e.message, status)
rescue StandardError => e
  log_internal_error(e)
  error_response('internal_server_error', 'An unexpected error occurred', 500)
end