门卫刷新令牌在重新使用时不会过期

时间:2019-10-07 14:40:02

标签: ruby-on-rails ruby doorkeeper

我正在使用Doorkeeper 5.2.1,Ive咨询了Doorkeeper docs on refresh tokens,并通读了GitHub的一些问题,并提出了与刷新令牌相关的请求,特别是herehere。 >

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

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

不过,我对基于this pull request的情况感到困惑,因为它在“使用该刷新令牌创建的访问令牌成功使用一次之后,实现了刷新令牌到期”。门卫如何知道我是否已成功使用该访问令牌发出了API请求?这是我的API,可以根据该访问令牌计算出授权逻辑。 Doorkeeper与我的API请求成功与否无关。但是,我认为这意味着如果resource_owner_authenticator块返回了一个用户,则可以构成成功的使用。但是我还没有发现刷新令牌成功失效。 (请参阅下面的规格。)

从阅读this spec file可以看出,如果您成功使用了刷新令牌,它将撤销以前的刷新令牌,这很有意义。

不过,我正在尝试在我的规格文件中解决所有这些问题,并且遇到了一个问题,即即使多次使用刷新令牌,也似乎没有撤销该令牌,或者(还使用了刷新令牌(“令牌B”),该刷新令牌(“令牌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

该规范在最后一个断言时失败,这表明对于给定的刷新令牌,如果成功使用了用于生成的访问令牌(与上面所述相反),或者当使用使用刷新的访问令牌。

我的问题是,在使用门卫的情况下,刷新令牌在什么情况下被吊销?

1 个答案:

答案 0 :(得分:1)

门童实施了一些流程,在这些流程中,应该撤消已发行的令牌。 (我怀疑我描述了所有这些,我只记得那些)

  • 通过自愿request撤销给定令牌。
  • 通过完成refresh token flow,这将撤消刷新的令牌。 (除非启用了第三个流程)
  • 成功启用completing an authentication,同时启用刷新令牌流,并在previous_refresh_token表上启用列oauth_access_tokens。在刷新令牌流期间,门卫将自动更新当前令牌(比以前的令牌要多)来自动填充此列。 (必须在门卫配置上启用此流程)
  • Revoking a grant token,用作其他流的预身份验证。授权令牌用于获取另一个令牌(例如客户端或访问令牌)后,便会立即被撤销
  • 在客户端凭据流上,通过在禁用重用访问令牌配置的情况下请求新令牌

基于所有我要说的,您假设完全正确。您编写的规范应该撤消了令牌,这使我开始思考这是否不是门卫上的错误。我没有看到您的看门人配置,但是,我发现来自版本#1341的拉取请求5.3.0旨在解决{{1 }}已启用。如果您启用了hash_token_secrets,请尝试将其禁用或更新门卫。如果这些都不可行,请尝试制作一个猴子补丁(作为最后的资源),看看是否能解决您的问题。