簡體   English   中英

獲得“身份驗證失敗! invalid_credentials:OAuth2 :: Error“用於自定義omniauth策略

[英]Getting “Authentication failure! invalid_credentials: OAuth2::Error” for custom omniauth strategy

目前我正在開發rails 4項目,現在我必須鏈接/連接另一個應用程序(不是用於訪問API的sso),例如example.com 注意: example.com使用3腳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 (你會問你怎么知道,所以答案是我在callback_phase方法中添加了binding.pry來檢查流程)。

但在執行策略后,我遇到了錯誤

錯誤 - 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 )。

編輯 - 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狀態400 - OAuth使用者憑據不足。

那么任何人都可以幫助解決這個問題嗎?

是否有任何其他方式來存儲訪問令牌,以便我可以利用它來進行通信。 謝謝

首先,我想說清楚Oauth2是如何工作的:

Oauth2,協議說:

  1. 您將用戶重定向到提供者登錄端點,添加一些必需參數(Ejm:PROVIDER / public / oauth?redirect_uri = MYWEB / oauthDemo&response_type = code&client_id = ABCDE)。 有時還有一個范圍/權限/資源參數,指示您的目的是什么。

    - >然后用戶登錄並使用代碼重定向到您的端點MYWEB / public / oauth

  2. 現在,您必須請求訪問令牌對提供程序端點執行POST。 例:

    POST PROVIDER?code = d5Q3HC7EGNH36SE3N&client_id = d4HQNPFIXFD255H&client_secret = 1a98b7cb92407cbd8961cd8db778de53&redirect_uri = https://example.com/oauthDemo& grant_type = authorization_code

  3. 現在您擁有access_token,您可以使用它來獲取信息或使用JWT對其進行解碼。


清楚這一點,看到你的電話似乎是核心:

  #<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消費者憑證不足。”,我想也許你:

一個。 您的客戶端在提供商上配置不正確。 通常,您使用提供程序站點上的基本配置,以便他能夠識別您。 所以可能沒有很好的配置。

在第一步(在重定向到提供程序中)中缺少或錯誤配置了資源/權限/范圍參數。 因此,當您要求令牌時,存在問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM