How to use a GAE service account to call server endpoints on a server?

We make extensive use of Google Cloud Endpoints (GCE) in our microservice-oriented architecture. All services are Google App Engine. For GAE public services, we will use standard Android OAuth to authenticate real users. However, for non-user services, we want our cloud endpoints to be protected (not publicly accessible), but accessible by default GAE service account.

For example, an internal payment service may want to contact the internal user service to obtain a user profile by authenticating with the default GAE service account, so we do not need to embed any credentials in our code. We use created Java libraries.

I use this code to initialize a service with generated libraries:

public User createUserService() { AppIdentityCredential credential = new AppIdentityCredential(Lists.newArrayList(OAUTH_EMAIL_SCOPE)) return new User.Builder(new UrlFetchTransport(), new JacksonFactory, credential) .setRootUrl(userServiceRootUrl) .build() } 

We also tried using GoogleCredential.getApplicationDefault () and setting the scope for this credential object.

The final destination called from the first GAE service has this code:

 @Api( name = "user", version = "v1", clientIds = Array(Constants.APP_ENGINE_SERVICE_ACCOUNT_CLIENT_ID) ) class UserEndpoints { /** * GET /user/:id * * Get a single user by id */ @ApiMethod( httpMethod = HttpMethod.GET, path = "user/{id}" ) def find( @Named("id") id: Long, authUser: GoogleUser ): User = { if (authUser == null) { throw new OAuthRequestException("Must be authenticated to use this endpoint!") } UserDAO.find(id) getOrElse { throw new NotFoundException("User not found") } } 

The client identifier used above is the one you can find in the JSON key file for GAE service accounts, which appears in the Credentials API console if you add domain domains to your service account.

We also tried options such as removing the User argument and setting authLevel = AuthLevel.REQUIRED in the @Api annotation.

No dice, we always get the error:

 Request URL: https://user-service-dot-foo-dev.appspot.com/_ah/api/user/v1/user/1 Method: user.userEndpoints.find Error Code: 403 Reason: insufficientAuthorizedParty Message: Client_id is not allowed 

Does anyone know what we are doing wrong? Why is it so difficult to have secured traffic with service accounts?

We want to avoid embedding credentials in our code, so please do not respond by saying that we need to create a manual service account.

Thanks for the good suggestions! We really wonder how difficult it is to communicate between servers and cloud ends!

+6
source share

All Articles