Class: KeycloakApiRails::Service
- Inherits:
-
Object
- Object
- KeycloakApiRails::Service
- Defined in:
- lib/keycloak-api-rails/service.rb
Constant Summary collapse
- REALM_NAME =
/\A(?!\.+\z)[A-Za-z0-9._~-]{1,128}\z/.freeze
- SUPPORTED_ALGORITHMS =
%i[RS256 RS384 RS512 PS256 PS384 PS512 ES256 ES384 ES512].freeze
Instance Method Summary collapse
- #decode_and_verify(token) ⇒ Object
- #extract_realm_from_token(token) ⇒ Object
-
#initialize(key_resolver) ⇒ Service
constructor
A new instance of Service.
- #need_middleware_authentication?(method, path, headers) ⇒ Boolean
- #read_token(uri, headers) ⇒ Object
- #realm_allowed?(realm_id) ⇒ Boolean
Constructor Details
#initialize(key_resolver) ⇒ Service
Returns a new instance of Service.
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/keycloak-api-rails/service.rb', line 11 def initialize(key_resolver) configuration = KeycloakApiRails.config @key_resolver = key_resolver @skip_paths = normalize_skip_paths(configuration.skip_paths, configuration.logger) @opt_in = configuration.opt_in @token_expiration_tolerance_in_seconds = configuration.token_expiration_tolerance_in_seconds @expected_audiences = Array(configuration.expected_audience).map(&:to_s) @expected_token_type = configuration.expected_token_type @verify_not_before = configuration.verify_not_before @allow_token_in_query_string = configuration.allow_token_in_query_string @allowed_algorithms = Array(configuration.allowed_algorithms).map(&:to_sym) end |
Instance Method Details
#decode_and_verify(token) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/keycloak-api-rails/service.rb', line 24 def decode_and_verify(token) raise TokenError.no_token(token) if token.nil? || token.empty? parts = token.to_s.split('.') raise TokenError.invalid_format(token) if parts.length < 3 realm_id = extract_realm_from_token(token) raise TokenError.invalid_realm(token) unless realm_allowed?(realm_id) public_keys = @key_resolver.find_public_keys(realm_id) if public_keys.nil? raise MissingPublicKeysError, "No Keycloak public key is available to verify the token" end decoded_token = decode(token, public_keys) verify_claims!(token, decoded_token, realm_id) decoded_token end |
#extract_realm_from_token(token) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/keycloak-api-rails/service.rb', line 44 def extract_realm_from_token(token) payload_segment = token.split('.', 3)[1] return nil unless payload_segment decoded_payload = Base64.urlsafe_decode64(payload_segment) parsed_payload = JSON.parse(decoded_payload) if parsed_payload.is_a?(Hash) iss = parsed_payload['iss'] return nil unless iss.is_a?(String) realm_id = iss.split('/').last if realm_id&.match?(REALM_NAME) realm_id else nil end else nil end rescue JSON::ParserError, ArgumentError nil end |
#need_middleware_authentication?(method, path, headers) ⇒ Boolean
93 94 95 |
# File 'lib/keycloak-api-rails/service.rb', line 93 def need_middleware_authentication?(method, path, headers) !is_preflight?(method, headers) && (!@opt_in && !should_skip?(method, path)) end |
#read_token(uri, headers) ⇒ Object
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/keycloak-api-rails/service.rb', line 82 def read_token(uri, headers) header_token = Helper.read_token_from_headers(headers) if !header_token.empty? header_token elsif @allow_token_in_query_string Helper.read_token_from_query_string(uri).to_s else "" end end |
#realm_allowed?(realm_id) ⇒ Boolean
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/keycloak-api-rails/service.rb', line 68 def realm_allowed?(realm_id) config_realm_id = KeycloakApiRails.config.realm_id return true if config_realm_id.nil? return false if realm_id.nil? if config_realm_id.respond_to?(:call) config_realm_id.call(realm_id) elsif config_realm_id.is_a?(Array) config_realm_id.include?(realm_id) else config_realm_id == realm_id end end |