Как использовать учетную запись службы GAE для вызова облачных оконечных точек сервер-сервер?
Мы широко используем Google Cloud Endpoints (GCE) в нашей микросервисно-ориентированной архитектуре. Все сервисы являются Google App Engine. Для общедоступных сервисов GAE мы будем использовать стандартную Android OAuth для аутентификации реальных пользователей. Однако для сервисов, не связанных с пользователями, мы хотим, чтобы наши облачные конечные точки были защищены (не доступны публично), но были доступны для учетной записи службы GAE по умолчанию.
Например, внутренняя платежная служба может захотеть связаться с внутренней пользовательской службой, чтобы получить профиль пользователя, аутентифицируясь с учетной записью службы GAE по умолчанию, поэтому нам не нужно встраивать какие-либо учетные данные в наш код. Мы используем сгенерированные библиотеки Java.
Я использую такой код для инициализации сервиса сгенерированными библиотеками:
public User createUserService() {
AppIdentityCredential credential = new AppIdentityCredential(Lists.newArrayList(OAUTH_EMAIL_SCOPE))
return new User.Builder(new UrlFetchTransport(), new JacksonFactory, credential)
.setRootUrl(userServiceRootUrl)
.build()
}
Мы также попытались использовать GoogleCredential.getApplicationDefault() и установить области действия для этого объекта учетных данных.
Целевая конечная точка, которая вызывается из первой службы GAE, имеет такой код:
@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")
}
}
Используемый выше идентификатор клиента - это тот, который вы можете найти в файле ключей JSON для учетных записей служб GAE, который отображается в консоли учетных данных API, если вы добавили делегирование по всему домену в свою учетную запись службы.
Мы также попробовали варианты этого, например, удалили аргумент User и вместо этого установили authLevel = AuthLevel.REQUIRED в аннотации @Api.
Никаких кубиков, мы всегда получаем ошибку, подобную этой:
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
Кто-нибудь знает - что мы делаем не так? Почему так сложно защитить трафик с помощью учетных записей служб?
Мы хотим избежать встраивания учетных данных в наш код, поэтому, пожалуйста, не отвечайте, сказав, что нам нужно создать учетную запись службы вручную.
Спасибо за любые хорошие предложения! Мы очень удивлены, насколько сложно осуществлять межсерверную связь с облачными конечными точками!