端点Google ID JWT和Golang oauth2:有id_token,需要access_token?
我有终点后面的App Engine应用程序,我有以下的文档添加周围认证的麻烦。我的首选是允许项目中的服务帐户通过,然后执行更细化的应用程序端授权。端点Google ID JWT和Golang oauth2:有id_token,需要access_token?
在我的情况下,大多数客户会外GCP,将不会自动程序的人,所以我使用JSON以为是去(纠正我,如果我错了,请)的方式密钥文件。我也不想重新部署应用程序更改用户的configs,所以我遵循从这里文档中的“GOOGLE ID JWT”信息:
https://cloud.google.com/endpoints/docs/openapi/service-to-service-auth
这是我招摇的安全部分JSON:
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "key",
"in": "query"
},
"google_id_token": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-issuer": "https://accounts.google.com"
}
},
"security": [
{
"api_key": [],
"google_id_token": []
}
]
此部署好了,但我难倒如何从客户端做使用该服务帐户JSON的。
在围棋,我用下面的,根据我的的oauth2 /谷歌文档的理解:
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"golang.org/x/oauth2/google"
)
func main() {
ctx := context.Background()
apiKey := os.Getenv("API_KEY")
basePath := "https://SERVICE_NAME-dot-PROJECT_NAME.appspot.com" // changed for privacy
creds, _ := google.FindDefaultCredentials(ctx)
jwt, _ := google.JWTConfigFromJSON(creds.JSON, basePath)
client := jwt.Client(ctx)
res, _ := client.Get(fmt.Sprintf("%s/REQUEST_PATH?key=%s", basePath, apiKey)) // changed for privacy
body, _ := ioutil.ReadAll(res.Body)
log.Printf("### http status: %d %s", res.StatusCode, res.Status)
log.Printf("### http body: %s", body)
}
我已经删除错误检查这段代码粘贴为了简洁,没有任何错误,当我运行这个。这之中的结果:
2017/10/16 07:32:38 ### http status: 401 401 Unauthorized
2017/10/16 07:32:38 ### http body: {
"code": 16,
"message": "JWT validation failed: Missing or invalid credentials",
"details": [
{
"@type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "auth"
}
]
}
一旦发生了什么事,如调用jwt.TokenSource(ctx).Token()
的内部检查,我看到谷歌正在恢复的id_token
,但没有access_token
(通过添加一些调试日志的智威汤逊包发现):
2017/10/16 07:38:47 ### oauth2/jwt -> tokenURL: https://accounts.google.com/o/oauth2/token, form: url.Values{"grant_type":[]string{"urn:ietf:params:oauth:grant-type:jwt-bearer"}, "assertion":[]string{"...cut..."}}
2017/10/16 07:38:47 ### oauth2/jwt <- response: {
"id_token" : "...cut..."
}
2017/10/16 07:38:47 ### oauth2/jwt <- token: &oauth2.Token{AccessToken:"", TokenType:"", RefreshToken:"", Expiry:time.Time{wall:0x0, ext:63643740079, loc:(*time.Location)(0x1424160)}, raw:map[string]interface {}{"id_token":"...cut..."}}
所以当的oauth2 HTTP传输尝试添加在auth头 - 这是联系在一起的的accessToken字段上方 - 它导致像Authorization: Bearer
一个字符串,从而结果失败。
我觉得我在这里失踪了一步这不是明显对我的文档。
谢谢你的时间。
将预期的OAuth客户端返回id_token
而不是access_token
。您正在使用JWTConfigFromJSON
,而不是ConfigFromJSON
,这是正确的。我认为JWTConfigFromJSON
的第二个参数是不正确的,您应该指定范围。在这种情况下,请尝试"email"
而不是basePath
。
每端点文档,应用程序引擎服务('在这种情况下basePath')的URL是作用域正确的值。 编辑过早重播:找到相关文件 – user1184088
我相当肯定的是,情况并非如此。对于服务帐户验证,服务名称可以用作受众,但基本路径不应该在两者之间,受众与范围不同。 – saiyr