2016-05-20 5 views
9

В настоящее время я работаю над проектом rails 4, и теперь мне нужно связать/подключить другое приложение (а не sso, но для доступа к API), например example .com. (Примечания:example.com использует 3 ножки архитектуры безопасности OAuth)Получение «Ошибка аутентификации! Invalid_credentials: OAuth2 :: Ошибка» для пользовательской стратегии omniauth

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

Для этого у меня есть ссылка this ссылка. По Strategy-Contribution-Guide Я могу завершить настройку и запросить фазу, здесь вы можете найти мой пример кода.

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) Authentication Failure! invalid_credentials: OAuth2 :: Ошибка.

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

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

@access_token = request_token.get_access_token(opts) 

Кроме того, для получения дополнительной информации я получаю сообщение об ошибке для build_access_token который метод oauth2

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

EDIT - 1

После отладки обнаружили, что получение этого вопроса от request method. (делая запрос Faraday). Вот фрагмент кода

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 потребительские мандатной.

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

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

+2

Вы раскрыли свой потребительский ключ и секрет потребителя здесь. Я попытался их отредактировать, однако это нужно будет подтвердить другим, прежде чем редактирование начнется в прямом эфире. Не забудьте немедленно удалить эти учетные данные и получить новые учетные данные, которые вы сохраняете конфиденциальными. –

+0

@ScottS. Спасибо за ваш ответ, я позабочусь об этом. Кстати, это случайные числа. –

+0

Есть ли причина, по которой вы не использовали https://github.com/intridea/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb, чтобы настроить свой oauth? –

ответ

2

Прежде всего, я тусклый, чтобы ясно, как oauth2 работы:

oauth2, протокол говорит:

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

    -> Тогда пользователи знаки в и перенаправляется на конечной точке Myweb/Public/OAuth с кодом

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

    POST ПРОВАЙДЕР код = d5Q3HC7EGNH36SE3N & client_id = d4HQNPFIXFD255H & client_secret = 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 Status 400 - Неадекватные учетные данные OAuth потребителей", я думаю, может быть вам:

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

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

+1

Если бы обсуждение с командой провайдера, они сказали, что поддерживают «OAuth1», а не «OAuth2», поэтому внесены изменения в файл стратегии. И он работает, чтобы найти данные (access_token). Спасибо за ответ. –

Смежные вопросы