简体   繁体   中英

Google endpoints framework and firebase authentication issue (No auth providers are defined in the config)

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM