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

Service Account authentication - Invalid JOSE Compact Serialization #179

Open
emremogn opened this issue Feb 19, 2019 · 1 comment
Open

Comments

@emremogn
Copy link

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

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants