Doorkeeper :: AuthorizationsController # create Не удается проверить подлинность токена CSRF

Я перешел на страницу https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Resource-Owner-Password-Credentials-flow путем тестирования API.

curl -F grant_type=password \
-F [email protected] \
-F password=mypass \
-X POST http://localhost:3000/oauth/token

И я получил ответ:

{"access_token": "6d4398b75d94835631a453af770161a6f58618b101b58ccf62a5a8492bce3440", "token_type": "bearer", "expires_in": 600, "refresh_token": "c1445d08cfd03cf2c8ec8e8c8e8ec8e8c8e8c8e8c8e8ec8e8ec8ec8e8ec8e8ec8

Но когда я вызываю / oauth / authorize с помощью:

curl -F response_type=6d4398b75d94835631a453af770161a6f58618b101b58ccf62a5a8492bce3440 \ -F client_id=9c291dc4aa87bfafd6c6a4cf6930d225c106f8fe88e1d0769832047f1ee011c4 \ -F client_secret=decba5aca425095978d33653ef03d654f0b74427bcec0596bdde518016708c35 \ -F redirect_uri=urn:ietf:wg:oauth:2.0:oob \ -F [email protected] \ -X POST http://localhost:3000/oauth/authorize

Но я получил:

Запущен POST "/ oauth / authorize" для 127.0.0.1 в 2015-04-25 00:30:05 -0300 Обработка Doorkeeper :: AuthorizationsController # create as / Параметры: {"response_type" => "6d4398b75d94835631a453af770161a6f58618b101b58ccf62a5a8492bce3440", "client_id" => "9c291dc4aa87bfafd6c6a4cf6930d225c106f8fe88e1d0769832047f1ee011c4", "client_secret" => "[ФИЛЬТРИРОВАНЫЕ]", "redirect_uri" => "урна: IETF: Рабочая группа по OAuth: 2,0: OOB", "имя пользователя" => "Foo @ bar.com "} Не удается проверить подлинность токена CSRF Завершено 422 Необработанная сущность за 1 мс ActionController :: InvalidAuthenticityToken (ActionController :: InvalidAuthenticityToken): ...

Что я делаю неправильно?


person Marcos Sousa    schedule 25.04.2015    source источник
comment
Это ожидаемое поведение. Форма авторизации отображается как HTML в приложении поставщика, и, к счастью, Rails по умолчанию проверяет, соответствует ли токен CSRF, который он отображает в форме, при отправке формы. Таким образом, команда curl без этого токена вызовет ошибку проверки CSRF.   -  person TuteC    schedule 25.04.2015
comment
Я знаю это, но я пытаюсь использовать Doorkeep oauth2 для написания API, а API не отображает HTML.   -  person Marcos Sousa    schedule 25.04.2015
comment
Если вы понимаете риски, вы можете отключить защиту от подделки Rails для этого действия контроллера. Doorkeeper не предоставляет возможности для этого, вам нужно будет повторно открыть этот контроллер.   -  person TuteC    schedule 25.04.2015
comment
лучше настроить gem привратника для поддержки потока учетных данных пароля владельца ресурса (github.com/doorkeeper-gem/doorkeeper/wiki/) в случаях, когда вы хотите разрешить клиенту API запрашивать имя пользователя и пароль. Используемый вами поток предназначен для перенаправления пользователя на вашу веб-службу для безопасного входа в систему и никогда не раскрывать учетные данные пользователя сторонним приложениям.   -  person Michael Reinsch    schedule 17.12.2015
comment
@MarcosSousa вы решили эту проблему?   -  person Sebastian Roth    schedule 12.12.2016


Ответы (2)


Если вы работаете только с API, я предполагаю, что вы можете просто отключить его в файле среды (test / developmentpement / production.rb), добавив эту строку:

config.action_controller.allow_forgery_protection = false'

Ваше здоровье !

person Edouard Brèthes    schedule 20.05.2015
comment
это довольно плохая идея, защита CSRF существует не просто так. В этом случае он защищает часть потока OAuth, через который пользователь проходит в своем браузере. - person Michael Reinsch; 17.12.2015
comment
Вот почему я сначала рассказал об API. Без доступа к браузеру защита CSRF бесполезна. - person Edouard Brèthes; 18.12.2015

Похоже, что во втором запросе вы используете токен для response_type. Думаю, должно быть authorization_code.

Однако, судя по первому ответу, похоже, что он дает вам жетон на предъявителя. Если это так, то для просмотра защищенной страницы (имеющей before_action: doorkeeper_authorize) команда будет выглядеть так:

curl http://localhost:3000/protected_page -H "Authorization: Bearer 6d4398b75d94835631a453af770161a6f58618b101b58ccf62a5a8492bce3440"

Библиотека OAuth2

Вам нужно использовать завиток? У меня такая же ошибка с токеном аутентичности CSRF, поскольку он думает, что это запрос формы, но у меня он работает с гемом OAuth2.

Зарегистрируйте приложение (предположительно, оно защищено) в /oauth/applications, перейдите к нему, нажмите Authorize, нажмите Approve, и вы увидите, что вы отправили POST на URL-адрес типа http://localhost:3000/oauth/authorize?client_id=abc123&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code с параметрами "utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "state"=>"", "scope"=>"public" abc123 - это ваша одноразовая аутентификация код.

Но вы все еще не авторизовали свое приложение. Итак, возьмем access_token и refresh_token.

client_id = "9c291dc4aa87bfafd6c6a4cf6930d225c106f8fe88e1d0769832047f1ee011c4"
client_secret = "decba5aca425095978d33653ef03d654f0b74427bcec0596bdde518016708c35"
site = "http://localhost:3000"
redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
code = "abc123" # see above
ENV['OAUTH_DEBUG'] = 'true'
client = OAuth2::Client.new(client_id, client_secret, :site => site)
token = client.auth_code.get_token(code, redirect_uri: redirect_uri)
access_token = token.token
refresh_token = token.refresh_token
# And if you want:
# if token.expired?
#   new_token = token.refresh!
#   new_token.token
#   new_token.refresh_token
# end

Если вы перейдете на http://localhost:3000/oauth/authorized_applications, вы увидите, что ваше приложение сейчас в списке.

Теперь вы можете просматривать защищенные страницы с помощью чего-то вроде curl -X GET http://localhost:3000/protected_page -H "Authorization: Bearer #{access_token}"

См. Также https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples

Возможно полезная информация: что нужно Doorkeeper для проверки кода авторизации

redirect_uri.present?
grant = Doorkeeper::AccessGrant.by_token(authorization_code)
grant.redirect_uri == redirect_uri
application = Doorkeeper::Application.by_uid_and_secret(client_id, client_secret)
dk_client = Doorkeeper::OAuth::Client.new(application)
!!dk_client
grant.application_id == dk_client.id
grant.accessible? #  !grant.expired? && !grant.revoked?

Видеть