diff --git a/iap/README.md b/iap/README.md index 06325915b13..efc22864d21 100644 --- a/iap/README.md +++ b/iap/README.md @@ -26,6 +26,7 @@ It will be used to test both the authorization of an incoming request to an IAP - [Enable](https://cloud.google.com/iap/docs/app-engine-quickstart) Identity-Aware Proxy on the App Engine app. - Add the service account email to the Identity-Aware Proxy access list for the project. - Set the environment variable `IAP_PROTECTED_URL` to point to `https://your-project-id.appspot.com` +- Set the environment variable `IAP_CLIENT_ID` to point to the [OAuth 2.0 Client ID](https://console.cloud.google.com/apis/credentials) of your IAP protected App Engine Application. - Run the integration test: ``` mvn -Dtest=com.example.iap.BuildAndVerifyIapRequestIT verify diff --git a/iap/src/main/java/com/example/iap/BuildIapRequest.java b/iap/src/main/java/com/example/iap/BuildIapRequest.java index efa59ff5ecb..0b52f06dbc4 100644 --- a/iap/src/main/java/com/example/iap/BuildIapRequest.java +++ b/iap/src/main/java/com/example/iap/BuildIapRequest.java @@ -50,13 +50,6 @@ public class BuildIapRequest { private BuildIapRequest() {} - private static String getBaseUrl(URL url) throws Exception { - String urlFilePath = url.getFile(); - int pathDelim = urlFilePath.lastIndexOf('/'); - String path = (pathDelim > 0) ? urlFilePath.substring(0, pathDelim) : ""; - return (url.getProtocol() + "://" + url.getHost() + path).trim(); - } - private static ServiceAccountCredentials getCredentials() throws Exception { GoogleCredentials credentials = GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(IAM_SCOPE)); @@ -67,7 +60,7 @@ private static ServiceAccountCredentials getCredentials() throws Exception { return (ServiceAccountCredentials) credentials; } - private static String getSignedJWToken(ServiceAccountCredentials credentials, String baseUrl) + private static String getSignedJWToken(ServiceAccountCredentials credentials, String iapClientId) throws IOException { Instant now = Instant.now(clock); long expirationTime = now.getEpochSecond() + EXPIRATION_TIME_IN_SECONDS; @@ -80,7 +73,7 @@ private static String getSignedJWToken(ServiceAccountCredentials credentials, St .setSubject(credentials.getClientEmail()) .setIssuedAt(Date.from(now)) .setExpiration(Date.from(Instant.ofEpochSecond(expirationTime))) - .claim("target_audience", baseUrl) + .claim("target_audience", iapClientId) .signWith(SignatureAlgorithm.RS256, credentials.getPrivateKey()) .compact(); } @@ -105,16 +98,22 @@ private static String getGoogleIdToken(String jwt) throws Exception { return idToken; } - public static HttpRequest buildIAPRequest(HttpRequest request) throws Exception { + /** + * Clone request and add an IAP Bearer Authorization header with signed JWT token. + * @param request Request to add authorization header + * @param iapClientId OAuth 2.0 client ID for IAP protected resource + * @return Clone of request with Bearer style authorization header with signed jwt token. + * @throws Exception + */ + public static HttpRequest buildIAPRequest(HttpRequest request, String iapClientId) throws Exception { // get service account credentials ServiceAccountCredentials credentials = getCredentials(); // get the base url of the request URL - String baseUrl = getBaseUrl(request.getUrl().toURL()); - String jwt = getSignedJWToken(credentials, baseUrl); + String jwt = getSignedJWToken(credentials, iapClientId); if (jwt == null) { throw new Exception( "Unable to create a signed jwt token for : " - + baseUrl + + iapClientId + "with issuer : " + credentials.getClientEmail()); } diff --git a/iap/src/test/java/com/example/iap/BuildAndVerifyIapRequestIT.java b/iap/src/test/java/com/example/iap/BuildAndVerifyIapRequestIT.java index 89bce31fa1f..020444e9b56 100644 --- a/iap/src/test/java/com/example/iap/BuildAndVerifyIapRequestIT.java +++ b/iap/src/test/java/com/example/iap/BuildAndVerifyIapRequestIT.java @@ -34,12 +34,14 @@ public class BuildAndVerifyIapRequestIT { private String iapProtectedUrl = System.getenv("IAP_PROTECTED_URL"); + private String iapClientId = System.getenv("IAP_CLIENT_ID"); private HttpTransport httpTransport = new NetHttpTransport(); private VerifyIapRequestHeader verifyIapRequestHeader = new VerifyIapRequestHeader(); @Before public void setUp() { assertNotNull(iapProtectedUrl); + assertNotNull(iapClientId); } // Access an IAP protected url without signed jwt authorization header @@ -59,7 +61,7 @@ public void accessIapProtectedResourceFailsWithoutJwtHeader() throws Exception { public void testGenerateAndVerifyIapRequestIsSuccessful() throws Exception { HttpRequest request = httpTransport.createRequestFactory().buildGetRequest(new GenericUrl(iapProtectedUrl)); - HttpRequest iapRequest = buildIAPRequest(request); + HttpRequest iapRequest = buildIAPRequest(request, iapClientId); HttpResponse response = iapRequest.execute(); assertEquals(response.getStatusCode(), HttpStatus.SC_OK); String headerWithtoken = response.parseAsString();