Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “线程中的异常”;“主要”;com.google.api.client.auth.oauth2.TokenResponseException:401尝试访问google课堂api时未经授权_Java_Google Api_Google Oauth_Google Admin Sdk_Google Classroom - Fatal编程技术网

Java “线程中的异常”;“主要”;com.google.api.client.auth.oauth2.TokenResponseException:401尝试访问google课堂api时未经授权

Java “线程中的异常”;“主要”;com.google.api.client.auth.oauth2.TokenResponseException:401尝试访问google课堂api时未经授权,java,google-api,google-oauth,google-admin-sdk,google-classroom,Java,Google Api,Google Oauth,Google Admin Sdk,Google Classroom,我已经阅读了所有与此问题相关的堆栈溢出问题。我有一些想法,但它不能帮助我解决这个问题 我已使用服务帐户进行授权。因为我不想为我的用户显示授权屏幕。所以我在GoogleAPI控制台中创建了服务帐户并启用了域范围的委托权限 我需要以编程的方式在用户的google教室中创建课程。我已经按照java语言使用了OAuth客户机ID和OAuth客户机机密。完成后,授权令牌已存储在项目目录中。使用此令牌,我可以在授权用户的google教室中创建课程。因为我需要在谷歌教室中为我所在领域的许多用户创建课程。所以我

我已经阅读了所有与此问题相关的堆栈溢出问题。我有一些想法,但它不能帮助我解决这个问题

我已使用服务帐户进行授权。因为我不想为我的用户显示授权屏幕。所以我在GoogleAPI控制台中创建了服务帐户并启用了域范围的委托权限

我需要以编程的方式在用户的google教室中创建课程。我已经按照java语言使用了OAuth客户机ID和OAuth客户机机密。完成后,授权令牌已存储在项目目录中。使用此令牌,我可以在授权用户的google教室中创建课程。因为我需要在谷歌教室中为我所在领域的许多用户创建课程。所以我使用了服务帐户。当我尝试实现它时,我得到了上面的错误

我已经在web应用程序中实现了它。为了更好地理解和代码可读性,我创建了一个quickstart maven项目并粘贴了代码。代码在System.out.println(“进入列表课程方法:”)中运行良好;线路

1) 如何解决这个问题

2) 它会要求管理员授权吗?因为为了访问用户数据,我们需要访问令牌。如何使用服务帐户获取访问令牌

public class ClassroomServiceAccount {

    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String SERVICE_ACCOUNT_EMAIL = "xxxxxxx@projectName.iam.gserviceaccount.com";
    private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "/MyProject.p12";
    private static final List<String> SCOPES = Arrays.asList(ClassroomScopes.CLASSROOM_COURSES, ClassroomScopes.CLASSROOM_TOPICS, ClassroomScopes.CLASSROOM_ANNOUNCEMENTS);

    public static void main(String... args) throws IOException, GeneralSecurityException {

        HttpTransport httpTransport = new NetHttpTransport();
        InputStream in = ClassroomServiceAccount.class.getResourceAsStream(SERVICE_ACCOUNT_PKCS12_FILE_PATH);
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(in, "notasecret".toCharArray());

        String alias = "key1";

        Key key = keystore.getKey(alias, "notasecret".toCharArray());

          // Get certificate of public key
          Certificate cert = keystore.getCertificate(alias);

          // Get public key
          PublicKey publicKey = cert.getPublicKey();
          System.out.println("This is public key : "+ publicKey);

          // Return a key pair
          KeyPair k = new KeyPair(publicKey, (PrivateKey) key);
          System.out.println("This is k : "+ k.getPrivate());



    GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountPrivateKey(k.getPrivate())
                .setServiceAccountScopes(SCOPES)
                .setServiceAccountUser("email@yourdomain.com")
                .build();   


  System.out.println("credentials : " + credential.getServiceAccountPrivateKey());

  Classroom service = new Classroom.Builder(httpTransport, JSON_FACTORY, null)
        .setApplicationName(APPLICATION_NAME)
        .setHttpRequestInitializer(credential)
        .build();

        // Create courses in users google classroom
        Course course = new Course();
        course.setOwnerId("user@yourdomain.com");
        course.setName("Science");
        service.courses().create(course).execute();
        }
    }
公共类ClassroomServiceAccount{
私有静态最终JsonFactory JSON_FACTORY=JacksonFactory.getDefaultInstance();
私有静态最终字符串服务\u帐户\u电子邮件=”xxxxxxx@projectName.iam.gserviceaccount.com";
私有静态最终字符串服务\u帐户\u PKCS12\u文件\u路径=“/MyProject.p12”;
私有静态最终列表范围=Arrays.asList(ClassroomScopes.clustry\u课程、ClassroomScopes.clustry\u主题、ClassroomScopes.clustry\u公告);
publicstaticvoidmain(字符串…参数)抛出IOException、GeneralSecurityException{
HttpTransport HttpTransport=新的NetHttpTransport();
InputStream in=ClassroomServiceAccount.class.getResourceAsStream(服务\帐户\ PKCS12\文件\路径);
KeyStore KeyStore=KeyStore.getInstance(KeyStore.getDefaultType());
加载(在“notasecret.toCharArray()中);
字符串alias=“key1”;
Key=keystore.getKey(别名“notasecret.toCharArray());
//获取公钥证书
证书cert=keystore.getCertificate(别名);
//获取公钥
PublicKey PublicKey=cert.getPublicKey();
System.out.println(“这是公钥:“+publicKey”);
//返回密钥对
密钥对k=新密钥对(公钥,(私钥)密钥);
System.out.println(“这是k:+k.getPrivate());
GoogleCredential credential=新建GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_工厂)
.setServiceAccountId(服务\帐户\电子邮件)
.setServiceAccountPrivateKey(k.getPrivate())
.setServiceAccountScopes(范围)
.setServiceAccountUser(“email@yourdomain.com")
.build();
System.out.println(“凭证:+credential.getServiceAccountPrivateKey());
教室服务=新教室.Builder(httpTransport,JSON_工厂,空)
.setApplicationName(应用程序名称)
.setHttpRequestInitializer(凭证)
.build();
//在谷歌教室中创建课程
课程=新课程();
course.setOwnerId(“user@yourdomain.com");
课程名称(“科学”);
service.courses().create(course.execute();
}
}

如评论中所述,您必须将用户凭据替换为用户的凭据。在本例中,我使用服务帐户中的示例修改了凭证的示例。如您所见,我完全删除了
getCredentials
函数。但是,您仍然可以将凭据生成器放在那里:

public class ClassroomQuickstart {
    private static final String APPLICATION_NAME = "Google Classroom API Java Quickstart";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";
    private static final String KEY_FILE_LOCATION = "full path of your service account creds json";

    /**
     * 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(ClassroomScopes.CLASSROOM_COURSES_READONLY);


    /**
     * 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.
     */

    public static void main(String... args) throws IOException, GeneralSecurityException {


        GoogleCredential credential = GoogleCredential
                .fromStream(new FileInputStream(KEY_FILE_LOCATION))
                .createScoped(ClassroomScopes.all());
        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        Classroom service = new Classroom.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME)
                .build();

        // List the first 10 courses that the user has access to.
        ListCoursesResponse response = service.courses().list()
                .setPageSize(10)
                .execute();
        List<Course> courses = response.getCourses();
        if (courses == null || courses.size() == 0) {
            System.out.println("No courses found.");
        } else {
            System.out.println("Courses:");
            for (Course course : courses) {
                System.out.printf("%s\n", course.getName());
            }
        }
    }
}
域范围快速启动的其余部分


您的教室服务生成器和新课程代码是正确的,应该与新的凭证一起使用。

我已通过更改范围解决了此异常。i、 例如,在我的代码中,我使用了三个作用域。这三个范围应与Gsuite的范围相匹配。同时,我们增加了范围。这两个范围都应该匹配,以避免未经授权

您是否从服务帐户创建了
?代币在里面。是的。我已经下载了.p12密钥。你可以在我的代码中看到它。i、 例如,私有静态最终字符串服务\u帐户\u PKCS12\u文件\u路径=“/MyProject.p12”@Jescanellas我从.p12文件中获得了私钥,并将其传递到凭证中(setServiceAccountPrivateKey)。我已经提到了这个答案。不要使用那个帖子,因为它是从2013年开始的,而且已经过时了。尝试从同一个站点复制步骤3授权。@Jescanella我可以使用该快速启动创建课程。他们使用了OAuth客户端ID。但我的问题不同。我想使用服务帐户,因为它使用机器人帐户启用服务器到服务器、应用程序级身份验证。谢谢您的回答。你能消除我的两个疑虑吗?1) 我需要在我的用户的google教室中创建课程/班级。我可以在哪里指定他们的电子邮件ID/所有者ID?2) 当我执行这段代码时,我得到了“系统无法调整指定的路径”。我为路径指定了限定名称(projectname/src/main/resources)。如何解决这个问题?1)您是从API还是从Web界面创建课程?2) 关于路径位置,您必须使用完整路径,因为它使用的是FileInputStream。例如:
/usr/local/bin/home/userName/myProjects/java/IntellijProjects/src/main/resources/service
GoogleCredential credential2 = new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId("example@project.iam.gserviceaccount.com")
                .setServiceAccountScopes(SCOPES)
                .setServiceAccountUser("my_email@example.com")
                .setServiceAccountPrivateKeyFromP12File(new File(KEY_FILE_LOCATION)).build();