在Cloud Endpoints和API Explorer上验证用户(使用Firebase和Google身份验证)

时间:2021-08-20 23:14:41

Using Cloud Endpoints Frameworks for App Engine I've added authenticating with Firebase Auth in addition to authenticating with Google Accounts.

使用适用于App Engine的Cloud Endpoints框架除了使用Google帐户进行身份验证外,我还添加了使用Firebase Auth进行身份验证的功能。

All is good and well, I can authorize client requests using Firebase Auth, but now I can no longer use API Explorer since that uses Google's authentication and results in a 401 "Invalid credentials" response.

一切都很好,我可以使用Firebase Auth授权客户端请求,但现在我无法再使用API​​资源管理器,因为它使用了Google的身份验证,并导致401“无效凭据”响应。

I added Firebase Auth by doing:

我通过执行以下操作添加了Firebase Auth:

    @Api(
            name = "test",
            version = "v1",
//        authenticators = {EspAuthenticator.class},
            issuers = {
                    @ApiIssuer(
                            name = "firebase",
                            issuer = "https://securetoken.google.com/PROJECT-ID",
                            jwksUri = "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com")
            },
            issuerAudiences = {
                    @ApiIssuerAudience(name = "firebase", audiences = "PROJECT-ID")
            },
            scopes = {Constants.EMAIL_SCOPE},
            clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID, Constants.IOS_CLIENT_ID, Constants.API_EXPLORER},
            audiences = {Constants.ANDROID_AUDIENCE},
            namespace = @ApiNamespace(ownerDomain = "XXX", ownerName = "XXX", packagePath="")
    )

A method that works with Google authentication and API Explorer is:

适用于Google身份验证和API Explorer的方法是:

@ApiMethod(
)
public User getTestUserGoogle(User user) throws UnauthorizedException {
    if (user == null) {
        throw new UnauthorizedException("Invalid credentials");
    }

    return user;
}

And a method that works with Firebase Auth but not OAuth 2.0 on API Explorer is:

在API Explorer上使用Firebase Auth而非OAuth 2.0的方法是:

@ApiMethod(
        authenticators = {EspAuthenticator.class}
)
public User getTestUserFirebase(User user) throws UnauthorizedException {
    if (user == null) {
        throw new UnauthorizedException("Invalid credentials");
    }

    return user;
}

This code snippet seems to suggest EspAuthenticator.class shoud work with Google authentication: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine/endpoints-frameworks-v2/backend/src/main/java/com/example/echo/Echo.java#L128

此代码段似乎建议EspAuthenticator.class使用Google身份验证:https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine/endpoints-frameworks-v2/backend/src/main/java /com/example/echo/Echo.java#L128

However the API Explorer request fails with a 401 "Invalid credentials" response whenever EspAuthenticator.class is set as the authenticator.

但是,只要将EspAuthenticator.class设置为身份验证器,API Explorer请求就会失败并显示401“无效凭据”响应。

Is there any way I can get both Google and Firebase authentication to work on the same method? The only difference between those 2 methods is EspAuthenticator.class and based on the official code snippet in the link above it looks like Google authentication should still work with the EspAuthenticator.class authenticator.

有什么方法可以让Google和Firebase身份验证同时使用相同的方法吗?这两种方法之间的唯一区别是EspAuthenticator.class,并且基于上面链接中的官方代码片段,看起来Google身份验证仍然可以与EspAuthenticator.class身份验证器一起使用。


Update: The error I get from Stackdriver is:

更新:我从Stackdriver获得的错误是:

com.google.api.server.spi.auth.EspAuthenticator authenticate: Authentication failed: com.google.common.util.concurrent.UncheckedExecutionException: com.google.api.auth.UnauthenticatedException: org.jose4j.jwt.consumer.InvalidJwtException: Unable to process JOSE object (cause: org.jose4j.lang.JoseException: Invalid JOSE Compact Serialization. Expecting either 3 or 5 parts for JWS or JWE respectively but was 2.): ya29.GmAkBDwfsFuyOCL7kqSSLelSHpOb9LJLyewtPfpeH1a4t12i8MWmzHBNliMeR9dAtOSARG2o-QlZEHisfEPYbA-Wb-Eh36zugIufmVbDe4E2TP9StAOjub8nsrhAzuGbolE (EspAuthenticator.java:86)

com.google.api.server.spi.auth.EspAuthenticator authenticate:身份验证失败:com.google.common.util.concurrent.UncheckedExecutionException:com.google.api.auth.UnauthenticatedException:org.jose4j.jwt.consumer.InvalidJwtException:无法处理JOSE对象(原因:org.jose4j.lang.JoseException:无效JOSE紧凑序列化分别期待3或5份为JWS或JWE但是2):ya29.GmAkBDwfsFuyOCL7kqSSLelSHpOb9LJLyewtPfpeH1a4t12i8MWmzHBNliMeR9dAtOSARG2o-QlZEHisfEPYbA-WB-Eh36zugIufmVbDe4E2TP9StAOjub8nsrhAzuGbolE(EspAuthenticator。 Java的:86)

Also filed an issue here: https://github.com/GoogleCloudPlatform/java-docs-samples/issues/590

此处还提出了一个问题:https://github.com/GoogleCloudPlatform/java-docs-samples/issues/590

2 个解决方案

#1


2  

You should either add GoogleOAuth2Authenticator or EndpointsAuthenticator

您应该添加GoogleOAuth2Authenticator或EndpointsAuthenticator

EndpointsAuthenticator is a wrapper for GoogleJwtAuthenticator, GoogleAppEngineAuthenticator, GoogleOAuth2Authenticator.

EndpointsAuthenticator是GoogleJwtAuthenticator,GoogleAppEngineAuthenticator,GoogleOAuth2Authenticator的包装器。

well, your authenticators parameter is supposed to look like

好吧,你的authenticators参数看起来应该是这样的

authenticators = {EspAuthenticator.class, GoogleOAuth2Authenticator.class},

#2


0  

It's more simple, you need pass token to appengine.

它更简单,你需要传递令牌到appengine。

Once you have the firebase token you have to auth with JSON Web Token I believe this is the EspAuthenticator.class method.

一旦你拥有了firebase令牌,就必须使用JSON Web Token进行身份验证,我相信这是EspAuthenticator.class方法。

Here is the Authentication using firebase token

这是使用firebase令牌的身份验证

Auth JSON WEB TOKEN Firebase Users

curl \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer ${firebase_token}" \
 -X GET \
 "https://$PROJECT_ID.appspot.com/_ah/api/echo/v1/firebase_user"

#1


2  

You should either add GoogleOAuth2Authenticator or EndpointsAuthenticator

您应该添加GoogleOAuth2Authenticator或EndpointsAuthenticator

EndpointsAuthenticator is a wrapper for GoogleJwtAuthenticator, GoogleAppEngineAuthenticator, GoogleOAuth2Authenticator.

EndpointsAuthenticator是GoogleJwtAuthenticator,GoogleAppEngineAuthenticator,GoogleOAuth2Authenticator的包装器。

well, your authenticators parameter is supposed to look like

好吧,你的authenticators参数看起来应该是这样的

authenticators = {EspAuthenticator.class, GoogleOAuth2Authenticator.class},

#2


0  

It's more simple, you need pass token to appengine.

它更简单,你需要传递令牌到appengine。

Once you have the firebase token you have to auth with JSON Web Token I believe this is the EspAuthenticator.class method.

一旦你拥有了firebase令牌,就必须使用JSON Web Token进行身份验证,我相信这是EspAuthenticator.class方法。

Here is the Authentication using firebase token

这是使用firebase令牌的身份验证

Auth JSON WEB TOKEN Firebase Users

curl \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer ${firebase_token}" \
 -X GET \
 "https://$PROJECT_ID.appspot.com/_ah/api/echo/v1/firebase_user"