我正在尝试让 Ruby Oauth2.0 客户端与 Ory Hydra docker-compose 5 分钟演示交谈。我被困在客户端应用程序的令牌身份验证代码交换上。日志如下。看起来主要问题是以下“hashedPassword 不是给定密码的哈希”。
来自 Hydra 服务器的调试日志
time="2019-06-04T21:32:09Z" level=info msg="started handling request" method=POST remote="172.19.0.2:35482" request=/oauth2/token
hydra_1
time="2019-06-04T21:32:09Z" level=error msg="An error occurred" debug="crypto/bcrypt: hashedPassword is not the hash of the given password" description="Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)" error=invalid_client
hydra_1
time="2019-06-04T21:32:09Z" level=info msg="completed handling request" measure#hydra/public: http://127.0.0.1:4444/.latency=92931900 method=POST remote="172.19.0.2:35482" request=/oauth2/token status=401 text_status=Unauthorized took=92.9319ms
我在这里读过,看来这“是”可能的。
这是我在 hydra 中注册客户“test-app9”的方法:
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app9 --secret secret--skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials
我确实可以从 docker-compose 演示中看到客户端出现在 postgres 数据库中。密码“秘密”在数据库中进行散列。
这是我作为 Oauth2.0 客户端的单个 Sinatra 文件:
require 'rubygems'
require 'sinatra'
require 'oauth2'
require 'json'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# If you add your authentication in the header then use ~Sclient_secret_basic~T
# If you add your authentication details in the post use ~Sclient_secret_post~T
def client
OAuth2::Client.new('test-app9',
'secret',
# 'c2VjcmV0',
:site => "http://127.0.0.1:4445",
:logger => Logger.new('example.log'),
:authorize_url => "http://127.0.0.1:4444/oauth2/auth",
:token_url => "http://hydra:4444/oauth2/token")
end
set :root, File.dirname(__FILE__)
set :views, Proc.new { File.join(root, "views") }
set :run, true
set :port, 80
get "/" do
erb :index
end
get '/auth' do
authorization_url = client.auth_code.authorize_url(:redirect_uri => redirect_uri, :response_type => "code", :scope => "profile", :state => "pqrst1234")
puts "Redirecting to URL: #{authorization_url.inspect}"
redirect authorization_url
end
get '/auth/callback' do
begin
access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri, :client_id => "test-app9", :client_secret => 'secret', :headers => {'Authorization' => 'basic_auth_header', 'client_id' => 'test-app9', 'client_secret' => 'c2VjcmV0'} )
api_url = "/me.json"
me = JSON.parse(access_token.get(api_url).body)
erb "<p>Your data:\n#{me.inspect}</p>"
rescue OAuth2::Error => e
erb %(<p>Wassup #{$!}</p><p><a href="/auth">Retry</a></p>)
end
end
get '/auth/failure' do
erb "<h1>Authentication Failed:</h1><h3>message:<h3> <pre>#{params}</pre>"
end
def redirect_uri(path = '/auth/callback', query = nil)
uri = URI.parse(request.url)
uri.path = path
uri.query = query
uri.to_s
end
__END__
所以一些有趣的笔记:
显然,我用什么秘密启动 OAuth2 客户端并不重要。我可以使用 'secret' 或 base64 编码的 'c2VjcmV0' 字符串。无论哪种方式,我都会进入令牌交换部分。
我对此进行了猛烈抨击,最终将 client_id 和 client_secret 放在我认为在标题和正文中设置的正确方法中。
我已经尝试了很多变化。似乎无法获得作者显然成功的正确语法,或者我遇到了一个错误(可疑)。
任何人都可以在这里提供帮助吗?
更新自己解决了这个问题。问题是创建我的客户端“应用程序”时的语法问题。这是修正版。
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app10 --secret secret --skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials