Module: Verikloak::BFF::ForwardedToken

Defined in:
lib/verikloak/bff/forwarded_token.rb

Overview

Helpers to extract and normalize forwarded/access token headers.

Constant Summary collapse

FORWARDED_HEADER =
Verikloak::HeaderSources::DEFAULT_FORWARDED_HEADER
AUTH_HEADER =
Verikloak::HeaderSources::AUTHORIZATION_HEADER

Class Method Summary collapse

Class Method Details

.ensure_bearer(token) ⇒ String

Normalize to a proper 'Bearer ' header value.

  • Detects scheme case-insensitively
  • Inserts a missing space (e.g., 'BearerXYZ' => 'Bearer XYZ')
  • Collapses multiple spaces/tabs after the scheme to a single space

Parameters:

  • token (String)

Returns:

  • (String)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/verikloak/bff/forwarded_token.rb', line 68

def ensure_bearer(token)
  s = sanitize(token)
  # Case-insensitive 'Bearer' with spaces/tabs after
  if s =~ /\ABearer[ \t]+/i
    rest = s.sub(/\ABearer[ \t]+/i, '')
    return "Bearer #{rest}"
  end

  # Case-insensitive 'Bearer' with no separator (e.g., 'BearerXYZ')
  if s =~ /\ABearer(?![ \t])/i
    rest = s[6..] || ''
    return "Bearer #{rest}"
  end

  # No scheme present; add it
  "Bearer #{s}"
end

.extract(env, forwarded_header_name = FORWARDED_HEADER, auth_header_name = AUTH_HEADER) ⇒ Array(String, String)

Extract normalized tokens from the Rack env.

Parameters:

  • env (Hash)
  • forwarded_header_name (String) (defaults to: FORWARDED_HEADER)

    Rack env key for forwarded header

  • auth_header_name (String) (defaults to: AUTH_HEADER)

    Rack env key for Authorization header

Returns:

  • (Array(String, String))

    [auth_token, forwarded_token]



25
26
27
28
29
# File 'lib/verikloak/bff/forwarded_token.rb', line 25

def extract(env, forwarded_header_name = FORWARDED_HEADER, auth_header_name = AUTH_HEADER)
  fwd_raw = env[forwarded_header_name]
  auth_raw = env[auth_header_name]
  [normalize_auth(auth_raw), normalize_forwarded(fwd_raw)]
end

.normalize_auth(raw) ⇒ String?

Only accept Bearer scheme for Authorization header. A scheme without a token (e.g. "Bearer" or "Bearer ") is treated as absent so that an empty Authorization header never shadows a valid forwarded token.

The pattern is anchored with \A/\z (not ^/$) so a multi-line value cannot smuggle a "Bearer " line past a non-Bearer first line, and only space/tab may separate the scheme from the token.

Parameters:

  • raw (String, nil)

Returns:

  • (String, nil)

    token or nil when not Bearer or token is empty



42
43
44
45
46
# File 'lib/verikloak/bff/forwarded_token.rb', line 42

def normalize_auth(raw)
  return nil unless raw

  raw.to_s.strip[/\ABearer[ \t]*(.+)\z/i, 1]
end

.normalize_forwarded(raw) ⇒ String?

Accept either bare token or Bearer for forwarded header.

Parameters:

  • raw (String, nil)

Returns:

  • (String, nil)

    token or nil



52
53
54
55
56
57
58
59
# File 'lib/verikloak/bff/forwarded_token.rb', line 52

def normalize_forwarded(raw)
  return nil unless raw

  token = raw.to_s.strip
  token = token.sub(/^Bearer\s+/i, '') if token =~ /^Bearer\s+/i

  token.empty? ? nil : token
end

.sanitize(token) ⇒ String

Remove CRLF and other control characters to prevent header injection.

Parameters:

  • token (String)

Returns:

  • (String)


101
102
103
# File 'lib/verikloak/bff/forwarded_token.rb', line 101

def sanitize(token)
  token.to_s.gsub(/[[:cntrl:]]/, '').strip
end

.set_authorization!(env, token) ⇒ void

This method returns an undefined value.

Set Authorization header to a normalized Bearer value. Always overwrites the existing Authorization header to ensure the chosen token and Authorization are synchronized.

Parameters:

  • env (Hash)
  • token (String)


93
94
95
# File 'lib/verikloak/bff/forwarded_token.rb', line 93

def set_authorization!(env, token)
  env[AUTH_HEADER] = ensure_bearer(token)
end

.strip_suspicious!(env, headers = nil) ⇒ void

This method returns an undefined value.

Remove potentially forged X-Auth-Request-* headers before passing downstream when not emitted by a trusted proxy.

Parameters:

  • env (Hash)
  • headers (Hash{Symbol=>String}, nil) (defaults to: nil)

    explicit headers to strip



111
112
113
114
# File 'lib/verikloak/bff/forwarded_token.rb', line 111

def strip_suspicious!(env, headers = nil)
  headers = Constants::DEFAULT_AUTH_REQUEST_HEADERS unless headers.is_a?(Hash)
  headers.each_value { |h| env.delete(h) }
end