【问题标题】:Doorkeeper Refresh Tokens Not Expiring on Reuse门卫刷新令牌在重用时不会过期
【发布时间】:2020-02-04 21:14:59
【问题描述】:

我正在使用 Doorkeeper 5.2.1,我咨询了 Doorkeeper docs on refresh tokens,并阅读了几个与刷新令牌相关的 GitHub 问题和拉取请求,特别是 herehere

根据我从这些对话和阅读规范中收集到的信息(以及documents and posts referencing the spec,以下陈述是正确的:

  • 刷新令牌的寿命很长(与访问令牌相反,访问令牌通常在相对较短的 TTL 后过期)
  • 授权服务器可以实现撤销
  • Doorkeeper 在某些基础上实现了刷新令牌撤销(虽然我不清楚是什么,请继续阅读)

不过,我很困惑,基于this pull request,它在“使用该刷新令牌创建的访问令牌成功使用一次”后实现刷新令牌到期。 Doorkeeper 如何知道我是否已成功使用该访问令牌发出 API 请求?我的 API 根据该访问令牌计算出授权逻辑。 Doorkeeper 不知道我的 API 请求是否成功。但是,我将其解释为如果 resource_owner_authenticator 块返回用户,则可能构成成功使用。但是我还没有发现刷新令牌成功过期。 (请参阅下面的规范。)

从阅读this spec file 中也可以看出,如果您成功使用了刷新令牌,它会撤销之前的刷新令牌,这是有道理的。

不过,我正在尝试在我的规范文件中解决所有这些问题,但我遇到了一个问题,即刷新令牌似乎没有被撤销,即使它被多次使用,或者它( “刷新令牌A”)在之后被重用,刷新令牌(“令牌B”)与刷新令牌A用于生成的访问令牌一起返回,也被使用。我的规范文件会更清楚地说明这一点:

describe 'OAuth flow' do
  # ...
  describe 'refresh tokens' do

    # ...
    context 'when attempting reuse of a refresh token' do
      before do
        redirect_uri = 'https://localhost:3002'

        # ivars necessary brecause plaintext tokens/secrets are only available upon creation of the object
        @client = Doorkeeper::Application.create(name: 'foo', uid: 'bar', redirect_uri: redirect_uri, scopes: 'project_index')
        @secret = @client.plaintext_secret
        @grant = Doorkeeper::AccessGrant.create(resource_owner_id: user.id, organization_id: org.id, application_id: @client.id, scopes: 'project_index', expires_in: 600, redirect_uri: redirect_uri)
        @code = @grant.plaintext_token
      end

      it 'revokes the initial refresh token' do
        # Get an initial access token and refresh token
        post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=authorization_code&redirect_uri=#{@client.redirect_uri}&scope=project_index"
        expect(response.status).to eq(200)

        # Use refresh token to get a new access token
        previous_refresh_token = JSON.parse(response.body)['refresh_token']

        post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{previous_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
        expect(response.status).to eq(200)
        json_body = JSON.parse(response.body)
        new_access_token = json_body['access_token']
        new_refresh_token = json_body['refresh_token']

        # Use the new access token successfully
        get "/api/v1/projects?access_token=#{new_access_token}"
        expect(response.status).to eq(200)

        # Use the new refresh token to get yet another access token
        post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{new_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
        expect(response.status).to eq(200)

        # Attempt reuse of the first refresh token
        post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{previous_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
        expect(response.status).to eq(400)

        # ^^^ fails, response is 200 and a new access token and refresh token are generated
      end
    end
  end

  # ...
end

此规范在最后一个断言上失败,表明对于给定的刷新令牌,当它用于生成的访问令牌被成功使用时(与上述相反),或者当刷新令牌发出时,它不会被撤销使用刷新的访问令牌。

我的问题是,对于 Doorkeeper,在什么情况下会撤销刷新令牌?

【问题讨论】:

    标签: ruby-on-rails ruby doorkeeper


    【解决方案1】:

    doorkepeer 实现了一些流程,其中发行的令牌应该被撤销。 (我怀疑我描述了所有这些,我只记得那些)

    • 自愿发送request 以撤销给定令牌。
    • 通过完成refresh token flow,这将撤销刷新的令牌。 (除非启用了第三个流程)
    • 通过成功completing an authentication 同时启用刷新令牌流并在oauth_access_tokens 表上设置previous_refresh_token 列。此列在刷新令牌流期间由门卫自动填充,当前令牌正在刷新(比前一个令牌)。 (必须在门卫配置上启用此流程)
    • Revoking a grant token,用作其他流的预授权。授权令牌一旦用于获取另一个令牌(例如客户端或访问令牌)就会被撤销
    • 在客户端凭据流中,通过请求禁用重用访问令牌配置的新令牌

    基于我要说的所有内容,您的假设是完全正确的。您编写的规范应该已经撤销了令牌,这让我想到这是否不是门卫的错误。如果没有看到您的门卫配置,我几乎会猜测,但是,我从版本 5.3.0 中发现了这个拉取请求 #1341,该请求旨在修复启用 hash_token_secrets 时撤销刷新令牌的错误。如果您启用了hash_token_secrets,请尝试禁用它或更新门卫。如果这些都不可行,请尝试制作一个猴子补丁(作为最后的资源),看看是否能解决您的问题。

    【讨论】:

    • 感谢您的回答。抱歉,我让赏金到期,然后才能将其奖励给您。我今天会尝试并报告。
    • 更新:这看起来很有希望,因为我确实启用了hash_token_secrets。我将他们的 gem 升级到 5.3.1,但我仍然看到这个问题。我在 gem repo 上提交的问题中添加了一个评论,所以我们会看到。我会继续挖掘。
    • 很遗憾听到它不适合您。如果您找到解决方案或了解问题出在哪里,请给我打电话,我真的很想知道发生了什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2018-08-05
    • 2012-02-15
    • 2019-04-07
    • 2012-07-19
    • 1970-01-01
    • 2021-08-25
    相关资源
    最近更新 更多