Skip to content

Commit eb97b98

Browse files
committed
Affected Issue(s): Extend OAuth 2.0 support
Resolves sid-indonesia/it-team#333 What this commit has achieved: 1. Added support for Body Authentication on Client Credentials flow 2. TODO implement OAuth 2.0 for sink FHIR Server.
1 parent c4235bf commit eb97b98

File tree

5 files changed

+80
-8
lines changed

5 files changed

+80
-8
lines changed

pipelines/batch/src/main/java/com/google/fhir/analytics/FhirEtlOptions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.google.fhir.analytics;
1717

18+
import com.google.fhir.analytics.enumeration.ClientCredentialsAuthMechanism;
1819
import org.apache.beam.sdk.options.Default;
1920
import org.apache.beam.sdk.options.Description;
2021
import org.apache.beam.sdk.options.Validation.Required;
@@ -84,6 +85,12 @@ public interface FhirEtlOptions extends BasePipelineOptions {
8485

8586
void setFhirServerOAuthTokenEndpoint(String value);
8687

88+
@Description("The mechanism for authenticating a client in the Client Credentials flow.")
89+
@Default.Enum("BASIC")
90+
ClientCredentialsAuthMechanism getFhirServerOAuthMechanism();
91+
92+
void setFhirServerOAuthMechanism(ClientCredentialsAuthMechanism value);
93+
8794
@Description(
8895
"The `client_id` to be used in the OAuth Client Credential flow when interacting with the "
8996
+ "FHIR server; see `fhirServerOAuthEndpoint`.")

pipelines/common/src/main/java/com/google/fhir/analytics/FetchUtil.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
import ca.uhn.fhir.rest.gclient.IOperationUntyped;
3232
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInput;
3333
import com.google.api.client.auth.oauth2.ClientCredentialsTokenRequest;
34+
import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
3435
import com.google.api.client.auth.oauth2.TokenResponse;
3536
import com.google.api.client.http.BasicAuthentication;
3637
import com.google.api.client.http.GenericUrl;
3738
import com.google.api.client.http.javanet.NetHttpTransport;
3839
import com.google.api.client.json.gson.GsonFactory;
3940
import com.google.common.base.Preconditions;
4041
import com.google.common.base.Strings;
42+
import com.google.fhir.analytics.enumeration.ClientCredentialsAuthMechanism;
4143
import java.io.IOException;
4244
import java.time.Instant;
4345
import java.util.List;
@@ -61,6 +63,8 @@ public class FetchUtil {
6163

6264
private final String oAuthTokenEndpoint;
6365

66+
private final ClientCredentialsAuthMechanism oAuthMechanism;
67+
6468
private final String oAuthClientId;
6569

6670
private final String oAuthClientSecret;
@@ -74,13 +78,15 @@ public class FetchUtil {
7478
String sourceUser,
7579
String sourcePw,
7680
String oAuthTokenEndpoint,
81+
ClientCredentialsAuthMechanism oAuthMechanism,
7782
String oAuthClientId,
7883
String oAuthClientSecret,
7984
FhirContext fhirContext) {
8085
this.fhirUrl = sourceFhirUrl;
8186
this.sourceUser = Strings.nullToEmpty(sourceUser);
8287
this.sourcePw = Strings.nullToEmpty(sourcePw);
8388
this.oAuthTokenEndpoint = Strings.nullToEmpty(oAuthTokenEndpoint);
89+
this.oAuthMechanism = oAuthMechanism;
8490
this.oAuthClientId = Strings.nullToEmpty(oAuthClientId);
8591
this.oAuthClientSecret = Strings.nullToEmpty(oAuthClientSecret);
8692
this.fhirContext = fhirContext;
@@ -93,7 +99,7 @@ public class FetchUtil {
9399
log.info("Fetching access tokens from {}", oAuthTokenEndpoint);
94100
authInterceptor =
95101
new ClientCredentialsAuthInterceptor(
96-
oAuthTokenEndpoint, oAuthClientId, oAuthClientSecret);
102+
oAuthTokenEndpoint, oAuthMechanism, oAuthClientId, oAuthClientSecret);
97103
} else if (!this.sourceUser.isEmpty()) {
98104
authInterceptor = new BasicAuthInterceptor(this.sourceUser, sourcePw);
99105
} else {
@@ -252,16 +258,23 @@ private static class ClientCredentialsAuthInterceptor extends BearerTokenAuthInt
252258
private static final int TOKEN_REFRESH_LEEWAY_IN_SECONDS = 10;
253259

254260
private final String tokenEndpoint;
261+
private final ClientCredentialsAuthMechanism oAuthMechanism;
255262
private final String clientId;
256263
private final String clientSecret;
257264
private TokenResponse tokenResponse;
258265
private Instant nextRefresh;
259266

260-
ClientCredentialsAuthInterceptor(String tokenEndpoint, String clientId, String clientSecret) {
267+
ClientCredentialsAuthInterceptor(
268+
String tokenEndpoint,
269+
ClientCredentialsAuthMechanism oAuthMechanism,
270+
String clientId,
271+
String clientSecret) {
261272
Preconditions.checkNotNull(tokenEndpoint);
273+
Preconditions.checkNotNull(clientSecret);
262274
Preconditions.checkNotNull(clientId);
263275
Preconditions.checkNotNull(clientSecret);
264276
this.tokenEndpoint = tokenEndpoint;
277+
this.oAuthMechanism = oAuthMechanism;
265278
this.clientId = clientId;
266279
this.clientSecret = clientSecret;
267280
}
@@ -291,12 +304,24 @@ public void interceptRequest(IHttpRequest theRequest) {
291304
}
292305

293306
TokenResponse requestAccessToken() throws IOException {
294-
TokenResponse response =
307+
ClientCredentialsTokenRequest clientCredentialsTokenRequest =
295308
new ClientCredentialsTokenRequest(
296-
new NetHttpTransport(), new GsonFactory(), new GenericUrl(tokenEndpoint))
297-
.setClientAuthentication(new BasicAuthentication(clientId, clientSecret))
298-
.execute();
299-
return response;
309+
new NetHttpTransport(), new GsonFactory(), new GenericUrl(tokenEndpoint));
310+
switch (oAuthMechanism) {
311+
case BASIC:
312+
clientCredentialsTokenRequest =
313+
clientCredentialsTokenRequest.setClientAuthentication(
314+
new BasicAuthentication(clientId, clientSecret));
315+
break;
316+
case BODY:
317+
clientCredentialsTokenRequest =
318+
clientCredentialsTokenRequest.setClientAuthentication(
319+
new ClientParametersAuthentication(clientId, clientSecret));
320+
break;
321+
case JWT:
322+
break;
323+
}
324+
return clientCredentialsTokenRequest.execute();
300325
}
301326
}
302327
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2020-2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.fhir.analytics.enumeration;
17+
18+
/**
19+
* A set of enumerations to specify the mechanism for authenticating a client in the Client
20+
* Credentials flow.
21+
*/
22+
public enum ClientCredentialsAuthMechanism {
23+
/**
24+
* the client sends its client ID and client secret as part of the Authorization header in an HTTP
25+
* request. The Authorization header contains a Base64-encoded string of <code>
26+
* {URL-encoded-client-ID}:{URL-encoded-client-secret}</code>
27+
*/
28+
BASIC,
29+
30+
/**
31+
* The client sends its client ID and client secret as parameters in the body of the HTTP request.
32+
* This is similar to Basic Authentication, but instead of sending the credentials in the
33+
* Authorization header, they are sent in the request body.
34+
*/
35+
BODY,
36+
37+
/** TODO: Unimplemented yet, as the need for it has not arisen. */
38+
JWT
39+
}

pipelines/controller/src/main/java/com/google/fhir/analytics/ControlPanelApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 Google LLC
2+
* Copyright 2020-2024 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

pipelines/controller/src/main/java/com/google/fhir/analytics/PipelineManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ private FhirSearchUtil getFhirSearchUtil(FhirEtlOptions options) {
331331
options.getFhirServerUserName(),
332332
options.getFhirServerPassword(),
333333
options.getFhirServerOAuthTokenEndpoint(),
334+
options.getFhirServerOAuthMechanism(),
334335
options.getFhirServerOAuthClientId(),
335336
options.getFhirServerOAuthClientSecret(),
336337
avroConversionUtil.getFhirContext()));

0 commit comments

Comments
 (0)