binaryIds = file.getValue();
for (var nextBinaryId : binaryIds) {
+ String nextBinaryIdPart = new IdType(nextBinaryId).getIdPart();
+ assertThat(nextBinaryIdPart, matchesPattern("[a-zA-Z0-9]{32}"));
+
Binary binary = myBinaryDao.read(new IdType(nextBinaryId));
assertEquals(Constants.CT_FHIR_NDJSON, binary.getContentType());
diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml
index 677a9ca52d6..4dbc5053465 100644
--- a/hapi-fhir-jpaserver-test-r4b/pom.xml
+++ b/hapi-fhir-jpaserver-test-r4b/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml
index aca614fbbe7..85881800013 100644
--- a/hapi-fhir-jpaserver-test-r5/pom.xml
+++ b/hapi-fhir-jpaserver-test-r5/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml
index 09ab9e26270..2ca337b4257 100644
--- a/hapi-fhir-jpaserver-test-utilities/pom.xml
+++ b/hapi-fhir-jpaserver-test-utilities/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index 84a6d6dec11..afeee5071cf 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
+++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml
index 4c49668e12e..80617f57860 100644
--- a/hapi-fhir-server-mdm/pom.xml
+++ b/hapi-fhir-server-mdm/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml
index 0dcc05a3523..d2239b8c3d3 100644
--- a/hapi-fhir-server-openapi/pom.xml
+++ b/hapi-fhir-server-openapi/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index be1b382cf47..9eebc8dcd8d 100644
--- a/hapi-fhir-server/pom.xml
+++ b/hapi-fhir-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/bulk/BulkExportJobParameters.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/bulk/BulkExportJobParameters.java
index 40740e05876..bde8e3b2efe 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/bulk/BulkExportJobParameters.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/bulk/BulkExportJobParameters.java
@@ -110,6 +110,10 @@ public class BulkExportJobParameters implements IModelJson {
*/
@JsonProperty("partitionId")
private RequestPartitionId myPartitionId;
+ @JsonProperty("binarySecurityContextIdentifierSystem")
+ private String myBinarySecurityContextIdentifierSystem;
+ @JsonProperty("binarySecurityContextIdentifierValue")
+ private String myBinarySecurityContextIdentifierValue;
public String getExportIdentifier() {
return myExportId;
@@ -231,6 +235,38 @@ public class BulkExportJobParameters implements IModelJson {
this.myPartitionId = thePartitionId;
}
+ /**
+ * Sets a value to place in the generated Binary resource's
+ * Binary.securityContext.identifier
+ */
+ public void setBinarySecurityContextIdentifierSystem(String theBinarySecurityContextIdentifierSystem) {
+ myBinarySecurityContextIdentifierSystem = theBinarySecurityContextIdentifierSystem;
+ }
+
+ /**
+ * Sets a value to place in the generated Binary resource's
+ * Binary.securityContext.identifier
+ */
+ public String getBinarySecurityContextIdentifierSystem() {
+ return myBinarySecurityContextIdentifierSystem;
+ }
+
+ /**
+ * Sets a value to place in the generated Binary resource's
+ * Binary.securityContext.identifier
+ */
+ public void setBinarySecurityContextIdentifierValue(String theBinarySecurityContextIdentifierValue) {
+ myBinarySecurityContextIdentifierValue = theBinarySecurityContextIdentifierValue;
+ }
+
+ /**
+ * Sets a value to place in the generated Binary resource's
+ * Binary.securityContext.identifier
+ */
+ public String getBinarySecurityContextIdentifierValue() {
+ return myBinarySecurityContextIdentifierValue;
+ }
+
public enum ExportStyle {
PATIENT, GROUP, SYSTEM
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationConstants.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationConstants.java
index 3c2da3fc6c6..43426534786 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationConstants.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationConstants.java
@@ -22,6 +22,7 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
public class AuthorizationConstants {
public static final int ORDER_CONSENT_INTERCEPTOR = 100;
+ public static final int ORDER_BINARY_SECURITY_INTERCEPTOR = 150;
public static final int ORDER_AUTH_INTERCEPTOR = 200;
public static final int ORDER_CONVERTER_INTERCEPTOR = 300;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptor.java
new file mode 100644
index 00000000000..b5949976512
--- /dev/null
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptor.java
@@ -0,0 +1,154 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package ca.uhn.fhir.rest.server.interceptor.binary;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.interceptor.api.Hook;
+import ca.uhn.fhir.interceptor.api.Interceptor;
+import ca.uhn.fhir.interceptor.api.Pointcut;
+import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException;
+import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationConstants;
+import ca.uhn.fhir.util.FhirTerser;
+import org.apache.commons.lang3.Validate;
+import org.hl7.fhir.instance.model.api.IBaseBinary;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+/**
+ * This security interceptor checks any Binary resources that are being exposed to
+ * a user and can forbid the user from accessing them based on the security context
+ * found in Binary.securityContext.identifier
.
+ *
+ * This interceptor is intended to be subclassed. The default implementation if it
+ * is not subclassed will reject any access to a Binary resource unless the
+ * request is a system request (using {@link SystemRequestDetails} or the Binary
+ * resource has no value in Binary.securityContext.identifier
.
+ *
+ *
+ * Override {@link #securityContextIdentifierAllowed(String, String, RequestDetails)} in order
+ * to allow the user to access specific context values.
+ *
+ *
+ * @since 6.8.0
+ */
+@SuppressWarnings("unused")
+@Interceptor(order = AuthorizationConstants.ORDER_BINARY_SECURITY_INTERCEPTOR)
+public class BinarySecurityContextInterceptor {
+
+ private final FhirContext myFhirContext;
+
+ /**
+ * Constructor
+ *
+ * @param theFhirContext The FHIR context
+ */
+ public BinarySecurityContextInterceptor(FhirContext theFhirContext) {
+ Validate.notNull(theFhirContext, "theFhirContext must not be null");
+ myFhirContext = theFhirContext;
+ }
+
+ /**
+ * Interceptor hook method. Do not call this method directly.
+ */
+ @Hook(Pointcut.STORAGE_PRESHOW_RESOURCES)
+ public void preShowResources(IPreResourceShowDetails theShowDetails, RequestDetails theRequestDetails) {
+ for (IBaseResource nextResource : theShowDetails.getAllResources()) {
+ if (nextResource instanceof IBaseBinary) {
+ applyAccessControl((IBaseBinary) nextResource, theRequestDetails);
+ }
+ }
+ }
+
+ /**
+ * Interceptor hook method. Do not call this method directly.
+ */
+ @Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED)
+ public void preShowResources(IBaseResource theOldValue, IBaseResource theNewValue, RequestDetails theRequestDetails) {
+ if (theOldValue instanceof IBaseBinary) {
+ applyAccessControl((IBaseBinary) theOldValue, theRequestDetails);
+ }
+ }
+
+ /**
+ * This method applies security to a given Binary resource. It is not typically
+ * overridden but you could override it if you wanted to completely replace the
+ * security logic in this interceptor.
+ *
+ * @param theBinary The Binary resource being checked
+ * @param theRequestDetails The request details associated with this request
+ */
+ protected void applyAccessControl(IBaseBinary theBinary, RequestDetails theRequestDetails) {
+ FhirTerser terser = myFhirContext.newTerser();
+ String securityContextSystem = terser.getSinglePrimitiveValueOrNull(theBinary, "securityContext.identifier.system");
+ String securityContextValue = terser.getSinglePrimitiveValueOrNull(theBinary, "securityContext.identifier.value");
+
+ if (isNotBlank(securityContextSystem) || isNotBlank(securityContextValue)) {
+ applyAccessControl(theBinary, securityContextSystem, securityContextValue, theRequestDetails);
+ }
+ }
+
+ /**
+ * This method applies access controls to a Binary resource containing the
+ * given identifier system and value in the Binary.securityContext element.
+ *
+ * @param theBinary The binary resource
+ * @param theSecurityContextSystem The identifier system
+ * @param theSecurityContextValue The identifier value
+ * @param theRequestDetails The request details
+ */
+ protected void applyAccessControl(IBaseBinary theBinary, String theSecurityContextSystem, String theSecurityContextValue, RequestDetails theRequestDetails) {
+ if (theRequestDetails instanceof SystemRequestDetails) {
+ return;
+ }
+ if (securityContextIdentifierAllowed(theSecurityContextSystem, theSecurityContextValue, theRequestDetails)) {
+ return;
+ }
+
+ handleForbidden(theBinary);
+ }
+
+ /**
+ * Handles a non-permitted operation. This method throws a {@link ForbiddenOperationException}
+ * but you could override it to change that behaviour.
+ */
+ protected void handleForbidden(IBaseBinary theBinary) {
+ throw new ForbiddenOperationException(Msg.code(2369) + "Security context not permitted");
+ }
+
+ /**
+ * Determines whether the current user has access to the given security
+ * context identifier. This method is intended to be overridden, the default
+ * implementation simply always returns false
.
+ *
+ * @param theSecurityContextSystem The Binary.securityContext.identifier.system
value
+ * @param theSecurityContextValue The Binary.securityContext.identifier.value
value
+ * @param theRequestDetails The request details associated with this request
+ * @return Returns true
if the request should be permitted, and false
otherwise
+ */
+ protected boolean securityContextIdentifierAllowed(String theSecurityContextSystem, String theSecurityContextValue, RequestDetails theRequestDetails) {
+ return false;
+ }
+
+}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/OffsetCalculator.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/OffsetCalculator.java
index 4c73a37ddd8..fa74b6a17f8 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/OffsetCalculator.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/OffsetCalculator.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
package ca.uhn.fhir.rest.server.method;
import ca.uhn.fhir.rest.api.Constants;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/RequestedPage.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/RequestedPage.java
index 8aea1613e34..d182f13f327 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/RequestedPage.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/RequestedPage.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
package ca.uhn.fhir.rest.server.method;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleBuilder.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleBuilder.java
index 818d47bdf35..cb9b53bc89a 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleBuilder.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleBuilder.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
package ca.uhn.fhir.rest.server.method;
import ca.uhn.fhir.i18n.Msg;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleRequest.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleRequest.java
index 9b7c1bcfb12..9deb8c41e50 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleRequest.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponseBundleRequest.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
package ca.uhn.fhir.rest.server.method;
import ca.uhn.fhir.model.api.Include;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponsePage.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponsePage.java
index d36823c9cfd..b9c91944ba1 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponsePage.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResponsePage.java
@@ -1,3 +1,22 @@
+/*-
+ * #%L
+ * HAPI FHIR - Server Framework
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
package ca.uhn.fhir.rest.server.method;
import org.hl7.fhir.instance.model.api.IBaseResource;
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
index ce6320bf3cf..53389434d47 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
index e6b33f740a4..70d87d89be7 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
@@ -21,7 +21,7 @@
ca.uhn.hapi.fhir
hapi-fhir-caching-api
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
index 9335c0a9417..6029099b749 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
index b0a4b034bcb..e34a90f51e4 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir
ca.uhn.hapi.fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../pom.xml
diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml
index 030afbf06eb..9dde28f71f5 100644
--- a/hapi-fhir-serviceloaders/pom.xml
+++ b/hapi-fhir-serviceloaders/pom.xml
@@ -5,7 +5,7 @@
hapi-deployable-pom
ca.uhn.hapi.fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
index 90ce7c41cc1..7d55b61309f 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
index 7b2768e3b06..43296a0974a 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
hapi-fhir-spring-boot-sample-client-apache
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
index 2a1ad54b5a0..dbe4dd12825 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
index c7572bb43a5..869578e75b8 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
index 1ef53facc77..1726a6924b7 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
index fb0e7899832..6a9fe7b3373 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index e91f6248bf1..25cca312042 100644
--- a/hapi-fhir-spring-boot/pom.xml
+++ b/hapi-fhir-spring-boot/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml
index 81fc6daba2c..db845a342e1 100644
--- a/hapi-fhir-sql-migrate/pom.xml
+++ b/hapi-fhir-sql-migrate/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml
index 5a3fcc03db1..4744b8f78a7 100644
--- a/hapi-fhir-storage-batch2-jobs/pom.xml
+++ b/hapi-fhir-storage-batch2-jobs/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/WriteBinaryStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/WriteBinaryStep.java
index fd06677bc9a..59071628dad 100644
--- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/WriteBinaryStep.java
+++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/WriteBinaryStep.java
@@ -25,6 +25,8 @@ import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.batch2.jobs.export.models.BulkExportBinaryFileId;
+import ca.uhn.fhir.context.FhirVersionEnum;
+import ca.uhn.fhir.jpa.util.RandomTextUtils;
import ca.uhn.fhir.rest.api.server.bulk.BulkExportJobParameters;
import ca.uhn.fhir.batch2.jobs.export.models.ExpandedResourcesList;
import ca.uhn.fhir.context.FhirContext;
@@ -36,8 +38,12 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.BinaryUtil;
+import ca.uhn.fhir.util.FhirTerser;
+import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
@@ -50,6 +56,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.slf4j.LoggerFactory.getLogger;
public class WriteBinaryStep implements IJobStepWorker {
@@ -107,13 +114,45 @@ public class WriteBinaryStep implements IJobStepWorker binaryCaptor = ArgumentCaptor.forClass(IBaseBinary.class);
ArgumentCaptor binaryDaoCreateRequestDetailsCaptor = ArgumentCaptor.forClass(SystemRequestDetails.class);
verify(binaryDao)
- .create(binaryCaptor.capture(), binaryDaoCreateRequestDetailsCaptor.capture());
+ .update(binaryCaptor.capture(), binaryDaoCreateRequestDetailsCaptor.capture());
String outputString = new String(binaryCaptor.getValue().getContent());
// post-pending a \n (as this is what the binary does)
String expected = String.join("\n", stringified) + "\n";
diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml
index 7dd205ad68d..b031de1491c 100644
--- a/hapi-fhir-storage-batch2-test-utilities/pom.xml
+++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml
index 8ae1a897b88..386bff231ae 100644
--- a/hapi-fhir-storage-batch2/pom.xml
+++ b/hapi-fhir-storage-batch2/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml
index 06af52b822d..82464aebd02 100644
--- a/hapi-fhir-storage-cr/pom.xml
+++ b/hapi-fhir-storage-cr/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml
index 91e5fafe815..d43db7bba52 100644
--- a/hapi-fhir-storage-mdm/pom.xml
+++ b/hapi-fhir-storage-mdm/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml
index 489a3b70706..a96661518bf 100644
--- a/hapi-fhir-storage-test-utilities/pom.xml
+++ b/hapi-fhir-storage-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml
index 321ccc0061a..7e0671ba447 100644
--- a/hapi-fhir-storage/pom.xml
+++ b/hapi-fhir-storage/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/binary/svc/BaseBinaryStorageSvcImpl.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/binary/svc/BaseBinaryStorageSvcImpl.java
index e69c7f38f51..6848f1bbdf8 100644
--- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/binary/svc/BaseBinaryStorageSvcImpl.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/binary/svc/BaseBinaryStorageSvcImpl.java
@@ -25,6 +25,7 @@ import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.binary.api.IBinaryStorageSvc;
+import ca.uhn.fhir.jpa.util.RandomTextUtils;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.PayloadTooLargeException;
@@ -59,8 +60,6 @@ public abstract class BaseBinaryStorageSvcImpl implements IBinaryStorageSvc {
public static long DEFAULT_MAXIMUM_BINARY_SIZE = Long.MAX_VALUE - 1;
public static String BLOB_ID_PREFIX_APPLIED = "blob-id-prefix-applied";
- private final SecureRandom myRandom;
- private final String CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
private final int ID_LENGTH = 100;
private long myMaximumBinarySize = DEFAULT_MAXIMUM_BINARY_SIZE;
private int myMinimumBinarySize;
@@ -72,7 +71,7 @@ public abstract class BaseBinaryStorageSvcImpl implements IBinaryStorageSvc {
public BaseBinaryStorageSvcImpl() {
- myRandom = new SecureRandom();
+ super();
}
@Override
@@ -98,12 +97,7 @@ public abstract class BaseBinaryStorageSvcImpl implements IBinaryStorageSvc {
@Override
public String newBlobId() {
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < ID_LENGTH; i++) {
- int nextInt = Math.abs(myRandom.nextInt());
- b.append(CHARS.charAt(nextInt % CHARS.length()));
- }
- return b.toString();
+ return RandomTextUtils.newSecureRandomAlphaNumericString(ID_LENGTH);
}
/**
diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/util/RandomTextUtils.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/util/RandomTextUtils.java
new file mode 100644
index 00000000000..adf7215f92c
--- /dev/null
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/util/RandomTextUtils.java
@@ -0,0 +1,41 @@
+/*-
+ * #%L
+ * HAPI FHIR Storage api
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package ca.uhn.fhir.jpa.util;
+
+import java.security.SecureRandom;
+
+public class RandomTextUtils {
+
+ private static final SecureRandom ourRandom = new SecureRandom();
+ private static final String ALPHANUMERIC_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ /**
+ * Creates a new string using randomly selected characters (using a secure random
+ * PRNG) containing letters (mixed case) and numbers.
+ */
+ public static String newSecureRandomAlphaNumericString(int theLength) {
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < theLength; i++) {
+ int nextInt = Math.abs(ourRandom.nextInt());
+ b.append(ALPHANUMERIC_CHARS.charAt(nextInt % ALPHANUMERIC_CHARS.length()));
+ }
+ return b.toString();
+ }
+}
diff --git a/hapi-fhir-storage/src/test/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptorTest.java b/hapi-fhir-storage/src/test/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptorTest.java
new file mode 100644
index 00000000000..ff3529bf8d8
--- /dev/null
+++ b/hapi-fhir-storage/src/test/java/ca/uhn/fhir/rest/server/interceptor/binary/BinarySecurityContextInterceptorTest.java
@@ -0,0 +1,211 @@
+package ca.uhn.fhir.rest.server.interceptor.binary;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.MethodOutcome;
+import ca.uhn.fhir.rest.api.server.IBundleProvider;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException;
+import ca.uhn.fhir.test.utilities.server.HashMapResourceProviderExtension;
+import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
+import org.hl7.fhir.r4.model.Binary;
+import org.hl7.fhir.r4.model.Patient;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+class BinarySecurityContextInterceptorTest {
+
+
+ private static final FhirContext ourCtx = FhirContext.forR4Cached();
+ @RegisterExtension
+ @Order(0)
+ public static final RestfulServerExtension ourServer = new RestfulServerExtension(ourCtx)
+ .registerInterceptor(new HeaderBasedBinarySecurityContextInterceptor(ourCtx));
+ @RegisterExtension
+ @Order(1)
+ public static final HashMapResourceProviderExtension ourBinaryProvider = new HashMapResourceProviderExtension<>(ourServer, Binary.class);
+ @RegisterExtension
+ @Order(1)
+ public static final HashMapResourceProviderExtension ourPatientProvider = new HashMapResourceProviderExtension<>(ourServer, Patient.class);
+
+ @Test
+ void testRead_SecurityContextIdentifierPresent_RequestAllowedByInterceptor() {
+ storeBinaryWithSecurityContextIdentifier();
+
+ Binary actual = ourServer
+ .getFhirClient()
+ .read()
+ .resource(Binary.class)
+ .withId("A")
+ .withAdditionalHeader(HeaderBasedBinarySecurityContextInterceptor.X_SECURITY_CONTEXT_ALLOWED_IDENTIFIER, "http://foo|bar")
+ .execute();
+ assertEquals("A", actual.getIdElement().getIdPart());
+ assertEquals("http://foo", actual.getSecurityContext().getIdentifier().getSystem());
+ }
+
+ @Test
+ void testRead_SecurityContextIdentifierPresent_SystemRequestDetailsPermitted() {
+ storeBinaryWithSecurityContextIdentifier();
+
+ IBundleProvider results = ourBinaryProvider.searchAll(new SystemRequestDetails());
+ assertEquals(1, results.sizeOrThrowNpe());
+ }
+
+ @Test
+ void testRead_SecurityContextIdentifierPresent_RequestBlockedByInterceptor() {
+ storeBinaryWithSecurityContextIdentifier();
+
+ try {
+ ourServer
+ .getFhirClient()
+ .read()
+ .resource(Binary.class)
+ .withId("A")
+ .execute();
+ fail();
+ } catch (ForbiddenOperationException e) {
+ assertEquals("HTTP 403 Forbidden: HAPI-2369: Security context not permitted", e.getMessage());
+ }
+ }
+
+ @Test
+ void testRead_SecurityContextIdentifierNotPresent() {
+ storeBinaryWithoutSecurityContext();
+
+ Binary actual = ourServer
+ .getFhirClient()
+ .read()
+ .resource(Binary.class)
+ .withId("A")
+ .execute();
+ assertEquals("A", actual.getIdElement().getIdPart());
+ assertNull(actual.getSecurityContext().getIdentifier().getSystem());
+ }
+
+ @Test
+ void testRead_NonBinaryResource() {
+ Patient patient = new Patient();
+ patient.setId("Patient/A");
+ patient.setActive(true);
+ ourPatientProvider.store(patient);
+
+ Patient actual = ourServer
+ .getFhirClient()
+ .read()
+ .resource(Patient.class)
+ .withId("A")
+ .execute();
+ assertEquals("A", actual.getIdElement().getIdPart());
+ assertTrue(actual.getActive());
+ }
+
+
+
+
+
+ @Test
+ void testUpdate_SecurityContextIdentifierPresent_RequestAllowedByInterceptor() {
+ storeBinaryWithSecurityContextIdentifier();
+
+ Binary newBinary = new Binary();
+ newBinary.setId("Binary/A");
+ newBinary.setContentType("text/plain");
+
+ MethodOutcome outcome = ourServer
+ .getFhirClient()
+ .update()
+ .resource(newBinary)
+ .withAdditionalHeader(HeaderBasedBinarySecurityContextInterceptor.X_SECURITY_CONTEXT_ALLOWED_IDENTIFIER, "http://foo|bar")
+ .execute();
+ assertEquals(2L, outcome.getId().getVersionIdPartAsLong());
+ }
+
+ @Test
+ void testUpdate_SecurityContextIdentifierPresent_RequestBlockedByInterceptor() {
+ storeBinaryWithSecurityContextIdentifier();
+
+ try {
+ Binary newBinary = new Binary();
+ newBinary.setId("Binary/A");
+ newBinary.setContentType("text/plain");
+
+ ourServer
+ .getFhirClient()
+ .update()
+ .resource(newBinary)
+ .execute();
+ fail();
+ } catch (ForbiddenOperationException e) {
+ assertEquals("HTTP 403 Forbidden: HAPI-2369: Security context not permitted", e.getMessage());
+ }
+ }
+
+
+ private void storeBinaryWithoutSecurityContext() {
+ Binary binary = new Binary();
+ binary.setId("Binary/A");
+ binary.setContentType("text/plain");
+ ourBinaryProvider.store(binary);
+ }
+
+ /**
+ * This class also exists in hapi-fhir-docs - Make sure any changes here
+ * are reflected there too!
+ */
+ private void storeBinaryWithSecurityContextIdentifier() {
+ Binary binary = new Binary();
+ binary.setId("Binary/A");
+ binary.getSecurityContext().getIdentifier().setSystem("http://foo");
+ binary.getSecurityContext().getIdentifier().setValue("bar");
+ ourBinaryProvider.store(binary);
+ }
+
+
+ /**
+ * This class also exists in hapi-fhir-docs - Update it there too if this changes!
+ */
+ public static class HeaderBasedBinarySecurityContextInterceptor extends BinarySecurityContextInterceptor {
+
+ /**
+ * Header name
+ */
+ public static final String X_SECURITY_CONTEXT_ALLOWED_IDENTIFIER = "X-SecurityContext-Allowed-Identifier";
+
+ /**
+ * Constructor
+ *
+ * @param theFhirContext The FHIR context
+ */
+ public HeaderBasedBinarySecurityContextInterceptor(FhirContext theFhirContext) {
+ super(theFhirContext);
+ }
+
+ /**
+ * This method should be overridden in order to determine whether the security
+ * context identifier is allowed for the user.
+ *
+ * @param theSecurityContextSystem The Binary.securityContext.identifier.system
value
+ * @param theSecurityContextValue The Binary.securityContext.identifier.value
value
+ * @param theRequestDetails The request details associated with this request
+ */
+ @Override
+ protected boolean securityContextIdentifierAllowed(String theSecurityContextSystem, String theSecurityContextValue, RequestDetails theRequestDetails) {
+
+ // In our simple example, we will use an incoming header called X-SecurityContext-Allowed-Identifier
+ // to determine whether the security context is allowed. This is typically not what you
+ // would want, since this is trusting the client to tell us what they are allowed
+ // to see. You would typically verify an access token or user session with something
+ // external, but this is a simple demonstration.
+ String actualHeaderValue = theRequestDetails.getHeader(X_SECURITY_CONTEXT_ALLOWED_IDENTIFIER);
+ String expectedHeaderValue = theSecurityContextSystem + "|" + theSecurityContextValue;
+ return expectedHeaderValue.equals(actualHeaderValue);
+ }
+ }
+
+}
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index c2d0719bc90..33b3d164c26 100644
--- a/hapi-fhir-structures-dstu2.1/pom.xml
+++ b/hapi-fhir-structures-dstu2.1/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index 5f9dbded75d..222ae8ac461 100644
--- a/hapi-fhir-structures-dstu2/pom.xml
+++ b/hapi-fhir-structures-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index 268c7d9a211..1135a07bde4 100644
--- a/hapi-fhir-structures-dstu3/pom.xml
+++ b/hapi-fhir-structures-dstu3/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index b39917b48ec..24f0c9cff63 100644
--- a/hapi-fhir-structures-hl7org-dstu2/pom.xml
+++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index 654db47d7f2..aceafa7fabe 100644
--- a/hapi-fhir-structures-r4/pom.xml
+++ b/hapi-fhir-structures-r4/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml
index 3fcc2179bf1..f385d30beff 100644
--- a/hapi-fhir-structures-r4b/pom.xml
+++ b/hapi-fhir-structures-r4b/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index da17ed839de..99fec65d69a 100644
--- a/hapi-fhir-structures-r5/pom.xml
+++ b/hapi-fhir-structures-r5/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index 824c105079e..f92b5808e6f 100644
--- a/hapi-fhir-test-utilities/pom.xml
+++ b/hapi-fhir-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index 9a2018d38e6..66ede12e4d5 100644
--- a/hapi-fhir-testpage-overlay/pom.xml
+++ b/hapi-fhir-testpage-overlay/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index a61fa01a48b..1134b80d5c4 100644
--- a/hapi-fhir-validation-resources-dstu2.1/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index 57f4daf36cf..a0dc6aa9e62 100644
--- a/hapi-fhir-validation-resources-dstu2/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index 58ac108727c..b43d9b02d12 100644
--- a/hapi-fhir-validation-resources-dstu3/pom.xml
+++ b/hapi-fhir-validation-resources-dstu3/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index a4a2988a161..bcda02cf979 100644
--- a/hapi-fhir-validation-resources-r4/pom.xml
+++ b/hapi-fhir-validation-resources-r4/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml
index ffb780fa9d6..55dccb925a9 100644
--- a/hapi-fhir-validation-resources-r4b/pom.xml
+++ b/hapi-fhir-validation-resources-r4b/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml
index 8a36a9652f4..dc3df50b4d1 100644
--- a/hapi-fhir-validation-resources-r5/pom.xml
+++ b/hapi-fhir-validation-resources-r5/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index 07f6ffcb351..ab536f6d8de 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index f0299d9fbb9..3be18c17a0a 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index 9059b10857a..4eacff61eff 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 08ced3c838f..b9beb1a64d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
HAPI-FHIR
An open-source implementation of the FHIR specification in Java.
diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
index 6e03ace49e4..86e8fb17ff1 100644
--- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
+++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
index aa4e15d0064..7f9e5b50e20 100644
--- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
index 6d3fc67bcdd..6910d86f677 100644
--- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.7.11-SNAPSHOT
+ 6.7.12-SNAPSHOT
../../pom.xml