如何将自定义信息从 App Engine 身份验证器传递到端点?

How can I pass custom information from an App Engine Authenticator to the Endpoint?

我在这个 post Google Cloud Endpoints and user's authentication 中引用了@MinWan 的精彩回答,他在其中描述了一种将自定义 header 添加到针对 App Engine 的云端点的请求的方法。

很明显,我们可以添加一个自定义 header 并为我们要验证的每个服务(例如 Google、Twitter、Facebook)编写一个验证器,其中每个验证器读取一个具体 header 并针对服务进行身份验证。如果令牌有效,服务通常 returns 带有电子邮件地址或用户 ID 的响应,加上一些额外信息 [A],我们从中生成 com.google.api.server.spi.auth.common.User,稍后传递到端点方法为 com.google.appengine.api.users.User.

第一个问题:为什么我们有两个不同的用户实体,例如具有不同命名空间的用户?看起来,这些都不是 sub/superclasses,因此它们可能是在幕后明确投射的。

第二个问题:显式转换用户实体以及没有自定义字段可以放置服务返回的额外信息 [A] 的问题是额外信息丢失了。此类额外信息可能有助于将外部服务的 oauth2 用户与本地用户或其他服务返回的 oauth2 用户进行匹配。

有输入吗?处理多重身份验证服务的建议方法是什么?

刚测试过,你绝对可以subclass User来包含你想要的任何私有字段。只需将 class 继承多态性用于 return 来自 Authenticator 方法的该类型的对象,而不更改方法签名中默认 User 的类型。

import javax.servlet.http.HttpServletRequest;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Authenticator;

public class BazUser extends User {
        private String secret; // extra piece of data held by this User
        public BazUser(String email) {
                super(email);
                this.secret = "notasecret";
        }
        public BazUser (String email, String secret) {
                super (email);
                this.secret = secret;
        }
}

public class BazAuthenticator implements Authenticator {
        public User authenticate(HttpServletRequest req) {
                return new BazUser ("userid@baz.com", "secret");
        }
}

在功能上,一切都适用于:

import com.google.api.server.spi.auth.common.User;

即使 gradle:

compile 'com.google.endpoints:endpoints-framework:2.0.0-beta.11'

可以通过包含 @SuppressWarnings("ResourceParameter") 来清除 IDE 警告,如下所示:

/**
 * Adds a new PmpUser.
 *
 * @param pmpUser  pmpUser object
 */
@SuppressWarnings("ResourceParameter")
@ApiMethod(
        name = "pmpUser.post",
        path = "pmpUser",
        httpMethod = ApiMethod.HttpMethod.POST)
...