首页 > 解决方案 > 为什么我在执行 Exact OAuth 时得到 OAuthProblemException error='invalid_request' description='Handle could not be extract'

问题描述

在调用 Exact-on-line API 进行身份验证时,我们遇到了获取第一个刷新令牌失败的问题。我们不确定为什么。这是我们从 Exact 得到的:

{
    error='invalid_request',
    description='Handle could not be extracted',
    uri='null',
    state='null',
    scope='null',
    redirectUri='null',
    responseStatus=400,
    parameters={}
}

我们使用这个基于库 org.apache.oltu.oauth2.client (1.0.2) 的 Java 代码:

OAuthClientRequest oAuthRequest = OAuthClientRequest //
        .tokenLocation(BASE_URL + "/api/oauth2/token") //
        .setGrantType(GrantType.AUTHORIZATION_CODE) //
        .setClientId(clientId) //
        .setClientSecret(clientSecret) //
        .setRedirectURI(REDIRECT_URI) //
        .setCode(code) //
        .buildBodyMessage();

OAuthClient client = new OAuthClient(new URLConnectionClient());

OAuthJSONAccessTokenResponse oauthResponse = client.accessToken(oAuthRequest, OAuth.HttpMethod.POST);

我们确实使用https://support.exactonline.com/community/s/knowledge-base#All-中显示的 localhost-redirect 完成了第一步(获取 setCode(...) 中使用的“代码”)All-DNO-Content-gettingstarted我们从浏览器的地址栏中复制代码并将其存储在下一个计算机步骤可以再次读取的位置。

标签: javaoauth-2.0exact-online

解决方案


这是因为代码是从您的浏览器地址栏中复制的。在那里,您会发现代码的 URL 编码版本(通常在 '%21' 中可见),当逐字传递到 setCode 时,后续调用将失败。

建议:对值进行 URL 解码或使用 Undertow 等设置一个小型临时localhost-HTTP-server 以捕获发送给您 localhost-URL 的代码:

Undertow server = Undertow.builder() //
        .addHttpListener(7891, "localhost") //
        .setHandler(new HttpHandler() {
            @Override
            public void handleRequest(final HttpServerExchange exchange) throws Exception {
                String code = exchange.getQueryParameters().get("code").getFirst();
                LOG.info("Recieved code: {}.", code);
                LOG.info("Store code");
                storeCode(code);
                LOG.info("Code stored");

                exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                exchange.getResponseSender().send( //
                        "Thanks for getting me the code: " + code + "\n" //
                                + "Will store it for you and get the first refreshToken..." //
                                + "Please have a look at " + OAUTH_STATE_INI
                                + " for the new code & refreshToken in a minute" //
                );

                done.add("done");
            }
        }).build();
server.start();

注意:请确保您的 Exact-app-settings 中的重定向 URL 正确无误


推荐阅读