从 Google 不太安全的应用程序迁移到 Google API,以便在 Java Web 应用程序中发送邮件

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

实际上,我正在使用 Google 邮件,并在 java webapp 中设置不太安全的应用程序。 Google 决定弃用此功能,我必须迁移到使用 Google API 通过 Oauth2 发送邮件 我尝试了多种选择,包括谷歌文档,但没有成功。我压力很大,因为我需要在谷歌关闭不太安全的应用程序兼容性之前解决它。

我拥有一个非营利性 Google Workspace 帐号,这意味着我拥有所有套件的完全访问权限。 我创建了一个完全访问服务帐户。 我启用了 Google Gmail API。 我创建了一个 OAuth 2.0 客户端 ID,其授权 URL 重定向到 http://localhost:8080/ROOT/oauth2callback 我创建了一个 OAuth 同意屏幕。

这是我的java代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Label;
import com.google.api.services.gmail.model.ListLabelsResponse;

/* class to demonstrate use of Gmail list labels API */
public class GmailQuickstart {
  /**
   * Application name.
   */
  private static final String APPLICATION_NAME = "Gmail API Java Quickstart";
  /**
   * Global instance of the JSON factory.
   */
  private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
  /**
   * Directory to store authorization tokens for this application.
   */
  private static final String TOKENS_DIRECTORY_PATH = "tokens";

  /**
   * Global instance of the scopes required by this quickstart.
   * If modifying these scopes, delete your previously saved tokens/ folder.
   */
  private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_LABELS);

  /**
   * Creates an authorized Credential object.
   *
   * @param HTTP_TRANSPORT The network HTTP Transport.
   * @return An authorized Credential object.
   * @throws IOException If the credentials.json file cannot be found.
   */
  private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT)
      throws IOException {
    // Load client secrets.
      File file = new File("/a/b/tokens/eac-webapp-client_secret.json");
      FileInputStream credentialsStream = new FileInputStream(file);
    GoogleClientSecrets clientSecrets =
        GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(credentialsStream));

    // Build flow and trigger user authorization request.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
        .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
        .setAccessType("offline")
        .build();
    LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(43513).build();
    Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
    //returns an authorized Credential object.
    return credential;
  }

  public static void main(String... args) throws IOException, GeneralSecurityException {
    // Build a new authorized API client service.
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
        .setApplicationName(APPLICATION_NAME)
        .build();

    // Print the labels in the user's account.
    String user = "me";
    ListLabelsResponse listResponse = service.users().labels().list(user).execute();
    List<Label> labels = listResponse.getLabels();
    if (labels.isEmpty()) {
      System.out.println("No labels found.");
    } else {
      System.out.println("Labels:");
      for (Label label : labels) {
        System.out.printf("- %s\n", label.getName());
      }
    }
  }
}

我用来创建 GoogleClientSecrets 的文件是我从 OAuth 2.0 客户端 ID 获得的文件。

但总是在执行授权方法的那一刻,在浏览器中打开时收到的消息是“访问被阻止”:此应用程序的请求无效(查看屏幕截图)

enter image description here

enter image description here

此时我被阻止了。 有人有办法解决这种情况吗?

谢谢大家。

g2h2o

java api oauth-2.0 gmail
1个回答
0
投票

您能检查/验证几件事吗?

  • 同意屏幕是否已完全配置,包括必要的范围、应用程序徽标和联系信息?

  • 重定向 URI (http://localhost:8080/ROOT/oauth2callback) 必须与 Google Cloud Console 中 OAuth 2.0 客户端 ID 设置下定义的内容完全匹配。

  • 代码中定义的范围 (GmailScopes.GMAIL_LABELS) 是否已添加到您的同意屏幕?

  • client_secret.json 来自 OAuth 2.0 客户端 ID 配置,而不是来自服务帐户,因为它们有不同的用途?

  • 如果应用程序处于测试模式,请确保测试用户已正确添加到 OAuth 同意屏幕配置中。

您还可以手动使用 OAuth Playground 来验证您的 OAuth 配置是否在代码之外有效:https://developers.google.com/oauthplayground/

最后,检查应用程序验证:如果您的应用程序未经验证,可能会导致访问问题。确保其经过验证,尤其是对于 Gmail 等受限范围。

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