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

时间:2015-06-28 09:29:12

标签: java oauth-2.0 bitbucket-api oltu

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

但是,我对OAuth的了解非常有限,所以我很早就陷入困境。这是我到目前为止所做的:

第1步:我使用我的Bitbucket帐户注册了OAuth Consumer,其中包含以下详细信息:

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:接下来的步骤是什么,我的做法有什么问题?

2 个答案:

答案 0 :(得分:6)

答案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 stackoverflow question上的评论。)相反,您应该使用Resource Owner Password Credentials Grant类型,这样您就可以直接在应用程序中验证Bitbucket的用户名和密码,而无需外部浏览器或回调URL。 Bitbucket提供了关于如何使用该授权类型here的示例curl命令。

答案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());

答案 1 :(得分:4)

您的主要问题是您提供的是客户名称而不是客户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