Ошибка Dialogflow Rest API «Авторизация учетной записи службы без OAuth»

Я настраиваю удаленный сервер и хотел бы вызвать API REST Dialogflow и специально определить API намерений.

У меня уже настроен агент со всеми намерениями и сущностями, и я хотел бы получить удаленный доступ к намерениям. Я читал о том, как интегрироваться с API, и наткнулся на «Дополнение: авторизация учетной записи службы без OAuth» в этой статье.

https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Я считаю, что я в значительной степени следовал всем инструкциям. Что я мог делать неправильно или я пропустил?

Вот мой код:

    public class DetectIntentTest {

    private static final String PROJECTID = "myprojectid-****";
    private static final String OAUTH_TOKEN_URI = "https://oauth2.googleapis.com/token";
    private static final String CREDENTIALSFILE = "mycredentialsfile-****-****.json";
    private static final String JWT_BEARER_TOKEN_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
    private static final HttpTransport HTTPTRANSPORT = new NetHttpTransport();

public static HttpRequest buildRequest(boolean withoutOauth, String url, String message) throws Exception {
    ServiceAccountCredentials credentials = fetchCredentials();
    String jwt = createJwt(withoutOauth, credentials);
    if (jwt == null) {
        throw new Exception("Could not create a signed jwt token");
    }

    String token = withoutOauth ? jwt : fetchToken(jwt);
    if (token == null) {
        throw new Exception("Could not to retrieve token");
    }

    return HTTPTRANSPORT.createRequestFactory()
            .buildPostRequest(
                    new GenericUrl(url),
                    new JsonHttpContent(JacksonFactory.getDefaultInstance(), message))
            .setHeaders(new HttpHeaders()
                    .setAuthorization("Bearer " + token)
                    .set("Host", host));
}

public static String buildUrl(String uri, String api, String languageCode, String projectId, String sessionId) {
    return "https://dialogflow.googleapis.com/v2/projects/" + projectId + uri + sessionId + ":" + api;
}

 private static String createJwt(boolean withoutOauth, ServiceAccountCredentials credentials) throws Exception {
    long now = System.currentTimeMillis();
    String clientId = credentials.getClientId();
    String privateKeyId = credentials.getPrivateKeyId();
    String serviceAccount = credentials.getClientEmail();
    String oauthTokenURI = credentials.getTokenServerUri().toString();
    RSAPrivateKey privateKey = (RSAPrivateKey) credentials.getPrivateKey();
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    return withoutOauth
            ? JWT.create()
                    .withKeyId(privateKeyId)
                    .withIssuer(serviceAccount)
                    .withSubject(serviceAccount)
                    .withIssuedAt(new Date(now))
                    .withExpiresAt(new Date(now + 3600 * 1000L))
                    .withAudience("https://dialogflow.googleapis.com/google.cloud.dialogflow.v2.Agents")
                    .sign(algorithm)
            : JWT.create()
                    .withKeyId(privateKeyId)
                    .withIssuer(serviceAccount)
                    .withSubject(serviceAccount)
                    .withIssuedAt(new Date(now))
                    .withExpiresAt(new Date(now + 3600 * 1000L))
                    .withAudience(oauthTokenURI)
                    .withClaim("target_audience", clientId)
                    .sign(algorithm);
}

public static ServiceAccountCredentials fetchCredentials() throws Exception {
    File credentialFile = new File(ClassLoader.getSystemResource(CREDENTIALSFILE).getFile());
    ServiceAccountCredentials credentials = ServiceAccountCredentials
            .fromStream(new FileInputStream(credentialFile));
    credentials.createScoped(
            "https://www.googleapis.com/auth/dialogflow",
            "https://www.googleapis.com/auth/cloud-platform");
    return credentials;
}

public static String fetchToken(String jwt) throws Exception {
    final GenericData tokenRequest = new GenericData().set("grant_type", JWT_BEARER_TOKEN_GRANT_TYPE).set("assertion", jwt);
    final UrlEncodedContent content = new UrlEncodedContent(tokenRequest);
    final HttpRequestFactory requestFactory = HTTPTRANSPORT.createRequestFactory();
    final HttpRequest request = requestFactory
            .buildPostRequest(new GenericUrl(OAUTH_TOKEN_URI), content)
            .setParser(new JsonObjectParser(JacksonFactory.getDefaultInstance()));
    HttpResponse response = request.execute();
    GenericData responseData = response.parseAs(GenericData.class);
    return (String) responseData.get("id_token");
}

public static void main(String[] args) {

    String api = "detectIntent";
    String uri = "/agent/sessions/";
    String languageCode = "en-US";
    String text = "Hi I would like help";
    String sessionId = UUID.randomUUID().toString();
    String host = "https://dialogflow.googleapis.com";
    String url = DetectIntentTest.buildUrl(uri, api, languageCode, PROJECTID, sessionId);
    JSONObject message = new JSONObject("{"
            + "  \"queryInput\": {"
            + "    \"text\": {"
            + "      \"languageCode\": \"" + languageCode + "\","
            + "      \"text\": \"" + text + "\""
            + "    }"
            + "  }"
            + "}");
    try {
        HttpRequest request = DetectIntentTest.buildRequest(true,host, url, message.toString());
        HttpResponse response = request.execute();
        System.out.println(response.getStatusCode());
        System.out.println(response.getStatusMessage());
        GenericData responseData = response.parseAs(GenericData.class);
        System.out.println(responseData.toString());
    } catch (Exception ex) {
        Logger.getLogger(DetectIntentTest.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
}

Переменные:

    {
"bearerToken": "eyJraWQiOiIxYWEyY2MzYTQwZjUwZT********",

"host": "https://dialogflow.googleapis.com",

"text": "Hi I would like help",

"languageCode": "en-US",

"projectId": "myprojectid-****",

"url": "https://dialogflow.googleapis.com/v2/projects/myprojectid-****/agent/sessions/4a02046c-c1a2-4a35-b680-6e779c6d34b8:detectIntent"
    }

Тело:

    {"queryInput": 
     {"text":
       {"text": "Hi I would like help",
        "languageCode": "en-US"
       }
      }
     }

Запрос:

    Request{
    method=POST, 
    url=https://dialogflow.googleapis.com/v2/projects/myprojectid-****/agent/sessions/4a02046c-c1a2-4a35-b680-6e779c6d34b8:detectIntent, 
    tags = {}
    }

Заголовки:

    Authorization: Bearer eyJraWQiOiIxYWEyY2MzYTQwZjUwZT********
    Host: https://dialogflow.googleapis.com
    Content-Type: application/json; charset=utf-8

Выход:

    com.google.api.client.http.HttpResponseException: 401 Unauthorized 
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
880
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я обнаружил проблему: я использовал неправильное имя API для обнаружения намерений в отношении аудитории JWT в этом списке. Правильное имя API — «google.cloud.dialogflow.v2.Sessions».

https://github.com/googleapis/googleapis/blob/master/google/cloud/dialogflow/dialogflow_v2.yaml

Другие вопросы по теме