0
votes

I've deployed the following endpoints framework API to my Google appengine application + generated and deployed the OpenAPI configuration for Google's "Client-API service" + generated the endpoints client API for my Android app successfully:

@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;
  }
}

As you can see from above I'm using firebase authentication and API keys.

In my Android application I successfully login my Firebase user, but if I try to execute the following an endpoint client API request

    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
}

I get the following response from Google's Endpoints Management service:

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."
}

Any idea, what I'm missing here?

I've followed the following Firebase specific authentication tutorial as well as the following Google Endpoints User Authentication tutorial.

Any idea or hint is very appreciated.


Update:

Here is the SERVICE_CONFIG_FILE used to deploy the endpoints API to Google's Service Management.

SecurityDefinitions from openenapi.json:

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"

Update 2:

Stacktrace from the App Engine console:

 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)

Update 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>

Of course,

"my_project_id"

is just an example ID for this post. I don't want to post my real project id here.

And

"2018-03-29r0"

is the the ID which is generated after deploying the openapi.json file with the command

gcloud endpoints services deploy target/openapi-docs/openapi.json


Update 4:

However I get now the following response from my appengine backend application

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"
}

when executing in my Android app

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

The exception UnauthenticatedException is triggered due to fact, that the backend API method processCutomerOrderRequest() validates user == null although the firebase authentication of the user was signalled as "successfully logged in".

My question: What is wrong here? Maybe I shouldn't use the method setOauthToken() in my client app? Is the call correct?

1
It sounds like you need to redeploy your service (gcloud endpoints services deploy).saiyr
I've done this twice. No luck--> I've edited my post with the "openapi.json" file. Maybe it helps to analyse. I'm wondering, why the openapi.json file doesn't contain any "User" key as defined in the "processCutomerOrderRequest" API method...Degoah
@saiyr Do you need additional information? Maybe the Firebase created "google-service.json" file?Degoah
Please paste the securityDefinitions from your openapi.json. I'm not going to download a file from a third-party site.saiyr
@Saiyr Please find above the Security Definition. In case you need more infos from the openapi.json file please let me know.Degoah

1 Answers

0
votes

I found an answer for the question mentioned in Update 4 of the initial post.

Please find it in the answer of the following post.

This stackoverflow question is comprised of multiple "detailed" questions. Based on self-study all questions could be answered by myself. The link mentioned above can be understood as the last "coffin nail" in finding all answers I was looking for.