oauth-2.0 - Ballerina Oauth2 经过身份验证的端点返回 406
问题描述
我正在尝试调用使用 Oauth2 密码凭据来获取身份验证令牌的第 3 方服务。Ballerina 正在返回以下消息。
2020-04-23 15:07:35,414 ERROR [ballerina/oauth2] - Received an invalid response with status-code: 406; and payload: {"fault":{"faultstring":"Raising fault. Fault name : RF.Raise-406-Exception","detail":{"errorcode":"steps.raisefault.RaiseFault"}}}
2020-04-23 15:07:35,418 ERROR [ballerina/oauth2] - Failed to generate OAuth2 token. : error {ballerina/oauth2}Error message=Received an invalid response with status-code: 406; and payload: {"fault":{"faultstring":"Raising fault. Fault name : RF.Raise-406-Exception","detail":{"errorcode":"steps.raisefault.RaiseFault"}}}
error {ballerina/http}AuthenticationFailed message=Failed to prepare request at bearer auth handler. cause=error {ballerina/auth}Error message=Failed to generate OAuth2 token. cause=error {ballerina/oauth2}Error message=Received an invalid response with status-code: 406; and payload: {"fault":{"faultstring":"Raising fault. Fault name : RF.Raise-406-Exception","detail":{"errorcode":"steps.raisefault.RaiseFault"}}}
让我感到困惑的是 406 代码,因为我将内容类型和接受标头都设置为“应用程序/json”,这是服务所需要的。但是,第二条消息显示“无法生成 OAuth2 令牌”,那么它可能是获取返回 406 的 oauth 令牌的调用吗?如果是这样,我如何在令牌服务调用中设置接受标头?
使用 Ballerina,我调用了令牌端点并成功获得了令牌,但是如果我尝试使用 PasswordGrantConfig 调用服务,这些就是我得到的错误。我已经尝试了我能想到的一切,并成功地使用 ClientCredentialsGrantConfig 让其他服务正常工作。感激地收到任何帮助。
相关代码如下。下面的三个部分是 3 个不同的 .bal 文件中的代码部分。
// configure the Oauth2 Config
import ballerina/config;
import ballerina/http;
import ballerina/oauth2;
public function getOauth2Handler() returns http:BearerAuthHandler {
oauth2:PasswordGrantConfig passwordGrantConfig = {
tokenUrl: config:getAsString("experian.authentication.tokenUrl"),
username: config:getAsString("experian.authentication.username"),
password: config:getAsString("experian.authentication.password"),
clientId: config:getAsString("experian.authentication.clientId"),
clientSecret: config:getAsString("experian.authentication.clientSecret"),
credentialBearer: http:AUTH_HEADER_BEARER
};
oauth2:OutboundOAuth2Provider oauth2Provider = new (passwordGrantConfig);
return new (oauth2Provider);
}
// Configure the API Client
http:ClientConfiguration delphiSelectClientConfig = {
auth: {
authHandler: experian:getOauth2Handler()
}
};
experian:DelphiSelectClientConfig delphiSelectConfig = {
serviceUrl: config:getAsString("experian.services.delphi-select.serviceUrl"),
clientConfig: delphiSelectClientConfig
};
experian:DelphiSelectClient delphiSelectClient = new (delphiSelectConfig);
// Call the endpoint using the Oath2 configuration
import ballerina/http;
import ballerina/io;
public type DelphiSelectClientConfig record {
string serviceUrl;
http:ClientConfiguration clientConfig;
};
//==============================
//============Client============
//==============================
public type DelphiSelectClient client object {
public http:Client clientEp;
public http:ClientConfiguration config;
public function __init(DelphiSelectClientConfig config) {
http:Client httpEp = new (config.serviceUrl, {auth: config.clientConfig.auth});
self.clientEp = httpEp;
self.config = config.clientConfig;
}
public remote function newApplication() returns @untainted json|error {
io:println("In newApplication function");
http:Request request = new;
json requestBody = newApplicationBody; // get test data from json in another file
request.setJsonPayload(requestBody);
var response = check self.clientEp->post("/application", request);
var payload = check response.getJsonPayload();
return payload;
}
};
我还修改了我的测试代码以调用令牌 EP 并故意设置accept
为不可接受的值,例如"text/csv"
. 在这种情况下,我得到相同的错误响应。但是设置accept
为"*/*"
确实有效。最后一个考试; accept
of ""
(empty) 也失败了,所以我怀疑 BearerAuthHandler 没有为accept
.
那么我可以强制 BearerAuthHandler 设置一个accept
of"application/json"
吗?
解决方案
对象的主要目的http:OutboundAuthHandler
是准备http:Request
需要通过您调用的外部端点进行身份验证的身份验证信息。
http:BearerAuthHandler
负责添加Authorization
值为 的标头Bearer <token>
。“令牌”是使用提供的信息准备的。因此,没有选项可以强制http:BearerAuthHandler
为请求设置任何标头。
但是在这种情况下,如果 API 成功响应,如果有值为Accept
的标头application/json
,您可以简单地将该标头添加到http:Request
调用 POST 请求之前,如下所示:
request.addHeader("Accept", "application/json");
推荐阅读
- typescript - 为什么这个Schema为空.....如何在nestjs中设置@ApiProperty
- r - 如何解决R语言使用write.xlsx()将数据写入excel文档的字符变化问题?
- sqlalchemy - 从 psycopg 连接创建 sqlalchemy 引擎
- javascript - React default className ...在三元运算符开始之前
- android - 深色主题更改时不调用 onConfigurationChanged()
- pandas - 如何从分类数据中绘制带有 y 轴值的水平条
- reactjs - 是否可以将参数从反应 Route 标签传递到 Navigate 标签?
- python - 如何在此处提取图像的链接?
- angularjs - 从 AngualrJs 应用迁移到 Vue3 应用
- google-apps-script - Google Apps 脚本 - 我可以修改嵌入图表的一个选项并保留其他选项吗?