1
votes

I am developing an application with JWT authentication on the google cloud platform. Server side I added authentication via Cloud API Gateway to a cloud run backend. Now I am making a client to generate the JWT token and pass it in the call. To do this I am creating an application that must be deployed on CloudRun and I am following this documentation: https://cloud.google.com/api-gateway/docs/authenticate-service-account#making_an_authenticated_request. My problem is that I don't know how to indicate what it requires as saKeyfile. I tried to put only the name of the file that under src / main / resources / filetest.json but once I try to call the method it tells me file not found. I tried to indicate also the full path. Can anyone help me?

PS I'm using Java

EDIT: here is my code which is the same of documentation

 public void makeCall() {
    String fullPath="src/main/resources/TEST1-id.json";
    String saEmail="testsa@projectID.iam.gserviceaccount.com";
    String audience="auth";
    int expiryLenght=600;
    String token;
    try {
        token=generateJwt(fullPath,saEmail,audience,expiryLenght);
        System.out.println("Token generated: "+token);
        URL url = new URL("apigatewayurl");
        makeJwtRequest(token, url);
        System.out.println("Call performed");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private static String generateJwt(final String saKeyfile, final String saEmail,
                                  final String audience, final int expiryLength)
        throws FileNotFoundException, IOException {

    Date now = new Date();
    Date expTime = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expiryLength));

    // Build the JWT payload
    JWTCreator.Builder token = JWT.create()
            .withIssuedAt(now)
            // Expires after 'expiraryLength' seconds
            .withExpiresAt(expTime)
            // Must match 'issuer' in the security configuration in your
            // swagger spec (e.g. service account email)
            .withIssuer(saEmail)
            // Must be either your Endpoints service name, or match the value
            // specified as the 'x-google-audience' in the OpenAPI document
            .withAudience(audience)
            // Subject and email should match the service account's email
            .withSubject(saEmail)
            .withClaim("email", saEmail);

    // Sign the JWT with a service account
    FileInputStream stream = new FileInputStream(saKeyfile);
    ServiceAccountCredentials cred = ServiceAccountCredentials.fromStream(stream);
    RSAPrivateKey key = (RSAPrivateKey) cred.getPrivateKey();
    Algorithm algorithm = Algorithm.RSA256(null, key);
    return token.sign(algorithm);
}

i've tried to use full path like in example and using only /TEST1-id.json

and here there is project structure. Is a springboot application which i will deploy in cloud run

enter image description here

1
Can you share more about your code, your architecture and the tests that you performed? - guillaume blaquiere
Hi @guillaumeblaquiere, I've edited the post :) - Francesco
Why do you need a SA file if you deploy on Cloud Run? - guillaume blaquiere
I need sa file for retrieve and generate jwt token to authenticate to another api gateway which is accessible only from this service account. If there is another way, please tell me - Francesco
Yes i tried. In the end I put the file in the root and copied it in the docker image and recover it as an environment variable in cloud run - Francesco

1 Answers

2
votes

The OP fixed the issue on this way

In the end I put the file in the root and copied it in the docker image and recover it as an environment variable in cloud run