Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.
This repository was archived by the owner on Jun 30, 2023. It is now read-only.

Service Account authentication - Invalid JOSE Compact Serialization #179

Open

Description

@emremogn

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:

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

Activity

  1. abhideep commented on Mar 24, 2021

    @abhideep

    Seeing the same exception. Were you able to resolve this? How?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions