我们在面向微服务的架构中广泛使用Google Cloud Endpoints(GCE)。所有服务均为Google App Engine。对于面向公众的GAE服务,我们将使用标准的Android OAuth对真实用户进行身份验证。但是,对于非面向用户的服务,我们希望我们的Cloud Endpoints受到保护(不公开),但可以通过默认的GAE服务帐户访问。
例如,内部付款服务可能希望与内部用户服务联系以获取用户的个人资料,使用默认的GAE服务帐户进行身份验证,因此我们不需要在代码中嵌入任何凭据。我们正在使用生成的Java库。
我使用这样的代码用生成的libs初始化服务:
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")
}
}
上面使用的客户端ID是您可以在GAE服务帐户的JSON密钥文件中找到的客户端ID,如果您已将域范围委派添加到您的服务帐户,则会显示在API凭据控制台中。
我们也尝试过对此进行修改,例如删除User参数,而是在@Api注释上设置 authLevel = AuthLevel.REQUIRED 。
没有骰子,我们总是会收到这样的错误:
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
有谁知道 - 我们做错了什么?为什么使用服务帐户保护流量如此困难?
我们希望避免在我们的代码中嵌入凭据,因此请不要回答说我们需要创建一个手动服务帐户。
感谢任何好的建议!我们真的很惊讶与云端点进行服务器到服务器通信是多么困难!