Google端点框架和firebase身份验证问题(配置中未定义身份验证提供程序)

时间:2018-03-28 17:33:06

标签: java android firebase firebase-authentication google-cloud-endpoints

我已将以下端点框架API部署到我的Google appengine应用程序+生成并部署了Google的“Client-API服务”的OpenAPI配置+为我的Android应用成功生成了端点客户端API:

@Api( 
name = "endpoint",
version = "v1",
apiKeyRequired = AnnotationBoolean.TRUE,
authenticators = {EspAuthenticator.class},
issuers = {
            @ApiIssuer(
                name = "firebase",
                issuer = "https://securetoken.google.com/MY_PROJECT_ID",
                jwksUri = "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com")
        },
 issuerAudiences = {
         @ApiIssuerAudience(name = "firebase", audiences = "MY_PROJECT_ID")
 },
namespace =
@ApiNamespace(
    ownerDomain = "xxxxx",
    ownerName = "xxxxx"
)
public class API {  
  @ApiMethod(name = "procesOrderRequest", path = "customer/orders/request")
     public Order processCutomerOrderRequest(User user, OrderRequest orderRequest) throws UnauthorizedException {
      log.info("procesOrderRequest(): CustomerId: " + orderRequest.getCustomer());
      log.info("procesOrderRequest(): bagId: " + orderRequest.getBagId());

      log.info("processCutomerOrderRequest(): customerId: " + orderRequest.getCustomer());

      if (user == null) {
          throw new UnauthenticatedException("Unauthorized user by RR");
      }

      Order order = new Order();
      order.setBagId(orderRequest.getBagId());
      order.setPriority(orderRequest.getPriority());
      order.setOrderId(orderRequest.getBagId() + 1000);
      return order;
  }
}

从上面我可以看到,我正在使用firebase身份验证和API密钥。

在我的Android应用程序中,我成功登录了Firebase用户,但是如果我尝试执行以下端点客户端API请求

    private class ContactBackendTask extends AsyncTask<Void, Void, Void> {
    String mIDToken = null;

    @Override
    protected Void doInBackground(Void... voids) {

        FirebaseUser user = mFirebaseAuthenticator.getCurrentUser();

        user.getIdToken(true).addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
            @Override
            public void onSuccess(GetTokenResult result) {
                mIDToken = result.getToken();
                //Do whatever
                Log.d("attempLogin", "GetTokenResult result = " + mIDToken);
            }
        });

        Endpoint.Builder endpoint = new Endpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null);
        endpoint.setRootUrl("https://MY_PROJECT_ID.appspot.com/_ah/api/");
        endpoint.setApplicationName("MY_PROJECT_ID");
        Endpoint service = endpoint.build();

        OrderRequest orderRequest = new OrderRequest();
        orderRequest.setBagId(35);
        orderRequest.setPriority(9);
        orderRequest.setCustomer("someUser@gmail.com");
        try {
            Endpoint.ProcesOrderRequest request = service.procesOrderRequest(orderRequest);
            Order order = request.setKey("MY_API_KEY").setOauthToken(mIDToken).execute();
            Log.d("attempLogin", "OrderId result = " + order.getOrderId());
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
return null
}

我从Google的终端管理服务得到以下回复:

400 Bad Request
{
   "code": 400,
   "errors": [
   {
     "domain": "global",
     "message": "java.lang.IllegalArgumentException: No auth providers are defined in the config.",
       "reason": "badRequest"
   }
  ],
  "message": "java.lang.IllegalArgumentException: No auth providers are defined in the config."
}

任何想法,我在这里缺少什么?

我遵循了以下Firebase specific authentication tutorial以及以下Google Endpoints User Authentication tutorial

非常感谢任何想法或提示。

更新

以下是用于将端点API部署到Google服务管理的SERVICE_CONFIG_FILE

来自openenapi.json的SecurityDefinitions:

securityDefinitions":{
    "api_key":{
        "in":"query",
        "name":"key",
        "type":"apiKey"
    },
    "firebase":{
        "authorizationUrl":"",
        "flow":"implicit",
        "type":"oauth2",
        "x-google-issuer":"https://securetoken.google.com/my_project_id",
        "x-google-jwks_uri":"https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com"
    }
},
"swagger":"2.0"

更新2:

来自App Engine控制台的Stacktrace:

 java.lang.IllegalArgumentException: No auth providers are defined in the config.

    at com.google.api.auth.Authenticator.create (Authenticator.java:178)
    at com.google.api.auth.Authenticator.create (Authenticator.java:171)
    at com.google.api.server.spi.auth.EspAuthenticator.<init> (EspAuthenticator.java:54)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance (Constructor.java:423)
    at java.lang.Class.newInstance (Class.java:443)
    at com.google.api.server.spi.request.Auth$1.apply (Auth.java:57)
    at com.google.api.server.spi.request.Auth$1.apply (Auth.java:51)

更新3:

    <env-variables>
    <env-var name="ENDPOINTS_SERVICE_NAME" value="my_project_id.appspot.com" />
     <env-var name="ENDPOINTS_SERVICE_VERSION" value="2018-03-29r0" /> 
</env-variables>

当然,

  

“my_project_id”

只是这篇文章的一个示例ID。我不想在这里发布我的真实项目ID。

并且

  

“2018-03-29r0”

是部署openapi.json文件后生成的ID 使用命令

  

gcloud端点服务部署目标/ openapi-docs / openapi.json

更新4:

但是我现在从我的appengine后端应用程序得到以下响应

503 Service Unavailable
 {
 "code": 503,
  "errors": [
     {
      "domain": "global",
     "message": "com.google.api.auth.UnauthenticatedException: Unauthorized user by RR",
  "reason": "backendError"
   }
  ],
  "message": "com.google.api.auth.UnauthenticatedException: Unauthorized user by RR"
}

在我的Android应用中执行

Order order = request.setKey("MY_API_KEY").setOauthToken(mIDToken).execute();

由于事实上后端API方法 processCutomerOrderRequest()验证用户== null ,但是触发了 UnauthenticatedException 异常,尽管firebase身份验证用户的信号称为“已成功登录”。

我的问题:这里有什么问题?也许我不应该在我的客户端应用程序中使用 setOauthToken()方法?通话是否正确?

1 个答案:

答案 0 :(得分:0)

我找到了初始帖子的 Update 4 中提到的问题的答案。

请在following帖子的答案中找到。

此stackoverflow问题由多个“详细”问题组成。 基于自学,所有问题都可以由我自己解答。上面提到的链接可以被理解为找到我正在寻找的所有答案的最后一个“棺材钉”。