简体   繁体   English

IBM Watson API Java SDK使用Watson令牌身份验证失败

[英]IBM Watson APIs Java SDK use Watson token authentication fail

I use Watson APIs Java SDK and my Authentication was use function setUsernameAndPassword(username, password), but now I want to use Tokens for authentication . 我使用Watson API Java SDK ,我的身份验证使用函数setUsernameAndPassword(用户名,密码),但现在我想使用令牌进行身份验证

my "Username and Password" Code 我的“用户名和密码”代码

mAssistant = new Assistant("2018-02-16");
mAssistant.setUsernameAndPassword(mUserName, mPassword);
InputData input = new InputData.Builder("Hello").build();
MessageOptions options = new MessageOptions.Builder("{workspaceId}")
                                           .input(input)
                                           .build();
MessageResponse response = mAssistant.message(options).execute();
System.out.println(response);

it work fine. 它工作正常。

I ues this method to get my token. 我使用这种方法获取我的令牌。 curl -X GET --user "{username}:{password}" "https://gateway.watsonplatform.net/authorization/api/v1/token?url=https://gateway.watsonplatform.net/conversation/api"

Tokens for authentication 用于身份验证的令牌
Method-1 方法1

mAssistant = new Assistant("2018-02-16");
Map<String, String> map = new HashMap<>();
map.put("X-Watson-Authorization-Token", "{token_string}");
mAssistant.setDefaultHeaders(map);
mAssistant.setSkipAuthentication(true);
InputData input = new InputData.Builder("Hello").build();
MessageOptions options = new MessageOptions.Builder("{workspaceId}")
                                           .input(input)
                                           .build();
MessageResponse response = mAssistant.message(options).execute();
System.out.println(response);

get the error code 得到错误代码

E/WatsonService: POST status: 403, error: Forbidden
com.ibm.watson.developer_cloud.service.exception.ForbiddenException: Forbidden
05-07 16:05:57.720 10392-10476/mvi.rcu W/System.err:     at com.ibm.watson.developer_cloud.service.WatsonService.processServiceCall(WatsonService.java:401)
05-07 16:05:57.720 10392-10476/mvi.rcu W/System.err:     at com.ibm.watson.developer_cloud.service.WatsonService$WatsonServiceCall.execute(WatsonService.java:459)

Method-2 方法2

mAssistant = new Assistant("2018-02-16");
IamOptions options = new IamOptions.Builder()
                                   .accessToken(token)
                                   .build();
mAssistant.setIamCredentials(options);
mAssistant.setEndPoint("https://gateway.watsonplatform.net/conversation/api");
// do same ... 
// mAssistant.message(options).execute();
// ...

get error message 得到错误消息

W/System.err: com.ibm.watson.developer_cloud.service.exception.UnauthorizedException: Unauthorized: Access is denied due to invalid credentials. Tip: Did you set the Endpoint?
W/System.err:     at com.ibm.watson.developer_cloud.service.WatsonService.processServiceCall(WatsonService.java:398)
W/System.err:     at com.ibm.watson.developer_cloud.service.WatsonService$WatsonServiceCall.execute(WatsonService.java:459)

If I want to use Tokens for authentication by Watson APIs Java SDK , what should I do? 如果我想通过Watson API Java SDK使用令牌进行身份验证,我该怎么办?

EDIT: The below answer works with the token you got before. 编辑:以下答案适用于您之前获得的令牌。 However, I just noticed that you called the token API using the https://gateway.watsonplatform.net/conversation/api URL. 但是,我刚刚注意到您使用https://gateway.watsonplatform.net/conversation/api URL调用了令牌API。 If you instead get a token with https://gateway.watsonplatform.net/assistant/api , your posted code should work fine. 如果您使用https://gateway.watsonplatform.net/assistant/api获取令牌,则您发布的代码应该可以正常工作。


Due to the Conversation -> Assistant rename, there seems to be an issue with authorization using the new name. 由于对话 - >助手重命名,使用新名称的授权似乎存在问题。 Therefore, once you get your authorization token, you can use the setEndPoint() method to call the Conversation endpoint, like so: 因此,一旦获得授权令牌,就可以使用setEndPoint()方法调用Conversation端点,如下所示:

mAssistant = new Assistant("2018-02-16");
Map<String, String> map = new HashMap<>();
map.put("X-Watson-Authorization-Token", "{token_string}");
mAssistant.setDefaultHeaders(map);
mAssistant.setSkipAuthentication(true);

// change here
mAssistant.setEndPoint("https://gateway.watsonplatform.net/conversation/api");

Assistant is just an alias for Conversation internally so your API calls should work the same. 助手只是内部对话的别名,因此您的API调用应该相同。

Alternatively, you could just use the Conversation service directly, although at some point that will go away in favor of just the Assistant service. 或者,你可以直接使用Conversation服务,虽然在某些时候它会消失,只支持Assistant服务。

There is actually an example in the README of the Java SDK : There is a method setIamCredentials() to configure how the Watson service, including Watson Assistant, handles the token-based access. Java SDK的自述文件中有一个示例 :有一个方法setIamCredentials()来配置Watson服务(包括Watson Assistant setIamCredentials()如何处理基于令牌的访问。 It can manage token refresh for you if you provide the API key, or you pass in the token itself and need to take care of refreshs. 如果您提供API密钥,它可以为您管理令牌刷新,或者您自己传递令牌并需要处理刷新。

Not tested, but similar to the example for the Discovery service and adapted for you code: 未经测试,但类似于Discovery服务的示例并且适合您的代码:

mAssistant = new Assistant("2018-02-16");
IamOptions options = new IamOptions.Builder()
  .apiKey("<iam_api_key>")
  .build();
mAssistant.setIamCredentials(options);

Note that this is using the strategic IBM Cloud IAM (Identity and Access Management) , not the Watson service token. 请注意,这是使用战略IBM Cloud IAM(身份和访问管理) ,而不是Watson服务令牌。 That feature was recently added to the Watson services and I would recommend using it. 该功能最近被添加到Watson服务中,我建议使用它。 You can manage the API key using the UI or by bx iam commands. 您可以使用UI或bx iam命令管理API密钥。

The below code work fine for me, but I have the question, which method is better ? 下面的代码对我来说很好,但我有问题,哪种方法更好?

Method-1 方法1

Get token by url https://gateway.watsonplatform.net/assistant/api 通过网址https://gateway.watsonplatform.net/assistant/api获取令牌

curl -X GET --user {username}:{password} "https://gateway.watsonplatform.net/authorization/api/v1/token?url=https://gateway.watsonplatform.net/assistant/api"

Use token 使用令牌

mAssistant = new Assistant("2018-02-16");
Map<String, String> map = new HashMap<>();
map.put("X-Watson-Authorization-Token", "{token_string}");
mAssistant.setDefaultHeaders(map);
mAssistant.setSkipAuthentication(true);

Method-2 方法2

Get token by url https://gateway.watsonplatform.net/conversation/api 通过网址https://gateway.watsonplatform.net/conversation/api获取令牌

curl -X GET --user {username}:{password} "https://gateway.watsonplatform.net/authorization/api/v1/token?url=https://gateway.watsonplatform.net/conversation/api"

Use token 使用令牌

mAssistant = new Assistant("2018-02-16");
Map<String, String> map = new HashMap<>();
map.put("X-Watson-Authorization-Token", "{token_string}");
mAssistant.setDefaultHeaders(map);
mAssistant.setSkipAuthentication(true);
mAssistant.setEndPoint("https://gateway.watsonplatform.net/conversation/api");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM