aboutsummaryrefslogtreecommitdiff
path: root/connector
diff options
context:
space:
mode:
Diffstat (limited to 'connector')
-rw-r--r--connector/checks/spotbugs-exclude.xml9
-rw-r--r--connector/pom.xml73
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java7
-rw-r--r--connector/src/main/resources/application.properties4
-rw-r--r--connector/src/main/resources/specific_eIDAS_connector.beans.xml3
-rw-r--r--connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java11
-rw-r--r--connector/src/test/java/at/asitplus/eidas/specific/connector/test/saml2/Pvp2SProfileEndPointTest.java10
-rw-r--r--connector/src/test/java/at/asitplus/eidas/specific/connector/test/task/GenerateCountrySelectionFrameTaskTest.java11
-rw-r--r--connector/src/test/resources/config/application-exectest.properties83
-rw-r--r--connector/src/test/resources/spring/SpringTest_connector.beans.xml2
10 files changed, 179 insertions, 34 deletions
diff --git a/connector/checks/spotbugs-exclude.xml b/connector/checks/spotbugs-exclude.xml
index 281e3796..bb41eb27 100644
--- a/connector/checks/spotbugs-exclude.xml
+++ b/connector/checks/spotbugs-exclude.xml
@@ -24,4 +24,13 @@
<Class name="at.asitplus.eidas.specific.connector.MsSpecificSpringBootApplicationContextInitializer" />
<Bug pattern="PATH_TRAVERSAL_IN" />
</Match>
+ <Match>
+ <!-- Builder pattern does not expose date elements -->
+ <OR>
+ <Class name="at.asitplus.eidas.specific.connector.health.IgniteClusterHealthIndicator" />
+ </OR>
+ <OR>
+ <Bug pattern="EI_EXPOSE_REP2" />
+ </OR>
+ </Match>
</FindBugsFilter>
diff --git a/connector/pom.xml b/connector/pom.xml
index a721930d..dff75c08 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>at.asitplus.eidas</groupId>
<artifactId>ms_specific</artifactId>
- <version>1.2.3-SNAPSHOT</version>
+ <version>1.2.4-SNAPSHOT</version>
</parent>
<groupId>at.asitplus.eidas.ms_specific</groupId>
@@ -33,6 +33,16 @@
<dependency>
<groupId>at.gv.egiz.eaaf</groupId>
<artifactId>eaaf_module_pvp2_idp</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>at.asitplus.eidas.ms_specific</groupId>
@@ -88,6 +98,10 @@
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-to-slf4j</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
@@ -96,6 +110,19 @@
<artifactId>hibernate-validator</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ </dependency>
+
<!-- Testing -->
<dependency>
@@ -126,6 +153,18 @@
<type>test-jar</type>
</dependency>
<dependency>
+ <groupId>at.gv.egiz.eaaf</groupId>
+ <artifactId>eaaf_module_pvp2_sp</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>at.asitplus.eidas.ms_specific.modules</groupId>
+ <artifactId>authmodule-eIDAS-v2</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>test</scope>
@@ -136,29 +175,27 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>mockwebserver</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>com.github.skjolber</groupId>
<artifactId>mockito-soap-cxf</artifactId>
- <scope>test</scope>
- <!--exclusions>
- <exclusion>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-wsdl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-bindings-soap</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-core</artifactId>
- </exclusion>
- </exclusions-->
+ <scope>test</scope>
</dependency>
+
<dependency>
- <groupId>com.squareup.okhttp3</groupId>
- <artifactId>mockwebserver</artifactId>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
index 881eeb8a..e4c68004 100644
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/verification/AuthnRequestValidator.java
@@ -53,6 +53,7 @@ import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils;
import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestPostProcessor;
@@ -211,7 +212,11 @@ public class AuthnRequestValidator implements IAuthnRequestPostProcessor {
} else {
if (el.getAttributeValues() != null && el.getAttributeValues().size() == 1) {
final String transactionId = el.getAttributeValues().get(0).getDOM().getTextContent();
- ((RequestImpl) pendingReq).setUniqueTransactionIdentifier(transactionId);
+ ((RequestImpl) pendingReq).setUniqueTransactionIdentifier(transactionId);
+ log.info("Find transactionId: {} from requesting service. Replace old id: {} ",
+ transactionId, TransactionIdUtils.getTransactionId());
+ TransactionIdUtils.setTransactionId(transactionId);
+
return true;
} else {
diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties
index f66f8e3a..bec125dc 100644
--- a/connector/src/main/resources/application.properties
+++ b/connector/src/main/resources/application.properties
@@ -12,7 +12,9 @@ app.build.artifactId=ms_connector
## SpringBoot Admin client
spring.boot.admin.client.enabled=false
-
+#############################################################################
+## SpringBoot Actuator
+management.endpoints.web.exposure.include=health,info
#############################################################################
diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml
index ec16a7d2..a417a0e5 100644
--- a/connector/src/main/resources/specific_eIDAS_connector.beans.xml
+++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml
@@ -89,7 +89,8 @@
class="at.asitplus.eidas.specific.connector.gui.DefaultVelocityGuiBuilderImpl" />
<bean id="mvcGUIBuilderImpl"
- class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" />
+ class="at.gv.egiz.eaaf.core.impl.gui.builder.SpringMvcGuiFormBuilderImpl" />
+
<bean id="StatusMessageProvider"
class="at.asitplus.eidas.specific.connector.provider.StatusMessageProvider" />
diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
index 4e66d324..893ab4cb 100644
--- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
+++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/FullStartUpAndProcessTest.java
@@ -9,6 +9,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.net.URISyntaxException;
+import java.time.Instant;
import java.util.Map;
import java.util.Timer;
@@ -16,7 +17,6 @@ import javax.xml.transform.TransformerException;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.ignite.Ignition;
-import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
@@ -57,6 +57,7 @@ import at.asitplus.eidas.specific.connector.controller.ProcessEngineSignalContro
import at.asitplus.eidas.specific.connector.controller.Pvp2SProfileEndpoint;
import at.asitplus.eidas.specific.connector.provider.PvpEndPointCredentialProvider;
import at.asitplus.eidas.specific.connector.provider.PvpMetadataProvider;
+import at.asitplus.eidas.specific.connector.test.saml2.Pvp2SProfileEndPointTest;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasSignalServlet;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.EidasAttributeRegistry;
@@ -540,10 +541,10 @@ public class FullStartUpAndProcessTest {
IOException, MarshallingException, ComponentInitializationException {
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
XMLObjectProviderRegistrySupport.getParserPool(),
- FullStartUpAndProcessTest.class.getResourceAsStream("/data/pvp2_authn_1.xml"));
- authnReq.setIssueInstant(DateTime.now());
- RequestAbstractType signedAuthnReq =
- Saml2Utils.signSamlObject(authnReq, credentialProvider.getMessageSigningCredential(), true);
+ Pvp2SProfileEndPointTest.class.getResourceAsStream("/data/pvp2_authn_1.xml"));
+ authnReq.setIssueInstant(Instant.now());
+ RequestAbstractType signedAuthnReq =
+ Saml2Utils.signSamlObject(authnReq, credentialProvider.getMessageSigningCredential(), true);
String b64 = Base64Utils.encodeToString(DomUtils.serializeNode(
XMLObjectSupport.getMarshaller(signedAuthnReq).marshall(signedAuthnReq)).getBytes("UTF-8"));
saml2Req.setParameter("SAMLRequest", b64);
diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/saml2/Pvp2SProfileEndPointTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/saml2/Pvp2SProfileEndPointTest.java
index bcba3e11..6b39bd76 100644
--- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/saml2/Pvp2SProfileEndPointTest.java
+++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/saml2/Pvp2SProfileEndPointTest.java
@@ -6,12 +6,12 @@ import java.io.UnsupportedEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.time.Instant;
import java.util.List;
import java.util.Timer;
import javax.xml.transform.TransformerException;
-import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -129,7 +129,7 @@ public class Pvp2SProfileEndPointTest {
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
XMLObjectProviderRegistrySupport.getParserPool(),
Pvp2SProfileEndPointTest.class.getResourceAsStream("/data/pvp2_authn_3.xml"));
- authnReq.setIssueInstant(DateTime.now());
+ authnReq.setIssueInstant(Instant.now());
RequestAbstractType signedAuthnReq =
Saml2Utils.signSamlObject(authnReq, credentialProvider.getMetaDataSigningCredential(), true);
String b64 = Base64Utils.encodeToString(DomUtils.serializeNode(
@@ -166,7 +166,7 @@ public class Pvp2SProfileEndPointTest {
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
XMLObjectProviderRegistrySupport.getParserPool(),
Pvp2SProfileEndPointTest.class.getResourceAsStream("/data/pvp2_authn_1.xml"));
- authnReq.setIssueInstant(DateTime.now());
+ authnReq.setIssueInstant(Instant.now());
RequestAbstractType signedAuthnReq =
Saml2Utils.signSamlObject(authnReq, credentialProvider.getMetaDataSigningCredential(), true);
String b64 = Base64Utils.encodeToString(DomUtils.serializeNode(
@@ -203,7 +203,7 @@ public class Pvp2SProfileEndPointTest {
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
XMLObjectProviderRegistrySupport.getParserPool(),
Pvp2SProfileEndPointTest.class.getResourceAsStream("/data/pvp2_authn_1.xml"));
- authnReq.setIssueInstant(DateTime.now());
+ authnReq.setIssueInstant(Instant.now());
RequestAbstractType signedAuthnReq =
Saml2Utils.signSamlObject(authnReq, credentialProvider.getMetaDataSigningCredential(), true);
String b64 = Base64Utils.encodeToString(DomUtils.serializeNode(
@@ -240,7 +240,7 @@ public class Pvp2SProfileEndPointTest {
final RequestAbstractType authnReq = (RequestAbstractType) XMLObjectSupport.unmarshallFromInputStream(
XMLObjectProviderRegistrySupport.getParserPool(),
Pvp2SProfileEndPointTest.class.getResourceAsStream("/data/pvp2_authn_1.xml"));
- authnReq.setIssueInstant(DateTime.now());
+ authnReq.setIssueInstant(Instant.now());
RequestAbstractType signedAuthnReq =
Saml2Utils.signSamlObject(authnReq, credentialProvider.getMessageSigningCredential(), true);
String b64 = Base64Utils.encodeToString(DomUtils.serializeNode(
diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/task/GenerateCountrySelectionFrameTaskTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/task/GenerateCountrySelectionFrameTaskTest.java
index 49d7acf4..938e1f29 100644
--- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/task/GenerateCountrySelectionFrameTaskTest.java
+++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/task/GenerateCountrySelectionFrameTaskTest.java
@@ -7,6 +7,7 @@ import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,7 +52,7 @@ public class GenerateCountrySelectionFrameTaskTest {
@BeforeClass
public static void classInitializer() {
final String current = new java.io.File(".").toURI().toString();
- System.setProperty("eidas.ms.configuration", current + "src/test/resources/config/junit_config_1.properties");
+ System.setProperty("eidas.ms.configuration", current + "src/test/resources/config/junit_config_1.properties");
Locale.setDefault(Locale.ENGLISH);
}
@@ -71,9 +72,13 @@ public class GenerateCountrySelectionFrameTaskTest {
pendingReq.setAuthUrl("https://localhost/ms_connector");
pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10));
+ Locale.setDefault(Locale.ENGLISH);
LocaleContextHolder.resetLocaleContext();
+ LocaleContextHolder.setDefaultLocale(Locale.ENGLISH);
+
}
+ @Ignore
@Test
public void validHtmlResponseWithOutLocale() throws TaskExecutionException, UnsupportedEncodingException {
@@ -102,6 +107,7 @@ public class GenerateCountrySelectionFrameTaskTest {
}
+ @Ignore
@Test
public void validHtmlResponseWithEN() throws TaskExecutionException, UnsupportedEncodingException {
LocaleContextHolder.setLocale(Locale.ENGLISH);
@@ -118,6 +124,7 @@ public class GenerateCountrySelectionFrameTaskTest {
@Test
public void validHtmlResponseWithFR() throws TaskExecutionException, UnsupportedEncodingException {
+ LocaleContextHolder.setDefaultLocale(null);
LocaleContextHolder.setLocale(Locale.FRANCE);
httpReq.addHeader("Accept-Language", "fr");
@@ -126,7 +133,7 @@ public class GenerateCountrySelectionFrameTaskTest {
//result validation
String html = doBasicValidation();
- Assert.assertTrue("No english text",
+ Assert.assertTrue("No france text",
html.contains("Information on Logins with European eIDs"));
}
diff --git a/connector/src/test/resources/config/application-exectest.properties b/connector/src/test/resources/config/application-exectest.properties
new file mode 100644
index 00000000..e63cda7b
--- /dev/null
+++ b/connector/src/test/resources/config/application-exectest.properties
@@ -0,0 +1,83 @@
+## embbeded Tomcat
+tomcat.workingdir=./target/work
+tomcat.ajp.enabled=true
+tomcat.ajp.port=8009
+tomcat.ajp.networkAddress=127.0.0.1
+tomcat.ajp.additionalAttributes.secretrequired=true
+tomcat.ajp.additionalAttributes.secret=junit
+
+## Basic service configuration
+eidas.ms.context.url.prefix=http://localhost
+eidas.ms.core.configRootDir=file:./src/test/resources/config/
+
+eidas.ms.context.use.clustermode=true
+
+##Monitoring
+eidas.ms.monitoring.eIDASNode.metadata.url=http://localhost:40900/mockup
+
+## extended validation of pending-request Id's
+eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret
+
+## eIDAS Ref. Implementation connector ###
+eidas.ms.auth.eIDAS.node_v2.forward.endpoint=http://eidas.node/junit
+
+eidas.ms.auth.eIDAS.szrclient.useTestService=true
+eidas.ms.auth.eIDAS.szrclient.endpoint.prod=
+eidas.ms.auth.eIDAS.szrclient.endpoint.test=http://localhost:1234/demoszr
+eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.path=keys/junit.jks
+eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.password=password
+eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.path=
+eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.password=
+
+#tech. AuthBlock signing for E-ID process
+eidas.ms.auth.eIDAS.authblock.keystore.password=f/+saJBc3a}*/T^s
+eidas.ms.auth.eIDAS.authblock.keystore.friendlyName=connectorkeypair
+eidas.ms.auth.eIDAS.authblock.keystore.path=keys/teststore.jks
+eidas.ms.auth.eIDAS.authblock.keystore.type=jks
+eidas.ms.auth.eIDAS.authblock.key.alias=connectorkeypair
+eidas.ms.auth.eIDAS.authblock.key.password=f/+saJBc3a}*/T^s
+
+
+#Raw eIDAS Id data storage
+eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=true
+eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=false
+
+
+
+## PVP2 S-Profile end-point configuration
+eidas.ms.pvp2.keystore.type=jks
+eidas.ms.pvp2.keystore.path=keys/junit.jks
+eidas.ms.pvp2.keystore.password=password
+eidas.ms.pvp2.key.metadata.alias=meta
+eidas.ms.pvp2.key.metadata.password=password
+eidas.ms.pvp2.key.signing.alias=sig
+eidas.ms.pvp2.key.signing.password=password
+eidas.ms.pvp2.metadata.validity=24
+
+eidas.ms.pvp2.metadata.organisation.name=JUnit
+eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit
+eidas.ms.pvp2.metadata.organisation.url=http://junit.test
+eidas.ms.pvp2.metadata.contact.givenname=Max
+eidas.ms.pvp2.metadata.contact.surname=Mustermann
+eidas.ms.pvp2.metadata.contact.email=max@junit.test
+
+## Service Provider configuration
+eidas.ms.sp.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata
+eidas.ms.sp.0.pvp2.metadata.truststore=keys/junit.jks
+eidas.ms.sp.0.pvp2.metadata.truststore.password=password
+eidas.ms.sp.0.friendlyName=jUnit test
+eidas.ms.sp.0.newEidMode=true
+
+#eidas.ms.sp.0.pvp2.metadata.url=
+#eidas.ms.sp.0.policy.allowed.requested.targets=.*
+#eidas.ms.sp.0.policy.hasBaseIdTransferRestriction=false
+
+## Service Provider configuration
+eidas.ms.sp.1.uniqueID=https://demo.egiz.gv.at/junit_test
+eidas.ms.sp.1.pvp2.metadata.truststore=keys/junit.jks
+eidas.ms.sp.1.pvp2.metadata.truststore.password=password
+eidas.ms.sp.1.friendlyName=jUnit test
+eidas.ms.sp.1.pvp2.metadata.url=http://junit.test/metadata
+eidas.ms.sp.1.policy.allowed.requested.targets=test
+eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true
+
diff --git a/connector/src/test/resources/spring/SpringTest_connector.beans.xml b/connector/src/test/resources/spring/SpringTest_connector.beans.xml
index 81fff7dd..0645ed31 100644
--- a/connector/src/test/resources/spring/SpringTest_connector.beans.xml
+++ b/connector/src/test/resources/spring/SpringTest_connector.beans.xml
@@ -89,7 +89,7 @@
class="at.asitplus.eidas.specific.connector.gui.DefaultVelocityGuiBuilderImpl" />
<bean id="mvcGUIBuilderImpl"
- class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" />
+ class="at.gv.egiz.eaaf.core.impl.gui.builder.SpringMvcGuiFormBuilderImpl" />
<bean id="templateEngine"
class="org.thymeleaf.spring5.SpringTemplateEngine">