Балерина Oauth2 аутентифицировала конечную точку, возвращающую 406 - PullRequest
1 голос
/ 23 апреля 2020

Я пытаюсь вызвать стороннюю службу, которая использует Oauth2 Password Credentials для получения токена аутентификации. Балерина возвращает следующие сообщения.

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, так как я установил оба типа контента и принимаю заголовки на «application / json», что и требуется сервису. Однако во втором сообщении говорится «Не удалось сгенерировать токен OAuth2», поэтому может ли это быть вызов для получения токена oauth, который возвращает 406? Если да, то как мне установить заголовок подтверждения при вызове службы токена?

Используя Балерину, я позвонил в конечную точку токена и успешно получил токен, но если я пытаюсь вызвать службу с использованием 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 из "" (пусто) также завершается ошибкой, поэтому я подозреваю, что BearerAuthHandler не устанавливает никакого значения для accept.

Так что я могу заставить BearerAuthHandler установить accept из "application/json" ?

Спасибо. Смотри картинку ниже. Picture showing requirement for content-type to be set to “application/JSON”

Кроме того, пример в приведенной вами присяге c показывает установленное значение типа содержимого. Даже значение “*/*” сработает, но я подозреваю, что Балерина оставит это поле пустым. Я поднял проблему GitHub Необходимо иметь возможность установить значения заголовка http для OutboundOAuth2Provider

1 Ответ

0 голосов
/ 24 апреля 2020

Основная цель http:OutboundAuthHandler объектов состоит в том, чтобы подготовить http:Request с информацией аутентификации, которая должна аутентифицироваться с внешней конечной точкой, к которой вы звоните.

http:BearerAuthHandler отвечает за добавление Authorization заголовок со значением Bearer <token>. «токен» подготовлен с предоставленной информацией. Таким образом, нет никакой возможности заставить http:BearerAuthHandler устанавливать любой заголовок для запроса.

Но в этом случае, если API успешно ответит, если есть заголовок Accept со значением application/json, Вы можете просто добавить этот заголовок в http:Request перед вызовом запроса POST следующим образом:

request.addHeader("Accept", "application/json");

...