Получение " ошибка аутентификации! недопустимые учетные данные: OAuth2:: Error " для пользовательской стратегии omniauth

в настоящее время я работаю над проектом rails 4, и теперь мне нужно связать / подключить другое приложение (не sso, а для доступа к API), скажем example.com. (Примечание: example.com использует архитектуру безопасности 3-legged oauth)

после поиска выяснилось, что я должен реализовать стратегию omniouth.

за это я судил этой ссылка. Согласно Стратегия-Вклад-Руководство я могу завершить этап установки и запроса, вы можете найти мой пример кода здесь.

require 'multi_json'
require 'omniauth/strategies/oauth2'
require 'uri'

module OmniAuth
  module Strategies
    class MyAppStrategy < OmniAuth::Strategies::OAuth2
      option :name, 'my_app_strategy'

   option :client_options, {
    site: site_url,
    authorize_url: authorize_url,
    request_url: request_url,
    token_url: token_url,
    token_method: :post,
    header: { Accept: accept_header }
  }

  option :headers, { Accept: accept_header }
  option :provider_ignores_state, true

  def consumer
    binding.pry
    ::OAuth::Consumer.new(options.client_id, options.client_secret, options.client_options)
  end

  def request_phase # rubocop:disable MethodLength
    binding.pry
    request_token = consumer.get_request_token({:oauth_callback => callback_url}, options.request_params)
    session["oauth"] ||= {}
    session["oauth"][name.to_s] = {"callback_confirmed" => request_token.callback_confirmed?, "request_token" => request_token.token, "request_secret" => request_token.secret}

    if request_token.callback_confirmed?
      redirect request_token.authorize_url(options[:authorize_params])
    else
      redirect request_token.authorize_url(options[:authorize_params].merge(:oauth_callback => callback_url))
    end

  rescue ::Timeout::Error => e
    fail!(:timeout, e)
  rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
    fail!(:service_unavailable, e)
  end

  def callback_phase # rubocop:disable MethodLength
    fail(OmniAuth::NoSessionError, "Session Expired") if session["oauth"].nil?

    request_token = ::OAuth::RequestToken.new(consumer, session["oauth"][name.to_s].delete("request_token"), session["oauth"][name.to_s].delete("request_secret"))

    opts = {}
    if session["oauth"][name.to_s]["callback_confirmed"]
      opts[:oauth_verifier] = request["oauth_verifier"]
    else
      opts[:oauth_callback] = 'http://localhost:3000/auth/callback' #callback_url
    end

    @access_token = request_token.get_access_token(opts)
    super
    rescue ::Timeout::Error => e
      fail!(:timeout, e)
    rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
      fail!(:service_unavailable, e)
    rescue ::OAuth::Unauthorized => e
      fail!(:invalid_credentials, e)
    rescue ::OmniAuth::NoSessionError => e
      fail!(:session_expired, e)
  end

  def custom_build_access_token
    binding.pry
    verifier = request["oauth_verifier"]
    client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params))
  end
  alias_method :build_access_token, :custom_build_access_token

  def raw_info
    binding.pry
    @raw_info ||= access_token.get('users/me').parsed || {}
  end

  private

  def callback_url
    options[:redirect_uri] || (full_host + script_name + callback_path)
  end

  def get_token_options(redirect_uri)
    { :redirect_uri => redirect_uri }.merge(token_params.to_hash(:symbolize_keys => true))
  end
end
end

конец

Я могу перенаправить на example.com, также после входа в систему я могу вернуться к моему callback_phase (вы спросите, как вы узнали, так что ответ я добавил binding.pry на callback_phase метод проверки расхода).

но после выполнения стратегии я получение следующей ошибки

ошибка -- omniauth: (my_app_strategy) ошибка аутентификации! invalid_credentials: что OAuth2::ошибка.

после отладки обнаружил, что я получаю эту ошибку для super вызов (из метода callback_phase).

сначала я, хотя, возможно, есть некоторые проблемы с учетными данными, но я могу получить маркер доступа, используя следующее (которое выполняется перед super звонок)

@access_token = request_token.get_access_token(opts)

также для более информация я получаю ошибку для build_access_token который является методом oauth2

вы можете обратиться этой ссылка для получения дополнительной информации (просто найдите build_access_token на странице).

EDIT-1

после отладки обнаружил, что получение этой проблемы из метод запроса. (Делая запрос Фарадея). Вот фрагмент кода

response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
    yield(req) if block_given?
  end

вот мой Фарадея запрос

#<struct Faraday::Request method=:post, path="example.com/oauth/access_token", params={}, headers={"User-Agent"=>"Faraday v0.9.2", "Content-Type"=>"application/x-www-form-urlencoded"}, body={"grant_type"=>"authorization_code", "code"=>"aPexxxvUg", "client_id"=>"xxxxxur303GXEch7QK9k", "client_secret"=>"xxxxxxcad97b3d252e2bcdd393a", :redirect_uri=>"http://localhost:3000/auth/my_app_strategy/callback"}, options=#<Faraday::RequestOptions (empty)>>

в ответ я получаю следующее сообщение об ошибке

HTTP Status 400-неадекватные учетные данные потребителя OAuth.

так может ли кто-нибудь помочь исправить эту проблему?

есть ли другой способ сохранить маркер доступа, чтобы я мог использовать его для целей связи. Спасибо

1 ответов


прежде всего, я хочу прояснить, как работает Oauth2:

OAuth2, то в протоколе написано:

  1. вы перенаправляете пользователя в конечную точку входа поставщика, добавляя некоторые необходимые параметры (EJM: PROVIDER/public/oauth?redirect_uri=MYWEB/oauthDemo& response_type=code&client_id=ABCDE). Иногда также есть параметр scope/permission/resource, который указывает, какова ваша цель.

    - > затем пользователи входят в систему и перенаправляются на ваш конечная точка MYWEB / public/oauth с кодом

  2. теперь вам нужно запросить маркер доступа, выполняющий запись в конечную точку поставщиков. Пример:

    ПОСТАВЩИК ПОЧТЫ?код=d5Q3HC7EGNH36SE3N& client_id=d4HQNPFIXFD255H& секрет клиента=1a98b7cb92407cbd8961cd8db778de53& redirect_uri=https://example.com/oauthDemo& grant_type=authorization_code произвести

  3. теперь у вас есть access_token, и вы можете использовать его для получения информация или декодировать его с помощью JWT.


имея это ясно, и видя, что ваш вызов кажется corect:

  #<struct Faraday::Request method=:post, path="PROVIDER/oauth/access_token", params={}, headers={"User-Agent"=>"Faraday v0.9.2", "Content-Type"=>"application/x-www-form-urlencoded"}, body={"grant_type"=>"authorization_code", "code"=>"aPexxxvUg", "client_id"=>"xxxxxur303GXEch7QK9k", "client_secret"=>"xxxxxxcad97b3d252e2bcdd393a", :redirect_uri=>"MYWEB/auth/my_app_strategy/callback"}, options=#<Faraday::RequestOptions (empty)>>

как ответ " состояние HTTP 400-неадекватные учетные данные потребителя OAuth.", Я думаю, может быть, вы:

a. Ваш клиент плохо настроен на провайдере. Обычно вы используете базовую конфигурацию на сайте поставщика, чтобы он мог вас узнать. Поэтому, возможно, не очень хорошо настроен.

b. Существует параметр resource / permission / scope отсутствует или неправильно настроен на первом шаге (при перенаправлении к поставщику). Поэтому, когда вы просите токен, возникает проблема.