Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1.0.0-RC1 #38
1.0.0-RC1 #38
Changes from all commits
89d4d07
700bc7d
c9e8c89
d365501
361608c
c4e9255
63c0f4d
b7f7cdc
a5efb63
d218664
4026c0e
7d23988
341f379
45f20f0
e63854f
bf3500b
4ac9a26
32a71da
1e75109
33729db
e9f81b3
2a29811
e9936ca
6f363c1
06c493b
9de2940
53b2fc7
89f1bd8
e659146
08fbb92
b2b6358
1f6c275
aad00c2
a2a4171
6f6a100
91d94b0
e30dec7
a9214a1
c3f18d8
a375fe1
e0d860c
d8eac94
6136d39
a92b4e9
3a9ccd6
79f5978
311b90d
3ecdc4e
6a979c4
1044e28
c13910b
ffdd491
e334dd5
e51c275
a370683
e159ea0
f84b65f
3b3f13d
944bb0b
31bece5
c73e80f
efbe465
cf416ca
f4ee8d4
4c1178f
c855208
f2129f8
0fe1897
40147d4
09dfd9c
4217069
e7dda13
9e29e44
7b9a0e3
533497a
47b0f5e
da1f032
415d3da
d27a96f
b20b7dd
fd62cf6
0b13991
76bb8a0
8c218fb
3f4f650
ba51428
07ea7fd
3bb5bf0
6677769
bf14e3e
e8365c4
24b0810
c208696
a1bf839
bcf2e9c
651872d
90de471
553abab
692a531
4da3789
f9f159f
d71be9b
5876127
6b8bdb5
1f953a8
00fe1b8
79e6727
e49b967
223217e
4adfe97
4ed6b92
8121349
0ed69bd
43868d8
711e139
23da33e
94ba7c3
d1af928
2e2e328
be1ec88
ce50def
a2e1650
2480a5e
563e747
6c02a1d
a259d80
604718e
0d3b9d7
530492c
422bca1
568c50d
5cde849
1b82bc4
10d6765
81e111d
0b65731
776a540
0f6fb60
2a99975
6f7c02f
acab8ba
4044dbe
a9b6703
e96510a
7cbea90
ea5d214
8c0573b
12f2f8c
f3aec80
8193d43
cb875f5
4f60997
1801f40
ab70da3
3b13852
43046ed
8713b45
c24a7d9
ef4cbfd
e0259ea
126a312
e3829db
7870cad
2498fa7
a2cf555
b8bf510
a96a456
e9b07ed
376f876
58dd84d
0321914
fcd9931
d1fd5e1
0662e26
5c29be9
d222b58
9ce7c1c
b47dfa5
d4881b1
e480449
f45945b
fe2fe82
7cea850
edafaa0
0f92a66
50b3bb1
0e0f729
3a01b43
855c3ce
2afbb49
e36e5dd
0a4f555
d38402d
3aeb1ae
2aa969d
b1ab11d
d43e0fc
216d582
2155ffc
95c63ba
e90bca0
9c426b7
fc6573b
4d1c85b
7f43939
eccab43
45b87d5
b26bbfa
4ef1bb1
85a0adc
d409a60
5b2fec7
60d4319
8467e7d
32a8ab1
00a46c4
a0c8ff2
fba4fd7
8add6f4
f9f4fbd
cb40dc1
c3a8295
f19980d
0be4f02
e53ab7b
e4aec60
ed1706e
c5822f7
38f5344
b850024
610ff4e
d9234e4
4463117
75b9260
80a7e20
04749d6
4de5727
c7323a5
e961432
f38f1ac
879b889
7bbaaf9
7b4e767
546a227
25f7351
4ab43d4
6bf313e
d34952f
68142a2
de3a49a
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
eng-lollipop-consumer-java-sdk
This repository contains the code that composes the
eng-lollipop-consumer-java-sdk
, containing the features to enable a LolliPoP validation inside a Consumer project using the JVM environment. It contains:Modules
The repository contains the following Gradle modules, to be used within other projects:
Samples
Use the SDK as dependency
The gradle modules contained in the repository (except the sources contained in the
sample
directory) will be available on GitHub Packages. In order to include a dependency, use the Maven dependencyOr, in Gradle:
Where
MODULE_NAME
is one of the modules to be used for the SDK (Described in the paragraph above), andRELEASE_VERSION
is the version available on GitHub Packages (or the version installed locally).Local Installation
Prerequisites
In order to work with the
eng-lollipop-consumer-java-sdk
locally the following are required to be installed:JDK 11
Gradle 7.4+
Maven Dependencies
In order to use maven it is required to have it installed locally, suggested to have it at least on version
3.8.5+
.Github Packages Dependencies
This library uses some dependencies available through GitHub Packages. It is required to have the following information, in order to obtain them:
gpr.user
project property, or theGITHUB_ACTOR
environment variable, containing the GitHub handle to be used for package recoverygpr.key
project property, or theGITHUB_TOKEN
environment variable, containing the GitHub token to be used for package recovery. The token must contain the permissions to retrieve GitHub Packages. See the Official GuidelinesBuild Locally
In order to build the library source locally it is suggested to run the
.\gradlew build --refresh-dependecies
. Ensure that the properties regarding GitHub credentials have been defined beforehand.Metadata Verification
This repository uses the Gradle verification process on dependency checksums, using the file provided under
gradle\verification-metadata.xml
. Whenever the dependency check does exit with a failure locally, it might be necessary to update the file. Gradle does provide the command.\gradlew --write-verification-metadata [algorithm] help
where the algorithm could be sha256, or whenever it is not available for a particular dependency sha1. An already known problem with the verification process and file update may not intercept all internal dependencies, obtaining a different result from the automated checks within the GitHub workflow. Whenever an update is required, and the provided cli command does not automatically update the file, it is required to introduce the checksum values manually. See the official Gradle Docs for troubleshooting of the metadata verification.Publish to Maven local repository
In order to publish the modules on the local maven repository the command to be used is
.\gradlew publishToMavenLocal
Native Build
In order to compile the modules contained in this repository in a native form, the graalvm plugin is applied. In order to execute a native build it is required that an instance of the GraalVM JDK is installed and configured.
In order to compile natively execute this command:
.\gradlew nativeCompile
The result will be found under the module
build/native
directory.Note that currently a native version of the SDK is not automatically published on the GitHub Package.
Utilization
Configurations
The core module contains defined parameters to configure the provided services. Within each of the configuration classes provided in this module, that are not directly related to an implementation of a specific library or framework does not contain any functionality for property loading. The choice of the preferred method to apply the configuration properties is defined by the library user. The configuration classes are defined as follows:
LollipopConsumerRequestConfig
This configuration class contains the standard configuration properties for the SDK core functionalities:
AssertionStorageConfig
This configuration contains the standard properties regarding the storage interface for the SAML Assertion data:
IdpCertStorageConfig
This configuration contains the standard properties regarding the storage interface for the IdP certificates:
Other Configs
Inside the modules with the default implementations of the core interfaces regarding storage, rest clients and signature validation functionalities, are contained configuration classes specific for the provided implementations, the description of which are defined in the respective Readme files.
Implementations Usage
Each service inside the core SDK is defined by an interface and a related Factory to generate an instance of the service, using the related configurations. The repository contains default implementations for each one of the interfaces to be used. The following steps should be followed to ensure the usage of the SDK:
LollipopConsumerRequestConfig
The baseline for the SDK configuration is in this configuration class. As for any of the config files within the core SDK there is no reference to a particular method to be used for loading properties from an external source, leaving the possibility and responsibility to implement a proper loading method in the service utilizing the library (See for example the SpringLollipopConsumerRequestConfig extension, using annotations to load properties from the application context).
Whenever is required to define a new instance of the configuration class programmatically, it may be used a builder to setup the required parameters to be changed (not that otherwise the default values are applied):
Having defined the general configuration we can initialize the single instances of services (or related factories) to be used in the validation process.
HttpMessageVerifierFactory
An instance of the service to be used in order to verify the content digest and signatures related to the http request, through an implementation of the HttpMessageVerifier interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the message verifier.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory. In order to initialize the factory the lollipopConsumerRequestConfig is required, as well as the value of the expected encoding. Note that the latter does not have a specific configuration file:
LollipopConsumerRequestValidationService
An instance of this service is used to apply formal validation a LollipopConsumerRequest instance. In order to use the provided implementation lollipopConsumerRequestConfig is required, as it is used to search for the headers using the name defined in the configuration class. We may define a new validation service as follows:
LollipopLoggerServiceFactory
An instance of the LollipopLoggerService is used to apply a form of logging in pre-defined portions of the SDK core services, in order to audit request validations, and if enabled the retrieval of Assertions and IdP Cert Data. The standard library does provide a factory interface to be used for the creation of a particular instance of the logger service.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory, using a standard logback implementation. In order to initialize the factory use the following snippet:
The SDK provides a default.xml logback include, as well as a default logback.xml file. The default may be used as a portion of other logback configuration, as an example see the spring implementation default logback-spring.xml.
AssertionStorageProvider
An instance of the service to be used in order to enable the possibility to retrieve or store already recovered SAML Assertions from a cache or storage, through an implementation of the AssertionStorage interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the storage.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface, using an instance of the StorageConfig class (described in the configuration paragraph):
The repository provides a standard implementation of the service, and related factory. that defines a simple in-memory cache storage for limited use, in order to initialize it, it is required to use the SimpleAssertionStorageProvider.
IdpCertStorageProvider
An instance of the service to be used in order to enable the possibility to retrieve or store already recovered IdP Certificates from a cache or storage, through an implementation of the IdpCertStorage interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the storage.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface, using an instance of the IdpCertStorageConfig class (described in the configuration paragraph):
The repository provides a standard implementation of the service, and related factory. that defines a simple in-memory cache storage for limited use, in order to initialize it, it is required to use the SimpleIdpCertStorageProvider.
Note that currently the storage is required only if applied directly to the default provider of IdP certificates data, as it is directly used in the Identity Services implementation. In case other implementations are used, this storage service may not be in use.
AssertionClientProvider
An instance of the service to be used in order to enable the possibility to retrieve SAML Assertions through an implementation of the AssertionClient interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the client.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory, that defines a Rest Client using the available functionalities in the JDK 11 environment, available in the assertion-rest-client-native module.
See the related README.md for further information about the usage of this implementation.
IdpCertSimpleClientProvider
An instance of the service to be used in order to enable the possibility to retrieve IdPCert data through an implementation of the IdpCertClient interface. The standard library does provide a factory interface to be used for the creation of a particular instance of the client.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory, that defines a Rest Client using the available functionalities in the JDK 11 environment, available in the identity-service-rest-client-native module.
See the related README.md for further information about the usage of this implementation.
IdpCertProviderFactory
Once we have defined the necessary services to be used for the retrieval of the IdP certificates, we can use an implementation of the IdpCertProvider interface, in order to provide a transparent functionality inside the SDK library.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory. In order to initialize the factory an instance of the IdpCertClientProvider is required:
AssertionServiceFactory
Once we have defined the necessary services to be used for the retrieval of the SAML Assertion data, we can use an implementation of the AssertionService interface, in order to provide a transparent functionality inside the SDK library.
Whenever the factory helper class is not used and the generation of new instance of the service is required, we may use the following to generate an instance using the factory interface:
The repository provides a standard implementation of the service, and related factory. In order to initialize the factory an instance of the AssertionClientProvider, AssertionStorageProvider, and StorageConfig are required:
AssertionVerifierService
In order to execute a validation of the SAML Assertions starting form a LollipopConsumerRequest an interface of the AssertionVerifierService has to be used.
The standard implementation of this interface expects to have instances of the previously described interfaces, to be used for SAML Assertion retrieval and storage. Whenever we are using the factory helper it is not necessary to directly manage in any part the service startup, as it will be managed by the helper class itsefl if an implementation is missing.
In case it is necessary an instance of the standard implementation of the service can be applied with the following snippet, provided that the required services have been produced by the respective factory methods (or directly):
Factory Helper Startup
The LollipopFactoryHelper is a singleton class to be used by the LollipopCommandBuilder implementation, that provides (and creates if unavailable) the required services, through the provided implementations of the factory classes for the single components. It is not mandatory to be used in order to use the services, if the dependencies are injected using a dedicated library.
It requires an instance of a LollipopConsumerRequestConfig, HttpMessageVerifierFactory, AssertionStorageProvider, IdpCertProviderFactory, AssertionServiceFactory, LollipopLoggerServiceFactory. LollipopConsumerRequestValidationService
And related configs and sub-dependencies defined by the factory implementation.
Example
The following examples provides the complete setup method with default configurations created directly into the method. For a simple usage of the library the following can be used with minimal setup changes in configuration related to the expect origin method and url, and the rest client url to be used for Assertions retrieval. In a normal usage case each factory implementation and related configurations should be treated with an implementation for the related frameworks and libraries used for the application (As an example, defining Beans and configurations within a Spring context, such as in the provided spring-impl module, and within the spring sample):
Execute Validation Command
In order to execute a validation of an instance of LollipopConsumerRequest, after an instance of a LollipopConsumerFactoryHelper we could create an instance of the LollipopCommandBuilder interface as in the following snippet, directly into the execution method, or as the part of the application context (As an example, as a Spring Bean):
With an existing builder we could provide a new instance of a command to execute using the following:
A new LollipopConsumerCommand could be defined without the help of the FactoryHelper and the CommandBuilder, provided instances of an implementation of the required services are available, directly in the class requiring the new instance, or throughout the application context capable of enabling the usage of the @Inject annotations within the implemented command. In the case of a direct creation of a command to execute, use the following:
Defining LollipopRequestCommand instance
In order to define an instance of the LollipopRequestCommand, to be used in the validation process it is required to setup the following parameters:
The following snippet defines the conversion from an HttpServletRequest instance, to a new LollipopConsumerRequest
Using CommandResult instances
Whenever a validation command is executed, a CommandResult will be produced, abstracting the exceptions or validation errors produced by the services regarding the validation process for the http message, and the SAML assertion. The CommandResult has properties indicating:
The following snippet shows an example of how the CommandResult could be used to define the HttpServletRespons status and response body whenever the CommandResult is not ending in a successful state:
Utility classes
LollipopConsumerConverter
Class that implements Javax Servlet library with two utility methods:
convertToLollipopRequest:
interceptResult:
Examples of its usage can be found in the Spring Interceptor.
LollipopTypesafeConfig
Class that implements Lightbend's Config library, used to define configuration parameters.
The class' constructor retrieve from a Config object the parameters that can be used as configuration in the application, if the path to the parameter is not found (it hasn't been configured) a default value will be set.
Examples of its usage can be found in the Simple Typesafe sample, where the Config object is generated with the library's class ConfigFactory using as source for the configuration the sample's application.properties.
Testing
Testing of the repository functionalities is conducted by unit test, integration and e2e testing.
Collecting Test Coverage
This repository contains a module dedicated to collecting the test coverage of all the modules within the repository through the usage of a dedicated gradle plugin.
In order to obtain a centralized report of the repository test coverage, the following command can be used on the test-coverage module:
Afterwards, the report is found at
/test-coverage/build/reports/jacoco/testCodeCoverageReport
.E2E
This repository contains a collection and docker-compose file to be used for the purpose of an integrated testing. See the related README.md for further information.
Generate new Rest Clients
The standard Rest Clients available in the repository are defined without a specific dependency, and relates to the standard services available (For example, the IdP Data Provider is referred to the existing Pagopa Identity Services).
In case a new implementation of the client (for example, using Feign), or one of the clients has a different specification from the one that has been used as a default, a tool may be used to generate the internal structure of the client using OpenApi generation tool or gradle plugin. For the latter the following steps may be used to produce the internals of the Rest Client implementation:
Introduce in your module the following plugin:
id("org.openapi.generator") version "6.5.0"
Afterwards define the following task structure in your module:
Where the
dataLibrary
config option defines the java version to be used, and thelibrary
defines witch implementation to be used. (For examplelibrary: "feign"
will generate a Feign Rest Client).In order to execute the task run the following command:
.\gradlew openApiGenerate
The default openApi specs for the two services already implemented are found in the respective modules under the
openApi
folder.See the OpenAPITools/openapi-generator repository for further information about the generation toolkit.
Having the Rest Client code generated, the output should be introduced inside the expected package within the module, and an instance of the core SDK interfaces should be implemented in order to handle the data retrieval through the generated client.
For example, in order to enable the usage of a new Rest Client regarding the IdP certificates retrieval an implementation of the IdpCertClient and IdpCertClientProvider should be defined. See for reference the IdpCertSimpleClient implementation.