当前位置: 首页 > 知识库问答 >
问题:

在GraalVM原生映像中使用Google Api服务时“无效的JWT:受众检查失败”

谢志文
2023-03-14

我有一个简单的应用程序,它通过基于HTTP的google-api-services-log向Google Cloud Logging发送消息。我最初使用的是gRPC云日志库,但根本无法让它与GraalVM一起工作。但不幸的是,我也在与HTTP变体作斗争。该代码在传统的JavaVM上执行时工作正常,但在运行本机映像时在运行时失败。

java.io.IOException: Error getting access token for service account: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT: Failed audience check."}
    at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444)
    at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157)
    at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:145)
    at com.google.auth.oauth2.ServiceAccountCredentials.getRequestMetadata(ServiceAccountCredentials.java:603)
    at com.google.auth.http.HttpCredentialsAdapter.initialize(HttpCredentialsAdapter.java:91)
    at com.google.api.client.http.HttpRequestFactory.buildRequest(HttpRequestFactory.java:88)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.buildHttpRequest(AbstractGoogleClientRequest.java:422)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:541)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:474)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:591)
    ...
Caused by: com.google.api.client.http.HttpResponseException: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT: Failed audience check."}
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)
    at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:441)
    ... 35 more

native-image.properties

Args = \
  --verbose \
  --no-server \
  --no-fallback \
  --static \
  --install-exit-handlers \
  -H:+ReportExceptionStackTraces \
  -H:+TraceClassInitialization \
  -H:+PrintClassInitialization \
  -H:UseMuslC=/musl/ \
  -H:+RemoveSaturatedTypeFlows \
  --enable-https \
  --enable-http \
  --initialize-at-build-time

反射配置。json

[
  {
    "name": "com.google.api.client.json.GenericJson",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.services.logging.v2.model.LogEntry",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.googleapis.GoogleUtils",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }
]

资源配置。json

{
  "resources": [
    { "pattern": "^.*\\.json$" },
    { "pattern": "^.*\\.properties$" },
    { "pattern": "^.*\\.jks$" }
  ]
}

应用程序。斯卡拉

val scopes = util.Arrays.asList(LoggingScopes.CLOUD_PLATFORM_READ_ONLY, LoggingScopes.LOGGING_WRITE)
val credentials  = ServiceAccountCredentials.fromStream("service-account.json").createScoped(scopes)
val logging = new Logging.Builder(
  transport,
  JacksonFactory.getDefaultInstance,
  new HttpCredentialsAdapter(credentials)
).setApplicationName("my-project").build()

Dockerfile文件

FROM        oracle/graalvm-ce:20.1.0-java11 as builder
...
RUN         gu install native-image
...
RUN         sbt assembly
RUN         native-image -jar /root/target/scala-2.13/graal-test-assembly-0.1.0-SNAPSHOT.jar

FROM        scratch

WORKDIR     /app/

COPY        --from=builder /root/graal-test-assembly-0.1.0-SNAPSHOT /app/my-native-image

CMD         ["/app/my-native-image"]

我怀疑这与加密/SSL相关的功能有关,但我已经没有东西可以尝试了。

共有1个答案

伏默
2023-03-14

事实证明,生成的JWT令牌基本上是空的,因为当序列化为JSON时,字段是通过反射遍历的。将相应的规则添加到反射配置。json解决了这个问题,并揭示了可以通过配置解决的更多问题。

[
  {
    "name": "com.google.api.client.json.GenericJson",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.json.webtoken.JsonWebToken",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.json.webtoken.JsonWebToken$Header",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.json.webtoken.JsonWebToken$Payload",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.util.GenericData",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.http.UrlEncodedContent",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.json.webtoken.JsonWebSignature$Header",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.json.webtoken.JsonWebSignature",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.services.logging.v2.model.WriteLogEntriesRequest",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.services.logging.v2.model.WriteLogEntriesResponse",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.services.logging.v2.model.LogEntry",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.client.googleapis.json.GoogleJsonError",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.google.api.services.logging.v2.model.MonitoredResource",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }
]

Google的Java库中对反射的滥用是相当痛苦的。他们至少可以将GraalVM本机映像配置添加到他们的库中。

您可以找到完整的反射配置。这里是谷歌云登录http的json。

 类似资料:
  • 我正在尝试用GraalVM创建一个本地映像,我的代码是: 然后我把代码本身称为: 当我运行IDE或java-jar时,它可以正常工作,但当我尝试编译为本机映像时,会抛出一个错误。下面是用于编译本机映像的命令行。 错误: TypeError:invokeMember(打印)在JavaObject[com.compiler.commons.log]上。Console@113a2d320(com.com

  • 失败:生成失败,出现异常。 错误:执行任务“:QuarkusBuild”失败。Io.Quarkus.Builder.BuildException:生成失败:由于错误导致生成失败[error]:生成步骤Io.Quarkus.Deployment.Pkg.Steps.NativeImageBuildStep#Build引发异常:java.lang.RuntimeException:未能在io.Quar

  • 我无法在Catalina 10.15.2中运行命令: 它向我返回以下消息: 我试过跑步 哪里 没有运气。我无法运行该命令,因此无法成功运行该命令 mvn安装-Pnative。 [pastebin][1] 我已经读过这个[帖子][2],对我来说不起作用。 救命啊求你了 更新 好的,我已经应用了建议,现在我可以创建native-image,但是当我尝试运行mvn install-P本国时,我遇到了一个

  • 所有使用指南都显示了如何在单个 JAR 文件上运行。但我相信大多数项目通常在类路径上使用多个JAR(例如Gradle默认方式)。如何告诉本机映像将它们全部捆绑到一个可执行文件中?

  • 在错误=我正在获取“消息”的上下文中需要帮助:“Access token validation Failure.Invalid Pavior.”, 我正在使用OAuth中的授权代码授予类型。我已经使用Azure广告策略将自定义声明映射到应用程序。因此,如果用户Scope=appid/.default,那么我将在令牌中获得一个自定义声明,并在Azure AD上对应用程序具有API权限,如user.r