2017-10-16 1 views
0

Ich habe eine App-Engine-App hinter Endpunkten und ich habe Probleme, die Dokumentation zum Hinzufügen von Authentifizierung zu befolgen. Meine Präferenz besteht darin, Dienstkonten innerhalb des Projekts zuzulassen und dann eine detailliertere App-Side-Autorisierung durchzuführen.Endpunkte Google ID JWT und Golang oauth2: haben id_token, brauchen access_token?

In meinem Fall werden die meisten Kunden außerhalb von GCP sein und werden automatisierte Programme nicht Menschen, so dass ich JSON-Schlüsseldateien denke, dass der Weg zu gehen ist (korrigieren Sie mich, wenn ich bitte falsch liege). Ich möchte auch die App erneut bereitstellen nicht haben, um Benutzer configs zu ändern, so dass ich folgen Sie den „GOOGLE ID JWT“ Informationen in der Dokumentation von hier:

https://cloud.google.com/endpoints/docs/openapi/service-to-service-auth

dies die Sicherheit Abschnitte meiner Prahlerei ist 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": [] 
    } 
    ] 

Dies setzt OK, aber ich bin ratlos, was von der Client-Seite zu tun Verwendung des Dienstkonto JSON zu machen.

In Go, verwende ich die folgenden, basierend auf mein Verständnis der oauth2/Google-Dokumentation:

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) 
} 

ich der Kürze halber Fehlerprüfung für diesen Code Paste entfernt haben, gibt es keine Fehler, wenn ich Führe das aus. Das Ergebnis dieses Wesens:

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" 
    } 
] 
} 

Bei näherer Betrachtung des Inneren von dem, was geschieht, wie jwt.TokenSource(ctx).Token() Aufruf, ich sehe, dass Google ein id_token zurückkehrt, aber keine access_token (spotted durch einige Debug-Protokolle zum jwt Paket hinzugefügt):

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..."}} 

Also, wenn der oauth2 HTTP-Transport den auth-Header hinzuzufügen versucht - die mit dem AccessToken Feld oben gebunden ist - es ist wie Authorization: Bearer in einem String ergibt, also nicht das Ergebnis.

Ich habe das Gefühl, dass mir hier ein Schritt fehlt, der für mich in der Dokumentation nicht offensichtlich ist.

Danke für Ihre Zeit.

Antwort

0

Es würde erwartet, dass der OAuth-Client id_token anstelle von access_token zurückgibt. Sie verwenden JWTConfigFromJSON, nicht ConfigFromJSON, was korrekt ist. Ich denke, das zweite Argument zu JWTConfigFromJSON ist falsch, und Sie sollten stattdessen Bereiche angeben. Versuchen Sie in diesem Fall "email" anstelle von basePath.

+0

In der Dokumentation zu Endpunkten ist die URL des App Engine-Dienstes (in diesem Fall "basePath") der richtige Wert für Bereiche. Edit für vorzeitige Wiederholung: wird relevante Dokumentation finden – user1184088

+0

Ich bin ziemlich sicher, dass das nicht der Fall ist. Für die Dienstkontoauthentifizierung kann der Dienstname als Zielgruppe verwendet werden, der Basispfad sollte jedoch in keiner der beiden Gruppen enthalten sein, und die Zielgruppe muss vom Gültigkeitsbereich abweichen. – saiyr

Verwandte Themen