У меня проблема с правильным ответом клиенту.Мой соответствующий код инициализатора выглядит следующим образом:
resource_owner_authenticator do
# Put your resource owner authentication logic here.
# Example implementation:
# User.find_by_id(session[:user_id]) || redirect_to(new_user_session_url)
passed_params = {}
%w(client_id redirect_uri state).each do |k|
passed_params[k] = params[k]
end
User.find_by_id(session['user_id']) || redirect_to(new_ldap_login_path(passed_params))
end
Здесь я передаю параметры в форму, которая запрашивает у пользователя учетные данные LDAP и переходит к методу создания в контроллере.
Вконтроллер Я выполняю аутентификацию LDAP и успешную аутентификацию upo. Я пытаюсь сгенерировать ответ:
if params[:client_id]
client_app = Doorkeeper::Application.where(uid: params[:client_id]).first
if client_app
redirect_to (client_app.redirect_uri +
'?' +
{ code: :what_is_supposed_to_be,
state: params[:state]
}.to_query)
, который выдает ошибку:
invalid_grant: Предоставленный грант авторизации недействителен, срок его действия истек, отозван, не совпадает с URI перенаправления, использованным в запросе авторизации, или был выдан другому клиенту.
При следующей попытке входа в систему поставщик не запрашивает учетные данные LDAP, и имя входа кажетсяработа в порядке.
угадывание
Может ли это привести к ответу?
https://github.com/doorkeeper-gem/doorkeeper/blob/master/lib/doorkeeper/oauth/code_response.rb
Как построить ответ, который не приводит кошибка?
другая подсказка
https://github.com/doorkeeper-gem/doorkeeper/blob/master/lib/doorkeeper/models/access_token_mixin.rb
предлагаемое решение
Создайте AccessToken и AccessGrant, убедившись, что токен совпадаетв обеих записях.По какой-то странной причине AccessGrant сохраняется с другим токеном.Почему мне нужно обновить токен в AccessGrant?
Как только у меня есть токен, я перенаправляю его на redirect_uri с токеном и состоянием в запросе.
if authenticated
if params[:client_id]
client_app = Doorkeeper::Application.where(uid: params[:client_id]).first
if client_app
# taken from Doorkeeper model code
#
# Looking for not expired AccessToken record with a matching set of
# scopes that belongs to specific Application and Resource Owner.
# If it doesn't exists - then creates it.
#
# @param application [Doorkeeper::Application]
# Application instance
# @param resource_owner_id [ActiveRecord::Base, Integer]
# Resource Owner model instance or it's ID
# @param scopes [#to_s]
# set of scopes (any object that responds to `#to_s`)
# @param expires_in [Integer]
# token lifetime in seconds
# @param use_refresh_token [Boolean]
# whether to use the refresh token
#
# @return [Doorkeeper::AccessToken] existing record or a new one
#
code = Doorkeeper::AccessToken.find_or_create_for(client_app,
@user.id,
nil,
7200,
true )
grant = Doorkeeper::AccessGrant.create(resource_owner_id: @user.id,
application_id: client_app.id,
token: code.token,
expires_in: 600,
redirect_uri: client_app.redirect_uri,
scopes: nil)
# why do I have to update the token?
grant.update(token: code.token)
redirect_to (client_app.redirect_uri +
'?' +
{ code: code.token,
state: params[:state]
}.to_query)