But if you use EspAuthenticator you get the following exception:
com.google.api.server.spi.auth.EspAuthenticator authenticate: Authentication failed: endpoints.repackaged.com.google.common.util.concurrent.UncheckedExecutionException: com.google.api.auth.UnauthenticatedException: endpoints.repackaged.org.jose4j.jwt.consumer.InvalidJwtException: JWT processing failed. Additional details: [[17] Unable to process JOSE object (cause: endpoints.repackaged.org.jose4j.lang.JoseException: Invalid JOSE Compact Serialization. Expecting either 3 or 5 parts for JWS or JWE respectively but was 2.): <token_here>] (EspAuthenticator.java:86)
I was able to make service-account-authentication work properly with the following config:
@Api(name = "apiNameHere", version = "v1",
//
authenticators = { EndpointsAuthenticator.class }, // notice the authenticator class
//
issuers = {
//
@ApiIssuer(
//
name = "serviceAccount",
//
issuer = "<app-default-service-account>@appspot.gserviceaccount.com",
//
jwksUri = "https://www.googleapis.com/robot/v1/metadata/x509/<app-default-service-account>@appspot.gserviceaccount.com") },
//
issuerAudiences = {
//
@ApiIssuerAudience(
//
name = "serviceAccount",
//
audiences = "https://www.googleapis.com/oauth2/v4/token") },
//
clientIds = { "<domain-wide-delegated-sa-client-id>" }) // notice the client ID here; I'm using a domain-wide delegated SA to impersonate users; the scope is userinfo.email
My Java SE client is something like this:
public static void main(String[] args) throws IOException {
GoogleCredential googleCredentialsFromJsonStream = GoogleCredential.fromStream(YourClient.class.getResourceAsStream("/your-cert.json"))
.createDelegated("end-user@domain") // used 1.28 api client here! 1.25 doesn't have this method
.createScoped(Collections.singletonList(YourApiScopes.USERINFO_EMAIL));
YourApi.Builder builder = new YourApi.Builder(googleCredentialsFromJsonStream.getTransport(), JacksonFactory.getDefaultInstance(), googleCredentialsFromJsonStream);
TestRequest testRequest = new TestRequest();
System.out.println(builder.build().YourApi().echoSa(testRequest).execute().getEchoedMessage());
}
I was also able to call my endpoint from Apps Script / App Maker using OAuth2 lib:
function getService() {
return OAuth2.createService('Test')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(PK) // your key
.setIssuer(SA) // your service account email
.setSubject(Session.getActiveUser().getEmail()) // impersonated end user
.setPropertyStore(PropertiesService.getUserProperties())
.setScope('https://www.googleapis.com/auth/userinfo.email');
}
According to https://cloud.google.com/endpoints/docs/frameworks/java/service-account-authentication you should set "authenticators" param to the value {EspAuthenticator.class}.
But if you use EspAuthenticator you get the following exception:
com.google.api.server.spi.auth.EspAuthenticator authenticate: Authentication failed: endpoints.repackaged.com.google.common.util.concurrent.UncheckedExecutionException: com.google.api.auth.UnauthenticatedException: endpoints.repackaged.org.jose4j.jwt.consumer.InvalidJwtException: JWT processing failed. Additional details: [[17] Unable to process JOSE object (cause: endpoints.repackaged.org.jose4j.lang.JoseException: Invalid JOSE Compact Serialization. Expecting either 3 or 5 parts for JWS or JWE respectively but was 2.): <token_here>] (EspAuthenticator.java:86)
I was able to make service-account-authentication work properly with the following config:
My Java SE client is something like this:
I was also able to call my endpoint from Apps Script / App Maker using OAuth2 lib: