Create an access checker plugin
In this guide you will create your own access checker plugin.
Implement the AccessCheckerFactory
interface
To create your own access checker plugin, create an implementation of
the AccessCheckerFactory
interface
annotated with a @Named(value = "name")
annotation defining the name of the
plugin.
The most important parts are to implement a
custom AccessChecker
to be returned by the factory and its checkAccess
function which specifies if
access is granted or not by returning
an AccessDecision
.
Create a new class
The simplest way to create your own access checker is to make a new class file
in the plugins/src/main/java/com/google/fhir/gateway/plugin
directory, next to
the existing sample plugins. The following code can be used as a starting
template for a minimal access checker:
package com.google.fhir.gateway.plugin;
import ca.uhn.fhir.context.FhirContext;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.fhir.gateway.FhirUtil;
import com.google.fhir.gateway.HttpFhirClient;
import com.google.fhir.gateway.JwtUtil;
import com.google.fhir.gateway.interfaces.AccessChecker;
import com.google.fhir.gateway.interfaces.AccessCheckerFactory;
import com.google.fhir.gateway.interfaces.AccessDecision;
import com.google.fhir.gateway.interfaces.NoOpAccessDecision;
import com.google.fhir.gateway.interfaces.PatientFinder;
import com.google.fhir.gateway.interfaces.RequestDetailsReader;
import javax.inject.Named;
public class MyAccessChecker implements AccessChecker {
private final FhirContext fhirContext;
private final HttpFhirClient httpFhirClient;
private final String claim;
private final PatientFinder patientFinder;
// We're not using any of the parameters here, but real access checkers
// would likely use some/all.
private MyAccessChecker(
HttpFhirClient httpFhirClient,
String claim,
FhirContext fhirContext,
PatientFinder patientFinder) {
this.fhirContext = fhirContext;
this.claim = claim;
this.httpFhirClient = httpFhirClient;
this.patientFinder = patientFinder;
}
@Override
public AccessDecision checkAccess(RequestDetailsReader requestDetails) {
// Implement your access logic here.
return NoOpAccessDecision.accessGranted();
}
// The factory must be thread-safe but the AccessChecker instances it returns
// do not need to be thread-safe.
@Named(value = "sample")
public static class Factory implements AccessCheckerFactory {
static final String CLAIM = "sub";
private String getClaim(DecodedJWT jwt) {
return FhirUtil.checkIdOrFail(JwtUtil.getClaimOrDie(jwt, CLAIM));
}
@Override
public AccessChecker create(
DecodedJWT jwt,
HttpFhirClient httpFhirClient,
FhirContext fhirContext,
PatientFinder patientFinder) {
String claim = getClaim(jwt);
return new MyAccessChecker(httpFhirClient, claim, fhirContext, patientFinder);
}
}
}
Rebuild to include the plugin
Once you're done implementing your access checker plugin, rebuild using
mvn package
from the root of the project to include the plugin, set the
access-checker using e.g. export ACCESS_CHECKER=sample
Run the gateway
Run the gateway using e.g.
java -jar exec/target/exec-0.1.0.jar --server.port=8080
.