Class: OmniAuth::Strategies::OpenIDConnect

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
OmniAuth::Strategy
Defined in:
lib/omniauth/strategies/openid_connect.rb

Defined Under Namespace

Classes: CallbackError

Constant Summary collapse

RESPONSE_TYPE_EXCEPTIONS =
{
  'id_token' => { exception_class: OmniAuth::OpenIDConnect::MissingIdTokenError, key: :missing_id_token }.freeze,
  'code' => { exception_class: OmniAuth::OpenIDConnect::MissingCodeError, key: :missing_code }.freeze,
}.freeze

Instance Method Summary collapse

Instance Method Details

#authorization_codeObject



150
151
152
# File 'lib/omniauth/strategies/openid_connect.rb', line 150

def authorization_code
  params['code']
end

#authorize_uriObject



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/omniauth/strategies/openid_connect.rb', line 162

def authorize_uri
  client.redirect_uri = redirect_uri
  opts = {
    response_type: options.response_type,
    response_mode: options.response_mode,
    scope: options.scope,
    state: new_state,
    login_hint: params['login_hint'],
    ui_locales: params['ui_locales'],
    claims_locales: params['claims_locales'],
    prompt: options.prompt,
    nonce: (new_nonce if options.send_nonce),
    hd: options.hd,
    acr_values: options.acr_values,
  }

  opts.merge!(options.extra_authorize_params) unless options.extra_authorize_params.empty?

  client.authorization_uri(opts.reject { |_k, v| v.nil? })
end

#callback_phaseObject



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/omniauth/strategies/openid_connect.rb', line 110

def callback_phase
  error = params['error_reason'] || params['error']
  error_description = params['error_description'] || params['error_reason']
  invalid_state = params['state'].to_s.empty? || params['state'] != stored_state

  raise CallbackError, error: params['error'], reason: error_description, uri: params['error_uri'] if error
  raise CallbackError, error: :csrf_detected, reason: "Invalid 'state' parameter" if invalid_state

  return unless valid_response_type?

  options.issuer = issuer if options.issuer.nil? || options.issuer.empty?

  verify_id_token!(params['id_token']) if configured_response_type == 'id_token'
  discover!
  client.redirect_uri = redirect_uri

  return id_token_callback_phase if configured_response_type == 'id_token'

  client.authorization_code = authorization_code
  access_token
  super
rescue CallbackError => e
  fail!(e.error, e)
rescue ::Rack::OAuth2::Client::Error => e
  fail!(e.response[:error], e)
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
  fail!(:timeout, e)
rescue ::SocketError => e
  fail!(:failed_to_connect, e)
end

#clientObject



96
97
98
# File 'lib/omniauth/strategies/openid_connect.rb', line 96

def client
  @client ||= ::OpenIDConnect::Client.new(client_options)
end

#configObject



100
101
102
# File 'lib/omniauth/strategies/openid_connect.rb', line 100

def config
  @config ||= ::OpenIDConnect::Discovery::Provider::Config.discover!(options.issuer)
end

#end_session_uriObject



154
155
156
157
158
159
160
# File 'lib/omniauth/strategies/openid_connect.rb', line 154

def end_session_uri
  return unless end_session_endpoint_is_valid?

  end_session_uri = URI(client_options.end_session_endpoint)
  end_session_uri.query = encoded_post_logout_redirect_uri
  end_session_uri.to_s
end

#other_phaseObject



141
142
143
144
145
146
147
148
# File 'lib/omniauth/strategies/openid_connect.rb', line 141

def other_phase
  if logout_path_pattern.match?(current_path)
    options.issuer = issuer if options.issuer.to_s.empty?
    discover!
    return redirect(end_session_uri) if end_session_uri
  end
  call_app!
end

#public_keyObject



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/omniauth/strategies/openid_connect.rb', line 183

def public_key
  @public_key ||= begin
    if options.discovery
      config.jwks
    elsif configured_public_key
      configured_public_key
    elsif client_options.jwks_uri
      fetch_key
    end
  end
end

#request_phaseObject



104
105
106
107
108
# File 'lib/omniauth/strategies/openid_connect.rb', line 104

def request_phase
  options.issuer = issuer if options.issuer.to_s.empty?
  discover!
  redirect authorize_uri
end

#secretObject

Some OpenID providers use the OAuth2 client secret as the shared secret, but Keycloak uses a separate key that’s stored inside the database.



197
198
199
# File 'lib/omniauth/strategies/openid_connect.rb', line 197

def secret
  options.jwt_secret || base64_decoded_jwt_secret || client_options.secret
end

#uidObject



63
64
65
# File 'lib/omniauth/strategies/openid_connect.rb', line 63

def uid
  .raw_attributes[options.uid_field.to_sym] || .sub
end