Class: Verikloak::Middleware
- Inherits:
-
Object
- Object
- Verikloak::Middleware
- Includes:
- MiddlewareAudienceResolution, MiddlewareConfiguration, MiddlewareDecoderCache, MiddlewareErrorMapping, MiddlewareJwksRefresh, MiddlewareTokenVerification, SkipPathMatcher
- 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['verikloak.token']— the raw JWT stringenv['verikloak.user']— the decoded JWT claims Hash
Failures are converted to JSON error responses with appropriate status codes.
Constant Summary collapse
- DEFAULT_REALM =
'verikloak'- DEFAULT_TOKEN_ENV_KEY =
'verikloak.token'- DEFAULT_USER_ENV_KEY =
'verikloak.user'- DEFAULT_DECODER_CACHE_LIMIT =
rubocop:disable Metrics/ParameterLists
128- DEFAULT_JWKS_REFRESH_INTERVAL =
60- MAX_TOKEN_BYTES =
Maximum token size in bytes to prevent DoS via oversized JWTs. Aligned with BFF's BFF::Constants::MAX_TOKEN_BYTES.
8192
Constants included from MiddlewareJwksRefresh
Verikloak::MiddlewareJwksRefresh::FORCED_REFRESH_MIN_INTERVAL
Constants included from MiddlewareErrorMapping
Verikloak::MiddlewareErrorMapping::AUTH_ERROR_CODES, Verikloak::MiddlewareErrorMapping::INFRA_ERROR_CODES
Instance Method Summary collapse
-
#call(env) ⇒ Array(Integer, Hash, Array<String>)
Rack entrypoint.
-
#initialize(app, discovery_url:, audience:, issuer: nil, skip_paths: [], discovery: nil, jwks_cache: nil, connection: nil, leeway: Verikloak::TokenDecoder::DEFAULT_LEEWAY, token_verify_options: {}, decoder_cache_limit: DEFAULT_DECODER_CACHE_LIMIT, jwks_refresh_interval: DEFAULT_JWKS_REFRESH_INTERVAL, token_env_key: DEFAULT_TOKEN_ENV_KEY, user_env_key: DEFAULT_USER_ENV_KEY, realm: DEFAULT_REALM, logger: nil, allow_http: false) ⇒ Middleware
constructor
A new instance of Middleware.
Constructor Details
#initialize(app, discovery_url:, audience:, issuer: nil, skip_paths: [], discovery: nil, jwks_cache: nil, connection: nil, leeway: Verikloak::TokenDecoder::DEFAULT_LEEWAY, token_verify_options: {}, decoder_cache_limit: DEFAULT_DECODER_CACHE_LIMIT, jwks_refresh_interval: DEFAULT_JWKS_REFRESH_INTERVAL, token_env_key: DEFAULT_TOKEN_ENV_KEY, user_env_key: DEFAULT_USER_ENV_KEY, realm: DEFAULT_REALM, logger: nil, allow_http: false) ⇒ Middleware
Returns a new instance of Middleware.
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
# File 'lib/verikloak/middleware.rb', line 736 def initialize(app, discovery_url:, audience:, issuer: nil, skip_paths: [], discovery: nil, jwks_cache: nil, connection: nil, leeway: Verikloak::TokenDecoder::DEFAULT_LEEWAY, token_verify_options: {}, decoder_cache_limit: DEFAULT_DECODER_CACHE_LIMIT, jwks_refresh_interval: DEFAULT_JWKS_REFRESH_INTERVAL, token_env_key: DEFAULT_TOKEN_ENV_KEY, user_env_key: DEFAULT_USER_ENV_KEY, realm: DEFAULT_REALM, logger: nil, allow_http: false) @app = app @connection = connection || Verikloak::HTTP.default_connection @audience_source = audience @discovery = discovery || Discovery.new(discovery_url: discovery_url, connection: @connection, allow_http: allow_http) @jwks_cache = jwks_cache @allow_http = allow_http @leeway = leeway @token_verify_options = || {} @decoder_cache_limit = normalize_decoder_cache_limit(decoder_cache_limit) @jwks_refresh_interval = normalize_jwks_refresh_interval(jwks_refresh_interval) @last_jwks_refresh_at = nil # Optional user-configured issuer (overrides discovery issuer when provided) @configured_issuer = issuer # Effective issuer; may be nil initially and set via discovery if not configured @issuer = @configured_issuer @mutex = Mutex.new @decoder_cache = {} @decoder_cache_order = [] @last_cached_keys_id = nil @keys_digest_memo = nil @token_env_key = normalize_env_key(token_env_key, 'token_env_key') @user_env_key = normalize_env_key(user_env_key, 'user_env_key') @realm = normalize_realm(realm) @logger = logger compile_skip_paths(skip_paths) end |
Instance Method Details
#call(env) ⇒ Array(Integer, Hash, Array<String>)
Rack entrypoint.
787 788 789 790 791 792 793 794 795 796 797 798 799 |
# File 'lib/verikloak/middleware.rb', line 787 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., status) rescue StandardError => e log_internal_error(e) error_response('internal_server_error', 'An unexpected error occurred', 500) end |