从流中读取凭据时出错,未指定“类型”字段

问题描述 投票:0回答:2

我正在开发一个 Java 应用程序,该应用程序使用 Google Auth 库通过 Google Calendar API 进行身份验证。我已经从 Google Cloud Console 下载了 OAuth2 凭据的

credentials.json
文件,并且我正在我的应用程序中加载此文件,如下所示:

InputStream in = GoogleCalendarExample.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
GoogleCredentials credentials = GoogleCredentials.fromStream(in).createScoped(SCOPES);

但是,当我尝试运行我的应用程序时,出现以下错误:

Exception in thread "main" java.io.IOException: Error reading credentials from stream, 'type' field not specified.
        at com.google.auth.oauth2.GoogleCredentials.fromStream(GoogleCredentials.java:170)
        at com.google.auth.oauth2.GoogleCredentials.fromStream(GoogleCredentials.java:143)
        at pl.szylak.googleservices.GoogleCalendarExample.main(GoogleCalendarExample.java:32)

我已检查我的

credentials.json
文件,它不包含
type
字段。相反,它包含一个
installed
对象,其中包含
client_id
client_secret
和其他详细信息:

{
  "installed": {
    "client_id": "CLIENT_ID.apps.googleusercontent.com",
    "project_id": "PROJECT_ID",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "CLIENT_SECRET",
    "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]
  }
}

我已经了解到 Google Auth 库应该能够毫无问题地处理这种类型的凭据文件,所以我不确定为什么会看到此错误。有没有其他人遇到过这个问题,有谁知道如何解决吗?

我更改了credentials.json 中占位符的值。


这是我的简单 java 代码,用于向我的日历添加一些事件。

package pl.szylak.googleservices;

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Collections;

public class GoogleCalendarExample {
private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static final String CREDENTIALS_FILE_PATH = "/resources/credentials.json";
private static final java.util.List\<String\> SCOPES = Collections.singletonList(CalendarScopes.CALENDAR);

    private static com.google.api.services.calendar.Calendar service;
    
    public static void main(String... args) throws IOException, GeneralSecurityException {
        // Build a new authorized API client service.
        final com.google.api.client.http.javanet.NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        InputStream in = GoogleCalendarExample.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        GoogleCredentials credentials = GoogleCredentials.fromStream(in).createScoped(SCOPES);
        service = new com.google.api.services.calendar.Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, new HttpCredentialsAdapter(credentials))
                .setApplicationName(APPLICATION_NAME)
                .build();
    
        // Call the Google Calendar API and add an event.
        addEvent();
    }
    
    private static void addEvent() throws IOException {
        Event event = new Event()
                .setSummary("Google I/O 2025")
                .setLocation("800 Howard St., San Francisco, CA 94103")
                .setDescription("A chance to learn more about Google's developer products.");
    
        EventDateTime start = new EventDateTime()
                .setDateTime(new DateTime("2025-05-28T09:00:00-07:00"))
                .setTimeZone("America/Los_Angeles");
        event.setStart(start);
    
        EventDateTime end = new EventDateTime()
                .setDateTime(new DateTime("2025-05-28T17:00:00-07:00"))
                .setTimeZone("America/Los_Angeles");
        event.setEnd(end);
    
        String calendarId = "primary";
        event = service.events().insert(calendarId, event).execute();
        System.out.printf("Event created: %s\n", event.getHtmlLink());
    }

}
java oauth-2.0 java-8 oauth google-calendar-api
2个回答
0
投票

总之你错过了“type”:“service_account”,

因为上面的代码试图从文件(来自 - “/resources/credentials.json”)读取凭据,但它无法在凭据文件中找到所需的“类型”字段 交叉检查凭据文件也位于项目的“资源”目录中。


0
投票

发生这种情况是因为您的服务帐户 JSON 文件不正确 - 可能是因为它是从 Firebase 控制台生成和下载的。预期的 JSON 文件应包含以下内容:

{
  "type": "service_account",
  ...
}

可以通过单击所附屏幕截图中突出显示的ADD KEY按钮,通过 Google 云控制台生成此 JSON 文件。

© www.soinside.com 2019 - 2024. All rights reserved.