【问题标题】:Dropbox Java API with GWT Authentication problems带有 GWT 身份验证问题的 Dropbox Java API
【发布时间】:2013-07-25 19:11:03
【问题描述】:

我使用的是 Dropbox API for Java 1.6 版,可在此处找到:https://www.dropbox.com/developers/core/sdks/java

我也在 E​​clipse 3.7 中使用 GWT 2.5.1

我有以下代码在作为 Java 应用程序运行时可以工作:

    DbxRequestConfig requestConfig = new DbxRequestConfig(type, locale);
    DbxAppInfo appInfo = new DbxAppInfo(APP_ID, APP_SECRET);
    DbxWebAuthNoRedirect webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
    String result = webauth.start();
    System.out.println(result);
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String code = reader.readLine();

    webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
    DbxAuthFinish finish = webauth.finish(code);

    DbxClient client = new DbxClient(requestConfig, finish.accessToken);
    DbxAccountInfo info = client.getAccountInfo();
    long total = info.quota.total;
    long used = info.quota.normal;

    System.out.println("total: " + total);
    System.out.println("used: " + used);

当我将它作为 Java 应用程序运行时,它可以正常工作。但是,当我尝试在 RemoteServiceServlet 中使用 GWT 做类似的事情时。当我尝试做时遇到异常

webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);

我得到的异常如下:

Caused by: java.lang.ClassCastException: com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection cannot be cast to javax.net.ssl.HttpsURLConnection
at com.dropbox.core.http.StandardHttpRequestor.prepRequest(StandardHttpRequestor.java:160)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:87)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:21)
at com.dropbox.core.DbxRequestUtil.startPostNoAuth(DbxRequestUtil.java:156)
at com.dropbox.core.DbxRequestUtil.doPostNoAuth(DbxRequestUtil.java:289)
at com.dropbox.core.DbxWebAuthHelper.finish(DbxWebAuthHelper.java:40)
at com.dropbox.core.DbxWebAuthNoRedirect.finish(DbxWebAuthNoRedirect.java:84)
at com.cloudshare.server.DropboxPlayground.getFinish(DropboxPlayground.java:21)
at com.cloudshare.server.DropboxServiceImpl.authenticate(DropboxServiceImpl.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
... 40 more

在过去的几个小时里,我一直在用头撞墙,试图弄清楚发生了什么。我最初想使用 DbxWebAuth,但他们的 API 中的文档包含的指令包含不存在的类(我假设他们曾经这样做过)。

我觉得 DbxWebAuthNoRedirect 正在做一些事情,它根据可用的类动态加载连接。但我一直无法弄清楚。

提前感谢您的帮助!

编辑:

好的,所以我查看了 Dropbox API 源,错误发生在这里:

    URL urlObject = new URL(url);
    HttpsURLConnection conn = (HttpsURLConnection) urlObject.openConnection(this.proxy);

因为我使用的是 Google App Engine,所以它使用的是自己的 URL 对象,而不是 App Engine API 导入的对象。关于不涉及为 Dropbox API 编写 GWT 包装器的解决方案的任何想法。

【问题讨论】:

  • 你在为谷歌应用引擎开发吗?如果是这样,则 dropbox api 使用的错误消息 HttpsURLConnection 中提到的类与应用程序引擎的工作方式不兼容。如果您不是为应用引擎开发,则需要禁用应用引擎。
  • 我正在使用 GAE。关于变通的任何想法?
  • 在您的编辑中。 GAE 在内部根据传递的 url 创建一个连接器。但是,由于 dropbox api 是一个 https url,因此 dropbox api 期望返回一个安全连接类,它会将其转换为该类。然而 GAE 只支持http 并且会返回一个不安全的 http 连接器,它不能被转换为安全连接类。由于 dropbox api 的源代码在 github 上,您可以尝试将代码更改为不安全的对象,但我不知道这是否可行。 (作为旁注,这不是 GWT 问题,而是 GAE 问题)

标签: java gwt dropbox dropbox-api


【解决方案1】:

最新的 Dropbox SDK 允许您选择 HttpRequestor 实现

new DbxRequestConfig(APP_NAME, userLocale, HttpRequestor);

所以您需要做的就是调整 com.dropbox.core.http.StandardHttpRequestor 使其对 Appengine 友好

要点:AppengineHttpRequestor.java

【讨论】:

    【解决方案2】:

    您是否使用安全的https:// 网址进行连接?我的猜测是,如果您使用 http://,您将获得无法转换为安全连接的不安全连接器。

    --编辑--

    看起来 HttpsURLConnection 类在 GAE 上根本不支持,因此它不会像 GAE 文档所说的那样工作。 Using HttpsURLConnection (doc issue)。这意味着您可能无法直接使用它。

    【讨论】:

    • 不幸的是,当我使用他们的 API 时,我没有选择请求类型。我只是在DbxWebAuthNoRedirect 的实例上调用finish 方法,它可能使用http 而不是https。但是,我对此表示怀疑,因为它会生成一个 https 站点来访问以进行身份​​验证。也许 GWT 正在生成一个 http 请求而不是 https?这将是令人惊讶的,因为我在使用 GWT 实现 Google Drive API 时没有遇到任何问题。
    • 看起来 Dropbox 源正在使用在 GAE 上更改的 Java 的 URL 类。我想我可以修改 Dropbox 源来解决这个问题,但我不确定。有什么想法吗?
    • 从 Dropbox SDK for Java 版本 2.0.5 开始,您可以使用 GoogleAppEngineHttpRequestor,它明确支持 App Engine 的 URL Fetch API。
    【解决方案3】:
    DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("107.108.85.10", 80));
    
    StandardHttpRequestor requ = new StandardHttpRequestor(proxy);
    DbxRequestConfig config = new DbxRequestConfig("JavaTutorial/1.0",
    Locale.getDefault().toString(),requ);
    DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(config, appInfo);
    

    因此,通过在 StandardHttpRequestor 中使用 Proxy(我的防火墙)并在 DbxRequestConfig 中使用此请求者,它对我有用。

    【讨论】:

      【解决方案4】:

      我也遇到了同样的问题。根据这篇文章,https://groups.google.com/forum/#!topic/google-appengine-java/V8pREOXPX24

      com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler 
      $Connection extends the class java.net.HttpURLConnection
      

      因此我替换了班级

      javax.net.ssl.HttpsURLConnection
      

      通过

      java.net.HttpURLConnection 
      

      在 com.dropbox.core.http.StandardHttpRequestor 类中并重建 Dropbox Java SDK。它工作正常。一个示例工作应用程序可以在https://gwt-gae-testing.appspot.com/

      【讨论】:

        【解决方案5】:

        这是检索 access_token 的唯一方法(但我不知道如何处理 Dropbox API 的其他方法)。

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
        
            String code = req.getParameter("code");
        
            URL fetchurl = new URL(url);
            HTTPRequest request = new HTTPRequest(fetchurl, HTTPMethod.POST);
            String body = "code=" + code + "&grant_type=authorization_code" + "&client_id=" + dropboKey + "&client_secret=" + dropboxSecret + "&redirect_uri=" + redirectUri;
            request.setPayload(body.getBytes("UTF-8"));
        
            HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request);
        
            String respInJson = new String(response.getContent());
        
            LOGGER.warning(respInJson);
        
            JSONObject jsonObj;
            try {
                jsonObj = new JSONObject(respInJson);
                String uid=jsonObj.getString("uid");
                String access_token=jsonObj.getString("access_token");
        
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
        

        我建议像@radu-c 所说的那样更改 HttpRequestor。它工作正常。

        【讨论】:

          猜你喜欢
          • 2018-06-29
          • 2021-02-09
          • 2019-12-05
          • 1970-01-01
          • 2017-07-14
          • 2019-08-24
          • 2011-01-18
          • 2015-03-28
          • 2019-10-10
          相关资源
          最近更新 更多