Cloud Endpoints 门户的身份验证问题
Authentication issues with Cloud Endpoints Portal
我在我的 App Engine 项目中实施了 Cloud Endpoints Framework,我想从已弃用的 API Explorer 迁移到新的 Endpoints 门户,但我遇到了身份验证问题。
我有一个端点启用了身份验证 Google ID token。但是,当用户在端点门户中单击 'Try This API' 时,他未通过身份验证。这适用于旧的 API 资源管理器。
我使用本教程中描述的项目:https://cloud.google.com/endpoints/docs/frameworks/java/get-started-frameworks-java。
API管理已在documentation and I followed these steps中描述了对用户进行身份验证
我已将下面的 class 添加到示例代码中以测试带有身份验证的 API:
package com.example.echo;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.UnauthorizedException;
@Api(
name = "authenticatedApi",
title = "Authenticated API",
version = "v1",
description = "Use OAuth 2.0 to authenticate",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
clientIds = {"*"}
)
public class AuthenticatedApi {
@ApiMethod(name = "sayHello")
public Message sayHello(User user) throws UnauthorizedException {
if (user == null) {
throw new UnauthorizedException("Invalid credentials");
}
Message message = new Message();
message.setMessage("Hello " + user.getEmail());
return message;
}
}
documentation关于如何配置门户进行身份验证,但没有关于 OAuth 2.0
我使用 maven 插件和 gcloud 生成并部署 openapi.json 文件:
$ mvn endpoints-framework:openApiDocs
$ gcloud endpoints services deploy target/openapi-docs/openapi.json
我错过了什么?
所以我找到了一种方法,但找不到任何相关文档。
这个code sample suggest that the Cloud Endpoints Portal needs ESP. But unlike Cloud Endpoints with OpenApi, Cloud Endpoints Framework does not use ESP,但是:
a built-in API gateway that provides API management features that are comparable to the features that ESP provides for Endpoints for OpenAPI
因此,mvn endpoints-framework:openApiDocs
生成的 openapi.json 文件缺少一些信息。
这是我更改的内容:
在class级别,在@Api注解中:
- 添加了观众(即使我没有 Android 客户,并且根据 documentation,观众仅供 Android 客户使用)
- 添加了自定义验证器来处理 ESP,类似于 com.google.api.server.spi.auth.EspAuthenticator
在 openapi.json 文件中,用 mvn endpoints-framework:openApiDocs
生成后
- securityDefinitions 部分,authorizationUrl https://accounts.google.com/o/oauth2/v2/auth(否则我有错误)
- 在我的方法路径声明中,其中包含 OAuth 范围的安全部分
来源:
API
package com.example.echo;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.UnauthorizedException;
@Api(
name = "authenticatedApi",
title = "Authenticated API",
version = "v1",
description = "Use OAuth to authenticate",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
clientIds = {"*"},
audiences = {"my-web-client-id.apps.googleusercontent.com"},
authenticators = {CustomAuthenticator.class}
)
public class AuthenticatedApi {
@ApiMethod(name = "sayHello")
public Message sayHello(User user) throws UnauthorizedException {
if (user == null) {
throw new UnauthorizedException("Invalid credentials");
}
Message message = new Message();
message.setMessage("Hello " + user.getEmail());
return message;
}
}
验证器
package com.example.echo;
import com.google.api.auth.UserInfo;
import com.google.api.control.ConfigFilter;
import com.google.api.control.model.MethodRegistry;
import com.google.api.server.spi.auth.EndpointsAuthenticator;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.response.ServiceUnavailableException;
import javax.servlet.http.HttpServletRequest;
public class CustomAuthenticator extends EndpointsAuthenticator {
private final com.google.api.auth.Authenticator authenticator;
public CustomAuthenticator() {
// ESP needs another authenticator
this.authenticator = com.google.api.auth.Authenticator.create();
}
@Override
public User authenticate(HttpServletRequest request) throws ServiceUnavailableException {
User user = super.authenticate(request);
// Testing the user is enough for the API Explorer, not for the Endpoints Portal
if (user == null) {
try {
MethodRegistry.Info methodInfo = ConfigFilter.getMethodInfo(request);
MethodRegistry.AuthInfo authInfo = methodInfo.getAuthInfo().get();
String serviceName = ConfigFilter.getService(request).getName();
UserInfo userInfo = this.authenticator.authenticate(request, authInfo, serviceName);
user = new User(userInfo.getId(), userInfo.getEmail());
} catch (Exception e) {
return null;
}
}
return user;
}
}
openapi.json
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "My Application"
},
"host": "my-application.appspot.com",
"basePath": "/_ah/api",
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/authenticatedApi/v1/sayHello": {
"post": {
"operationId": "AuthenticatedApiSayHello",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/Message"
}
}
},
"security": [
{
"google_id_token_https": ["https://www.googleapis.com/auth/userinfo.email"]
}
],
"x-security": [
{
"google_id_token_https": {
"audiences": [
"my-web-client-id.apps.googleusercontent.com"
]
}
}
]
}
}
},
"securityDefinitions": {
"google_id_token_https": {
"type": "oauth2",
"authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth",
"flow": "implicit",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v1/certs"
}
},
"definitions": {
"Email": {
"properties": {
"email": {
"type": "string"
}
}
},
"Message": {
"properties": {
"message": {
"type": "string"
}
}
}
}
}
这是 Google Cloud Endpoints 团队的当前功能请求:
我在我的 App Engine 项目中实施了 Cloud Endpoints Framework,我想从已弃用的 API Explorer 迁移到新的 Endpoints 门户,但我遇到了身份验证问题。
我有一个端点启用了身份验证 Google ID token。但是,当用户在端点门户中单击 'Try This API' 时,他未通过身份验证。这适用于旧的 API 资源管理器。
我使用本教程中描述的项目:https://cloud.google.com/endpoints/docs/frameworks/java/get-started-frameworks-java。
API管理已在documentation and I followed these steps中描述了对用户进行身份验证
我已将下面的 class 添加到示例代码中以测试带有身份验证的 API:
package com.example.echo;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.UnauthorizedException;
@Api(
name = "authenticatedApi",
title = "Authenticated API",
version = "v1",
description = "Use OAuth 2.0 to authenticate",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
clientIds = {"*"}
)
public class AuthenticatedApi {
@ApiMethod(name = "sayHello")
public Message sayHello(User user) throws UnauthorizedException {
if (user == null) {
throw new UnauthorizedException("Invalid credentials");
}
Message message = new Message();
message.setMessage("Hello " + user.getEmail());
return message;
}
}
documentation关于如何配置门户进行身份验证,但没有关于 OAuth 2.0
我使用 maven 插件和 gcloud 生成并部署 openapi.json 文件:
$ mvn endpoints-framework:openApiDocs
$ gcloud endpoints services deploy target/openapi-docs/openapi.json
我错过了什么?
所以我找到了一种方法,但找不到任何相关文档。
这个code sample suggest that the Cloud Endpoints Portal needs ESP. But unlike Cloud Endpoints with OpenApi, Cloud Endpoints Framework does not use ESP,但是:
a built-in API gateway that provides API management features that are comparable to the features that ESP provides for Endpoints for OpenAPI
因此,mvn endpoints-framework:openApiDocs
生成的 openapi.json 文件缺少一些信息。
这是我更改的内容:
在class级别,在@Api注解中:
- 添加了观众(即使我没有 Android 客户,并且根据 documentation,观众仅供 Android 客户使用)
- 添加了自定义验证器来处理 ESP,类似于 com.google.api.server.spi.auth.EspAuthenticator
在 openapi.json 文件中,用 mvn endpoints-framework:openApiDocs
- securityDefinitions 部分,authorizationUrl https://accounts.google.com/o/oauth2/v2/auth(否则我有错误)
- 在我的方法路径声明中,其中包含 OAuth 范围的安全部分
来源:
API
package com.example.echo;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.UnauthorizedException;
@Api(
name = "authenticatedApi",
title = "Authenticated API",
version = "v1",
description = "Use OAuth to authenticate",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
clientIds = {"*"},
audiences = {"my-web-client-id.apps.googleusercontent.com"},
authenticators = {CustomAuthenticator.class}
)
public class AuthenticatedApi {
@ApiMethod(name = "sayHello")
public Message sayHello(User user) throws UnauthorizedException {
if (user == null) {
throw new UnauthorizedException("Invalid credentials");
}
Message message = new Message();
message.setMessage("Hello " + user.getEmail());
return message;
}
}
验证器
package com.example.echo;
import com.google.api.auth.UserInfo;
import com.google.api.control.ConfigFilter;
import com.google.api.control.model.MethodRegistry;
import com.google.api.server.spi.auth.EndpointsAuthenticator;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.response.ServiceUnavailableException;
import javax.servlet.http.HttpServletRequest;
public class CustomAuthenticator extends EndpointsAuthenticator {
private final com.google.api.auth.Authenticator authenticator;
public CustomAuthenticator() {
// ESP needs another authenticator
this.authenticator = com.google.api.auth.Authenticator.create();
}
@Override
public User authenticate(HttpServletRequest request) throws ServiceUnavailableException {
User user = super.authenticate(request);
// Testing the user is enough for the API Explorer, not for the Endpoints Portal
if (user == null) {
try {
MethodRegistry.Info methodInfo = ConfigFilter.getMethodInfo(request);
MethodRegistry.AuthInfo authInfo = methodInfo.getAuthInfo().get();
String serviceName = ConfigFilter.getService(request).getName();
UserInfo userInfo = this.authenticator.authenticate(request, authInfo, serviceName);
user = new User(userInfo.getId(), userInfo.getEmail());
} catch (Exception e) {
return null;
}
}
return user;
}
}
openapi.json
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "My Application"
},
"host": "my-application.appspot.com",
"basePath": "/_ah/api",
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/authenticatedApi/v1/sayHello": {
"post": {
"operationId": "AuthenticatedApiSayHello",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/Message"
}
}
},
"security": [
{
"google_id_token_https": ["https://www.googleapis.com/auth/userinfo.email"]
}
],
"x-security": [
{
"google_id_token_https": {
"audiences": [
"my-web-client-id.apps.googleusercontent.com"
]
}
}
]
}
}
},
"securityDefinitions": {
"google_id_token_https": {
"type": "oauth2",
"authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth",
"flow": "implicit",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v1/certs"
}
},
"definitions": {
"Email": {
"properties": {
"email": {
"type": "string"
}
}
},
"Message": {
"properties": {
"message": {
"type": "string"
}
}
}
}
}
这是 Google Cloud Endpoints 团队的当前功能请求: