Class: OmniAuth::Krystal::InitiatedLoginMiddleware
- Inherits:
-
Object
- Object
- OmniAuth::Krystal::InitiatedLoginMiddleware
- Defined in:
- lib/omniauth/krystal/initiated_login_middleware.rb
Defined Under Namespace
Classes: AntiReplayTokenAlreadyUsedError, Error, JWTDecodeError, JWTExpiredError
Constant Summary collapse
- JWT_RESERVED_CLAIMS =
%w[ar exp nbf iss aud jti iat sub].freeze
Instance Method Summary collapse
-
#call(env) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize.
-
#initialize(app, options = {}) ⇒ InitiatedLoginMiddleware
constructor
A new instance of InitiatedLoginMiddleware.
Constructor Details
#initialize(app, options = {}) ⇒ InitiatedLoginMiddleware
Returns a new instance of InitiatedLoginMiddleware.
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/omniauth/krystal/initiated_login_middleware.rb', line 23 def initialize(app, = {}) @app = app @options = @options[:provider_name] ||= 'krystal' @options[:identity_url] ||= ENV.fetch('KRYSTAL_IDENTITY_URL', 'https://identity.krystal.io') @options[:anti_replay_expiry_seconds] ||= 60 @keys = SigningKeys.new("#{@options[:identity_url]}/.well-known/signing.json") end |
Instance Method Details
#call(env) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/omniauth/krystal/initiated_login_middleware.rb', line 36 def call(env) unless env['PATH_INFO'] == "/auth/#{@options[:provider_name]}/callback" # If it's not a Krystal Identity auth callback then we don't # need to do anything here. return @app.call(env) end request = Rack::Request.new(env) state = request.params['state'] if state.nil? || !state.start_with?('kidil_') # Return to the app if the state is not a Krystal Identity # initiated login. return @app.call(env) end # Decode the JWT and ensure that the state is valid. JWT will check # the expiry. data = nil begin data, = JWT.decode(state.sub(/\Akidil_/, ''), nil, true, { algorithm: 'ES256', jwks: @keys }) rescue JWT::ExpiredSignature raise JWTExpiredError, 'State parameter has expired' rescue JWT::DecodeError raise JWTDecodeError, 'Invalid state parameter provided (either malformed, expired or signed with the wrong key)' end # Verify the replay token verify_anti_replay_token(data['ar']) # Set the expected omniauth state to the state that we have been given so it # thinks the session is trusted as normal. env['rack.session']['omniauth.state'] = state # Set any additional params that were passed in the state. env['rack.session']['omniauth.params'] = data.reject { |key| JWT_RESERVED_CLAIMS.include?(key) } @app.call(env) end |