OAUTH2.0 不记名令牌不工作

Posted

技术标签:

【中文标题】OAUTH2.0 不记名令牌不工作【英文标题】:OAUTH2.0 Bearer token not working 【发布时间】:2017-03-11 17:40:57 【问题描述】:

我正在使用 Retrofit 2.0 在 android 上构建一个 Bitbucket REST 客户端。

就我而言,OAUTH2.0 提供“隐式授权”,当用户在提示时登录到他们的帐户时,它会立即为客户端提供访问承载令牌。

不记名令牌是可用于访问受保护资源的令牌。任何拥有不记名令牌的人都有权访问受保护的资源,就像其他拥有不记名令牌的人一样。 (根据来自 IETF 的this doc)

如果我错了,请纠正我,但我认为使用隐式授权,在用户登录他们的 Bitbucket 帐户后,我将拥有 Bearer 访问令牌。之后,我可以使用此访问令牌访问 Bitbucket 上的受保护资源(例如创建一个新存储库)。

所以我使用 OAUTH2.0 隐式授权构建了我的 android,如 Bitbucket doc 中所述。请注意,他们描述的响应将有#access_token=token&token_type=bearer

这是我在登录后实际从 Bitbucket 收到的内容:

your://redirecturi#access_token=lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw%3D&scopes=pipeline%3Awrite+webhook+snippet%3Awrite+wiki+issue%3Awrite+pullrequest%3Awrite+repository%3Adelete+repository%3Aadmin+project%3Awrite+team%3Awrite+account&expires_in=3600&token_type=bearer

我的第一个问题: 上述响应中的 Bearer 访问令牌究竟是什么?

lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw 部分是 Bearer 访问令牌吗?我是否必须包含“%3D”(这是用 ASCII 编码的字符“=”)? Bitbucket 文档不是意味着除了最后一个“&token_type=bear”之外的所有东西都是熊访问令牌吗?

这还不是全部。 Bitbucket 文档的请求说明如下:

在请求头中发送它:授权:Bearer access_token

所以我根据API of Bitbucket设置这个请求创建一个新的仓库:

@POST("repositories/username/repo_slug")
    Call<Repository> createRepository(
            @Header("Authorization") String auth,
            @Path("username") String userName,
            @Path("repo_slug") String repoSlug);

但每次,我都会收到状态码 401 和消息错误的响应:

访问令牌已过期。使用您的刷新令牌获取新的访问令牌。

当我尝试通过 Restlet(类似 Postman 的 chrome 扩展)使用 DHC 发布相同的请求时,会出现一个弹出窗口并要求我登录到 Bitbucket。如果我拒绝这样做,我会收到相同的错误 401 响应。如果我确实登录,那么它可以工作。

我的第二个问题:为什么我必须再次提供我的凭据?

我认为这里有问题。我认为使用 Bearer 访问令牌,我应该能够访问受保护的资源,而无需在访问令牌的过期时间到达之前登录。为什么我必须第二次输入我的凭据?这不是 IETF 的“隐式授权”方法here 中描述的内容。

【问题讨论】:

【参考方案1】:

access_token 的值在access_token= 之后开始,在下一个参数scopes 之前结束,所以在&amp;scopes= 之前。片段部分的格式在https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2 中指定,而https://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13.4.1 又指向https://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13.4.1,它表示:

[...] 名称与值由 = 和名称/值对分隔 由&amp; [...]

因此,您的访问令牌值按规范为 lEuvneW39onVrnNR-jvZfirI43fwi5Wdc0YaaMROBk5YKJsd2ulXm20vJDdOBjf8I-Ne2r2vC8-_FHECSLw%3D,但我同意结尾 %3D 是可疑的,并且可能是发件人的错误。

如果您的访问令牌已过期(看起来就是这样),您需要再次使用隐式授权或使用刷新令牌授权来获取一个新的。

【讨论】:

发件人可能正在使用 Base64 编码,手动替换 +/ 字符,然后忘记修剪填充。最终结果:Base64AlmostURL 编码。

以上是关于OAUTH2.0 不记名令牌不工作的主要内容,如果未能解决你的问题,请参考以下文章

如何在客户端持久保存不记名令牌

如何使用 Oauth2.0 解码不透明的访问令牌

OAuth2.0

Node.js 互联网打印协议 (IPP) API Oauth2 授权

Oauth2.0协议简介

OAuth 2.0 访问令牌已过期,刷新令牌不可用