如何通过 Jersey+Oltu 从 Java 桌面应用程序访问 Bitbucket API?

Posted

技术标签:

【中文标题】如何通过 Jersey+Oltu 从 Java 桌面应用程序访问 Bitbucket API?【英文标题】:How to access Bitbucket API from a Java Desktop App via Jersey+Oltu? 【发布时间】:2015-09-14 21:04:57 【问题描述】:

正如标题所述,我想从本机 Java 桌面应用程序访问 bitbucket API。 Bitbucket 要求应用程序使用 OAuth2,为此我发现 Oltu 应该可以完成这项工作。

但是,我对 OAuth 的了解非常有限,因此我还处于很早的阶段。这是我到目前为止所做的:

第 1 步:我使用我的 Bitbucket 帐户注册了一个 OAuth 消费者,并提供了以下详细信息:

Name: jerseytestapp
Description:
CallbackURL: http://localhost:8080/
URL: 

问题 1:我可以自动执行此步骤吗?

第 2 步:我运行了以下 Java 代码:

package jerseytest;

import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;

public class BitbucketJersey 

    public static void main(String[] args) 
    OAuthClientRequest request;
    try 
        request = OAuthClientRequest
                .authorizationLocation("https://bitbucket.org/site/oauth2/authorize")
                .setClientId("jerseytestapp")
                .setRedirectURI("http://localhost:8080")
                .buildQueryMessage();

            System.out.println(request.getLocationUri());

         catch (OAuthSystemException e) 
            e.printStackTrace();
        
    


第 3 步:我收到以下 locationURI 并在 Firefox 中打开

https://bitbucket.org/site/oauth2/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=jerseytestapp

问题 2:我需要使用浏览器还是可以从 java 应用程序中执行此操作?

我在 Firefox 中收到以下回复消息:

Invalid client_id
This integration is misconfigured. Contact the vendor for assistance.

问题 3:接下来正确的步骤是什么?我的方法有什么问题?

【问题讨论】:

【参考方案1】:

答案 1:您可以自动创建 OAuth 使用者,但您可能不想这样做。

Bitbucket 提供documentation on how to create a consumer through their APIs,尽管文档缺少许多相关字段。即便如此,您仍然可以以编程方式制作 HTTP 请求,该请求模仿 Bitbucket 的 Web 界面为创建消费者所做的任何事情。所以是的,它可以自动化。

这就是您可能不想这样做的原因。在您的情况下,您需要协同工作的三件事:您的应用程序、最终用户和 Bitbucket。 (或者就此流程的 OAuth 术语而言,它们分别是 client, resource owner, and authorization server。)通常的处理方式是您的应用程序由您在帐户中创建的 OAuth 使用者唯一标识,并且所有您的应用程序对 Bitbucket 的使用将使用该单个 OAuth 使用者来识别您的应用程序。因此,除非您正在开发一个生成其他 Bitbucket 应用程序的 Bitbucket 应用程序,否则您无需自动创建其他 OAuth 使用者。

答案 2:您可以直接从 Java 应用程序进行授权。

Bitbucket 声明 it supports all four grant flows/types 在 RFC-6749 中定义。您的代码当前正在尝试使用 Authorization Code Grant 类型。使用此授权类型将强制您使用浏览器。但这并不是桌面应用程序这种授权类型的唯一问题。如果没有公共网络服务器指向,您将不得不在回调 URL 中使用 localhost,正如您已经在做的那样。这是一个很大的安全漏洞,因为恶意软件可能会拦截到您的回调 URL 的流量,以获取对最终用户仅授予您的应用程序的令牌的访问权限。 (有关该主题的更多讨论,请参阅 this *** question 上的 cmets。)相反,您应该使用 Resource Owner Password Credentials Grant 类型,这将允许您直接在应用程序中验证 Bitbucket 的用户名和密码,而无需外部浏览器或回调 URL。 Bitbucket 提供了一个示例 curl 命令,说明如何使用该授权类型 here。

答案 3:正确的下一步是按照以下示例对代码进行建模。您的方法的问题在于您尝试使用不适合您需求的授权类型,并且您尝试使用 OAuth 使用者的名称来识别您的应用程序,而不是您的使用者的密钥和秘密。

以下代码示例使用我自己的用户名/密码/密钥/秘密组合成功检索了访问令牌,其值已被替换。使用 JDK 1.8.0_45 和 org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.0 测试代码。

OAuthClientRequest request = OAuthClientRequest
    .tokenLocation("https://bitbucket.org/site/oauth2/access_token")
    .setGrantType(GrantType.PASSWORD)
    .setUsername("someUsernameEnteredByEndUser")
    .setPassword("somePasswordEnteredByEndUser")
    .buildBodyMessage();
String key = "yourConsumerKey";
String secret = "yourConsumerSecret";
byte[] unencodedConsumerAuth = (key + ":" + secret).getBytes(StandardCharsets.UTF_8);
byte[] encodedConsumerAuth = Base64.getEncoder().encode(unencodedConsumerAuth);
request.setHeader("Authorization", "Basic " + new String(encodedConsumerAuth, StandardCharsets.UTF_8));
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthResourceResponse response = oAuthClient.resource(request, OAuth.HttpMethod.POST, OAuthResourceResponse.class);
System.out.println("response body: " + response.getBody());

【讨论】:

感谢您提供如此详细的回答。我还没有尝试过,但我已经猜到了,选择了错误的身份验证类型。赏金归你! 你非常有帮助,我吃了所有的谷歌知道从哪里获取授权标头值,现在我才知道它是 base64 ......'【参考方案2】:

您的主要问题是您提供的是客户名称而不是客户 ID:

.setClientId("jerseytestapp")

我知道的获取客户端 ID 的唯一方法是查询: https://bitbucket.org/api/1.0/users/your_account_name/consumers

但是,即便如此,它仍然无法正常工作,因此我联系了 bitbucket 支持。事实证明,该文档具有误导性。您实际上需要使用客户端密钥。

.setClientId("ydrqABCD123QWER4567") // or whatever your case might be

https://bitbucket.org/site/oauth2/authorize?client_id=client_key&response_type=token

【讨论】:

好吧,我认为作为一个真正的 bitbucket-java APT 无论如何都要进行实现是值得的。你可以建立一个 github 项目并免费提供,只要我有空闲时间我就会加入。

以上是关于如何通过 Jersey+Oltu 从 Java 桌面应用程序访问 Bitbucket API?的主要内容,如果未能解决你的问题,请参考以下文章

Apache Oltu Spring Security OAuth2 和 Google 集成

OLTU 能否提供 JWT 作为访问令牌

如何将 Swagger 与 Maven + Java + Jersey +Tomcat 集成

Apache oltu Oauth2 令牌验证

将使用 jersey 1.x 的 java 代码转换为 jersey 2.x

如何在java REST API中用GZip和Jersey压缩相应