From 3bf69ddcaac62328f8e5ddd1fff7122e7b6175dd Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Wed, 8 Nov 2023 17:35:23 -0500 Subject: [PATCH 1/2] Fix #1039: Make client certificate mapper support Spring Boot 3 * let it choose v2 of the jar when SB3 is detected * otherwise, continue as before with default v1 --- config/client_certificate_mapper.yml | 5 +++- docs/framework-client_certificate_mapper.md | 15 +++++++--- .../framework/client_certificate_mapper.rb | 21 +++++++++++++ .../client_certificate_mapper_spec.rb | 30 +++++++++++++++++++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index a306eaba03..6be2855709 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -16,4 +16,7 @@ # Container security provider configuration --- version: 1.+ -repository_root: "{default.repository.root}/client-certificate-mapper" +version_lines: + - 2.+ +repository_root: "https://anthonydahanne.github.io/java-buildpack-client-certificate-mapper" +javax_forced: false \ No newline at end of file diff --git a/docs/framework-client_certificate_mapper.md b/docs/framework-client_certificate_mapper.md index 1927985803..4e2c52c8ec 100644 --- a/docs/framework-client_certificate_mapper.md +++ b/docs/framework-client_certificate_mapper.md @@ -1,6 +1,11 @@ # Client Certificate Mapper -The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute. +The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax|jakarta.servlet.request.X509Certificate` Servlet attribute. +The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot applications classpath. + +If the app you're deploying is using Spring Boot 2 or earlier, the latest 1.x version (`javax` support) from [the listing][this listing] will be downloaded. + +If the app you're deploying is using Spring Boot 3, the latest 2.x version (`jakarta` support) from [the listing][this listing] will be downloaded. @@ -18,10 +23,11 @@ For general information on configuring the buildpack, including how to specify c The framework can be configured by modifying the [`config/client_certificate_mapper.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. -| Name | Description -| ---- | ----------- +| Name | Description +|-------------------| ----------- | `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). -| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. +| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. +| `javax_forced` | You can force the download of the v1.x version of the [library][library repository] which is based on `javax` naming. ## Servlet Filter The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute for each request. The `X-Forwarded-Client-Cert` header is contributed by the Cloud Foundry Router and contains the any TLS certificate presented by a client for mututal TLS authentication. This certificate can then be used by any standard Java security framework to establish authentication and authorization for a request. @@ -32,3 +38,4 @@ The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert [Servlet Filter]: https://github.com/cloudfoundry/java-buildpack-client-certificate-mapper [this listing]: http://download.pivotal.io.s3.amazonaws.com/container-security-provider/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering +[library repository]: https://github.com:cloudfoundry/java-buildpack-client-certificate-mapper.git diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index 599d3a6ba2..d92da14a22 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -17,15 +17,28 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/spring_boot_utils' module JavaBuildpack module Framework # Encapsulates the functionality for contributing an mTLS client certificate mapper to the application. class ClientCertificateMapper < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + def initialize(context) + @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new + @configuration = context[:configuration] + super(context) + end # (see JavaBuildpack::Component::BaseComponent#compile) def compile + if spring_boot_3? && !@configuration['javax_forced'] + spring_boot_3_configuration = @configuration + spring_boot_3_configuration['version'] = '2.+' + @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, spring_boot_3_configuration) + end download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) end @@ -42,6 +55,14 @@ def supports? true end + private + + def spring_boot_3? + # print '@application.details: ' + @application.details.to_s + @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= + Gem::Version.new('3.0.0') + end + end end diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index 37120b3709..3f52001de7 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -33,6 +33,36 @@ expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # version was not patched by the compile step + expect(configuration).to eq({}) + end + + + it 'configures client certificate mapper to download version 2.+ during compile of spring boot 3 app', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.compile + + expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # version of the dep. was forced to 2.+ by the compile step, because Spring Boot 3 was found + expect(configuration).to eq({ 'version' => '2.+' }) + end + + context 'user forced javax to be used' do + let(:configuration) { { 'javax_forced' => true } } + it 'configures client certificate mapper to download version 1 during compile of spring boot 3 app ', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.compile + + expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # user prevented version 2.+, forcing javax + expect(configuration).to eq({ 'javax_forced' => true }) + end end it 'adds the jar to the additional libraries during release', From f9b4a20df6c24c1a979f317bce927ad672e3d149 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Thu, 14 Dec 2023 11:05:51 -0500 Subject: [PATCH 2/2] Fix cloudfoundry#1039 Make client certificate mapper support Jakarta EE; using a single library that can support SB2, SB3, JEE and JakartaEE apps --- config/client_certificate_mapper.yml | 5 ++-- docs/framework-client_certificate_mapper.md | 6 +--- .../framework/client_certificate_mapper.rb | 21 ------------- .../client_certificate_mapper_spec.rb | 30 ------------------- 4 files changed, 3 insertions(+), 59 deletions(-) diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index 6be2855709..e32fbedc82 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -15,8 +15,7 @@ # Container security provider configuration --- -version: 1.+ +version: 2.+ version_lines: - 2.+ -repository_root: "https://anthonydahanne.github.io/java-buildpack-client-certificate-mapper" -javax_forced: false \ No newline at end of file +repository_root: "{default.repository.root}/client-certificate-mapper" \ No newline at end of file diff --git a/docs/framework-client_certificate_mapper.md b/docs/framework-client_certificate_mapper.md index 4e2c52c8ec..5d3852b5a6 100644 --- a/docs/framework-client_certificate_mapper.md +++ b/docs/framework-client_certificate_mapper.md @@ -1,11 +1,8 @@ # Client Certificate Mapper The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax|jakarta.servlet.request.X509Certificate` Servlet attribute. -The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot applications classpath. +The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot (2 and 3), as well as JEE / JakartaEE applications classpath with a servlet filter. -If the app you're deploying is using Spring Boot 2 or earlier, the latest 1.x version (`javax` support) from [the listing][this listing] will be downloaded. - -If the app you're deploying is using Spring Boot 3, the latest 2.x version (`jakarta` support) from [the listing][this listing] will be downloaded.
Detection Criterion
@@ -27,7 +24,6 @@ The framework can be configured by modifying the [`config/client_certificate_map |-------------------| ----------- | `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). | `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. -| `javax_forced` | You can force the download of the v1.x version of the [library][library repository] which is based on `javax` naming. ## Servlet Filter The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute for each request. The `X-Forwarded-Client-Cert` header is contributed by the Cloud Foundry Router and contains the any TLS certificate presented by a client for mututal TLS authentication. This certificate can then be used by any standard Java security framework to establish authentication and authorization for a request. diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index d92da14a22..599d3a6ba2 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -17,28 +17,15 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' -require 'java_buildpack/util/spring_boot_utils' module JavaBuildpack module Framework # Encapsulates the functionality for contributing an mTLS client certificate mapper to the application. class ClientCertificateMapper < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Util - - def initialize(context) - @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new - @configuration = context[:configuration] - super(context) - end # (see JavaBuildpack::Component::BaseComponent#compile) def compile - if spring_boot_3? && !@configuration['javax_forced'] - spring_boot_3_configuration = @configuration - spring_boot_3_configuration['version'] = '2.+' - @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, spring_boot_3_configuration) - end download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) end @@ -55,14 +42,6 @@ def supports? true end - private - - def spring_boot_3? - # print '@application.details: ' + @application.details.to_s - @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= - Gem::Version.new('3.0.0') - end - end end diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index 3f52001de7..37120b3709 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -33,36 +33,6 @@ expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # version was not patched by the compile step - expect(configuration).to eq({}) - end - - - it 'configures client certificate mapper to download version 2.+ during compile of spring boot 3 app', - app_fixture: 'framework_java_cf_boot_3', - cache_fixture: 'stub-client-certificate-mapper.jar' do - - component.compile - - expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist - expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # version of the dep. was forced to 2.+ by the compile step, because Spring Boot 3 was found - expect(configuration).to eq({ 'version' => '2.+' }) - end - - context 'user forced javax to be used' do - let(:configuration) { { 'javax_forced' => true } } - it 'configures client certificate mapper to download version 1 during compile of spring boot 3 app ', - app_fixture: 'framework_java_cf_boot_3', - cache_fixture: 'stub-client-certificate-mapper.jar' do - - component.compile - - expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist - expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # user prevented version 2.+, forcing javax - expect(configuration).to eq({ 'javax_forced' => true }) - end end it 'adds the jar to the additional libraries during release',
Detection Criterion