【发布时间】:2018-12-03 01:12:47
【问题描述】:
我使用以下文件遇到问题
使用应用引擎默认服务帐户编写方法测试以生成签名的 JWT
private String test() throws CertificateException, UnsupportedEncodingException,
NoSuchAlgorithmException, InvalidKeyException, SignatureException {
long now = System.currentTimeMillis() / 1000;
JSONObject headerJson = new JSONObject();
headerJson.put("typ", "JWT");
headerJson.put("alg", "RS256");
JSONObject payloadJson = new JSONObject();
payloadJson.put("iat", now);
payloadJson.put("exp", now + 3600);
payloadJson.put("iss", "{test-project}@appspot.gserviceaccount.com");
payloadJson.put("sub", "{test-project}@appspot.gserviceaccount.com");
payloadJson.put("aud", "https://echo-api.endpoints.{test-project}.cloud.goog");
String headerAndPayload = String.format("%s.%s", Base64.getUrlEncoder().encodeToString(headerJson.toString().getBytes()), Base64.getUrlEncoder().encodeToString(payloadJson.toString().getBytes()));
AppIdentityService appIdentityService = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.SigningResult signingResult = appIdentityService.signForApp(headerAndPayload.getBytes());
String signedJwt = String.format("%s.%s", headerAndPayload , new
String(Base64.getUrlEncoder().encode(signingResult.getSignature())));
return signedJwt;
}
我需要生成签名的 JWT 来验证在应用引擎中运行的 java 后端。使用开放 API 云端点保护 API。以下是我的 openapi.yaml
swagger: "2.0"
info:
description: "A simple Google Cloud Endpoints API example."
title: "Endpoints Example"
version: "1.0.0"
host: "echo-api.endpoints.{test-project}.cloud.goog"
consumes:
- "application/json"
produces:
- "application/json"
schemes:
- "https"
paths:
"/test/echo":
post:
description: "Echo back a given message."
operationId: "echo"
produces:
- "application/json"
responses:
200:
description: "Echo"
schema:
$ref: "#/definitions/echoMessage"
parameters:
-
description: "Message to echo"
in: body
name: message
required: true
schema:
$ref: "#/definitions/echoMessage"
security:
- api_key: []
google_jwt: []
definitions:
echoMessage:
type: "object"
properties:
message:
type: "string"
securityDefinitions:
google_jwt:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "stl-cardio-dev@appspot.gserviceaccount.com"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/jwk/{test-project}@appspot.gserviceaccount.com"
创建 JWT 后,我尝试访问 /test/echo 它给出“JWT 验证失败:BAD_SIGNATURE”。
我尝试了
中描述的python客户端我使用以下“标头和有效负载”和“签名方法”,收到以下结果。
(01)。 python header_and_payload + python app_identity.sign_blob 方法 => 成功
(02)。 python header_and_payload + java appIdentity.signForApp() => 错误
(03)。 java headerAndPayload + python app_identity.sign_blob 方法 => 成功
(04)。 java headerAndPayload + java appIdentity.signForApp() => 错误
我看到 appIdentity.signForApp() 中的问题导致我的 java 实现。
我找不到完整的示例或文档。我如何使用 java 生成正确的签名 JWT。
谢谢。
【问题讨论】:
-
在 Base64 编码时,您是否尝试过使用 utf-8 字符集调用 getBytes?
-
我试过了。字符串 headerAndPayload = String.format("%s.%s", Base64.getUrlEncoder().encodeToString(headerJson.toString().getBytes(UTF-8)), Base64.getUrlEncoder().encodeToString(payloadJson.toString() .getBytes(UTF-8)));但结果是一样的。
-
按照Troubleshooting JWT Validation 的步骤来确定签名的 JWT 或您的
openapi.yaml是否存在问题。缩小问题范围并告诉我,以便我们继续解决问题。 -
我遵循这个,我可以确认签名 JWT 中的问题。也 python 代理完美地与相同的 openapi.yaml 一起工作。文档说签名结果的“signingResult.getSignature()”是“SHA256withRSA”散列。我们需要将此散列字节数组转换为“Base64 url 安全编码”以生成最终的 JWT。我看到那里有问题。 SHA256withRSA -> Base64 或 SHA256withRSA -> 需要字符串。
-
尝试使用 this example 创建签名的 JWT
标签: java google-app-engine jwt google-cloud-endpoints google-cloud-endpoints-v2