How to google oauth to an api? My example is not working

五迷三道 提交于 2020-06-29 03:46:45

问题


I am trying to do this article for google cloud build

https://cloud.google.com/endpoints/docs/openapi/service-account-authentication

I am guessing to use the service account email I generated the key from in that example AND for Audient, I put "" (which is probably the reason it's not working?). I have no idea and can't find what in the world to put for audience.

In addition to code below, I tried setting audience to 'https://cloudbuild.googleapis.com' which also did not work

My code is the following...

public class GenToken {
    public static void main(String[] args) throws IOException {
        Duration d = Duration.ofDays(365);
        String tok = generateJwt("/Users/dean/workspace/order/java/googleBuild/orderly-gcp-key.json",
                "mycloudbuilder@order-gcp.iam.gserviceaccount.com", "", d.toSeconds());

        System.out.println("tok="+tok);

        URL url = new URL("https://cloudbuild.googleapis.com/v1/projects/order-gcp/builds");
        makeJwtRequest(tok, "GET", url);

    }

    public static String generateJwt(final String saKeyfile, final String saEmail,
                                     final String audience, final long 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);
    }

    /**
     * Makes an authorized request to the endpoint.
     */
    public static String makeJwtRequest(final String signedJwt, String method, final URL url)
            throws IOException, ProtocolException {

        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod(method);
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("Authorization", "Bearer " + signedJwt);

        InputStreamReader reader = new InputStreamReader(con.getInputStream());
        BufferedReader buffReader = new BufferedReader(reader);

        String line;
        StringBuilder result = new StringBuilder();
        while ((line = buffReader.readLine()) != null) {
            result.append(line);
        }
        buffReader.close();
        return result.toString();
    }
}

The orderly-gcp-key.json has these attributes in it

{
    "type": "service_account",
    "project_id": "myproj",
    "private_key_id": "xxxxxxxx",
    "private_key": "-----BEGIN PRIVATE KEY-----\nasdfsd\n-----END PRIVATE KEY-----\n",
    "client_email": "build-ci-mine@myproj.iam.gserviceaccount.com",
    "client_id": "1167333552",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/build-ci-mine%40myproj.iam.gserviceaccount.com"
}

oops, my edit didn't get posted :(. Here is the error

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: https://cloudbuild.googleapis.com/v1/projects/orderly-gcp/builds
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1919)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
at com.orderlyhealth.auth.websecure.GenToken.makeJwtRequest(GenToken.java:71)
at com.orderlyhealth.auth.websecure.GenToken.main(GenToken.java:26)

回答1:


I hope that I better understood!!

When you try to reach a Google API, you have to use an access token. I have 2 code snippets for you.

Use Google Http client

        GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
        HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(credentials));
        HttpRequest request = factory.buildGetRequest(new GenericUrl("https://cloudbuild.googleapis.com/v1/projects/gbl-imt-homerider-basguillaueb/builds"));
        HttpResponse httpResponse = request.execute();
        System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

Use pure java connection

        GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();

        HttpURLConnection con = (HttpURLConnection) new URL("https://cloudbuild.googleapis.com/v1/projects/gbl-imt-homerider-basguillaueb/builds").openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("Authorization", "Bearer " + credentials.refreshAccessToken().getTokenValue());

        InputStreamReader reader = new InputStreamReader(con.getInputStream());
        BufferedReader buffReader = new BufferedReader(reader);

        String line;
        StringBuilder result = new StringBuilder();
        while ((line = buffReader.readLine()) != null) {
            result.append(line);
        }
        buffReader.close();
        System.out.println(result.toString());

You can rely on the platform environment. In local, perform a gcloud auth application-default login to set your credential as default default credential. On GCP, the component identity (the default service account or the service account that you define when you create the component), is used thanks to the method GoogleCredentials.getApplicationDefault();

Your dependency management need this (here in maven)

        <dependency>
            <groupId>com.google.auth</groupId>
            <artifactId>google-auth-library-oauth2-http</artifactId>
            <version>0.20.0</version>
        </dependency>

Does this solve your issue?



来源:https://stackoverflow.com/questions/62450572/how-to-google-oauth-to-an-api-my-example-is-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!