是否可以使用服务帐户访问Google管理报告SDK?
我有一个非常基本的例子,我试图运行,我总是得到400错误返回。我已验证密钥和服务ID是否正确,我甚至已授权此服务帐户。这不可能吗?有人有什么想法吗?
PrivateKey serviceAcountPrivateKey = null;
try (InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("insta2.p12")) {
serviceAcountPrivateKey = SecurityUtils.loadPrivateKeyFromKeyStore(
SecurityUtils.getPkcs12KeyStore(), resourceAsStream, "notasecret",
"privatekey", "notasecret");
} catch (IOException | GeneralSecurityException e) {
throw new RuntimeException("Error loading private key", e);
}
try {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
// Build service account credential.
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("BLOCKED@developer.gserviceaccount.com")
.setServiceAccountPrivateKey(serviceAcountPrivateKey)
.setServiceAccountScopes(
Arrays.asList(
ReportsScopes.ADMIN_REPORTS_USAGE_READONLY,
ReportsScopes.ADMIN_REPORTS_AUDIT_READONLY))
.build();
Reports service = new Reports.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("APP_NAME_BLOCKED")
.build();
service.activities().list("all", "admin").execute();
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException("Error init google", e);
}
我得到的错误如下:
{ "代码" :401, "错误" :[{ "结构域" :"全球", "位置" :"授权", "的locationType" :"标题", "消息" :"访问被拒绝。您无权阅读活动记录。", "理由" :" authError" }], "消息" :"访问被拒绝。您无权阅读活动记录。" }
答案 0 :(得分:1)
对于所有想知道的人,如果你不使用电话
.setServiceAccountUser(" admins email address")
在GoogleCredential对象上,这将失败,如上所述。这有点令人困惑,因为它自己的服务帐户没有访问报告的权限,但它确实能够承担一个帐户的角色......
答案 1 :(得分:0)
是的,您需要传递冒充的管理员电子邮件 ID。以下是 GO 语言的工作代码:
package main
import (
"fmt"
"io/ioutil"
"log"
"time"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
//admin "google.golang.org/api/admin/directory/v1"
admin "google.golang.org/api/admin/reports/v1"
"google.golang.org/api/option"
)
// Path to the Service Account's Private Key file
var ServiceAccountFilePath = “/path/to/keyfile.json"
// Build and returns an Admin SDK Directory service object authorized with
// the service accounts that act on behalf of the given user.
// Args:
// user_email: The email of the user. Needs permissions to access the Admin APIs.
// Returns:
// Admin SDK directory service object.
func CreateReportsService(userEmail string) (*admin.Service, error) {
ctx := context.Background()
jsonCredentials, err := ioutil.ReadFile(ServiceAccountFilePath)
if err != nil {
return nil, err
}
config, err := google.JWTConfigFromJSON(jsonCredentials, "https://www.googleapis.com/auth/admin.reports.audit.readonly")
if err != nil {
return nil, fmt.Errorf("JWTConfigFromJSON: %v", err)
}
config.Subject = userEmail
ts := config.TokenSource(ctx)
srv, err := admin.NewService(ctx, option.WithTokenSource(ts))
if err != nil {
return nil, fmt.Errorf("NewService: %v", err)
}
return srv, nil
}
func main() {
srv, err := CreateReportsService(“<admin_user_email_id>") // Here please enter the admin user email id; it is the admin user who has the permission
if err != nil {
log.Fatalf("Unable to retrieve reports Client %v", err)
return
}
var userKey = "all"
//var appName = "admin"
var appName = "login"
//var appName = "token"
r, err := srv.Activities.List(userKey, appName).MaxResults(10).Do()
if err != nil {
log.Fatalf("Unable to retrieve logins to domain: userKey=%s, appName=%s, error: %v", userKey, appName, err)
return
}
if len(r.Items) == 0 {
fmt.Println("No logins found.")
} else {
fmt.Println("Logins:")
for _, a := range r.Items {
t, err := time.Parse(time.RFC3339Nano, a.Id.Time)
if err != nil {
fmt.Println("Unable to parse login time.")
// Set time to zero.
t = time.Time{}
}
fmt.Printf("%s: %s %s\n", t.Format(time.RFC822), a.Actor.Email,
a.Events[0].Name)
}
}
}