2017-10-16 184 views
0

我有终点后面的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一个字符串,从而结果失败。

我觉得我在这里失踪了一步这不是明显对我的文档。

谢谢你的时间。

回答

0

将预期的OAuth客户端返回id_token而不是access_token。您正在使用JWTConfigFromJSON,而不是ConfigFromJSON,这是正确的。我认为JWTConfigFromJSON的第二个参数是不正确的,您应该指定范围。在这种情况下,请尝试"email"而不是basePath

+0

每端点文档,应用程序引擎服务('在这种情况下basePath')的URL是作用域正确的值。 编辑过早重播:找到相关文件 – user1184088

+0

我相当肯定的是,情况并非如此。对于服务帐户验证,服务名称可以用作受众,但基本路径不应该在两者之间,受众与范围不同。 – saiyr

相关问题