From ce1e18825579503c9d996d447a5a44dd77f6b81c Mon Sep 17 00:00:00 2001 From: Sander Kondratjev Date: Tue, 18 Nov 2025 10:26:46 +0200 Subject: [PATCH 1/4] NFC-66 Readme update Signed-off-by: Sander Kondratjev --- README.md | 61 ++++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index e3aa6986..bc4325de 100644 --- a/README.md +++ b/README.md @@ -178,46 +178,29 @@ Similarly, the `WebEidMobileAuthInitFilter` handles `/auth/mobile/init` requests See the full implementation [here](example/src/main/java/eu/webeid/example/security/WebEidMobileAuthInitFilter.java). ```java -public final class WebEidMobileAuthInitFilter extends OncePerRequestFilter { - private static final ObjectWriter OBJECT_WRITER = new ObjectMapper().writer(); - private final RequestMatcher requestMatcher; - private final ChallengeNonceGenerator nonceGenerator; - private final String loginPath; - - public WebEidMobileAuthInitFilter(String path, String loginPath, ChallengeNonceGenerator nonceGenerator) { - this.requestMatcher = PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, path); - this.nonceGenerator = nonceGenerator; - this.loginPath = loginPath; +@Override +protected void doFilterInternal(@NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain chain) throws IOException, ServletException { + if (!requestMatcher.matches(request)) { + chain.doFilter(request, response); + return; } - @Override - protected void doFilterInternal( - @NonNull HttpServletRequest request, - @NonNull HttpServletResponse response, - @NonNull FilterChain chain - ) throws IOException, ServletException { - if (!requestMatcher.matches(request)) { - chain.doFilter(request, response); - return; - } + var challenge = nonceGenerator.generateAndStoreNonce(); - var challenge = nonceGenerator.generateAndStoreNonce(); + String loginUri = ServletUriComponentsBuilder.fromCurrentContextPath() + .path(mobileLoginPath).build().toUriString(); - String loginUri = ServletUriComponentsBuilder.fromCurrentContextPath() - .path(loginPath).build().toUriString(); - - String payloadJson = OBJECT_WRITER.writeValueAsString( - new AuthPayload(challenge.getBase64EncodedNonce(), loginUri) - ); - String encoded = Base64.getEncoder().encodeToString(payloadJson.getBytes(StandardCharsets.UTF_8)); - String eidAuthUri = "web-eid-mobile://auth#" + encoded; - - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - OBJECT_WRITER.writeValue(response.getWriter(), new AuthUri(eidAuthUri)); - } + String payloadJson = OBJECT_WRITER.writeValueAsString( + new AuthPayload(challenge.getBase64EncodedNonce(), loginUri, + webEidMobileProperties.requestSigningCert() ? Boolean.TRUE : null) + ); + String encoded = Base64.getEncoder().encodeToString(payloadJson.getBytes(StandardCharsets.UTF_8)); + String authUri = getAuthUri(encoded); - record AuthPayload(String challenge, @JsonProperty("login_uri") String loginUri) {} - record AuthUri(@JsonProperty("auth_uri") String authUri) {} + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + OBJECT_WRITER.writeValue(response.getWriter(), new AuthUri(authUri)); } ``` @@ -225,10 +208,10 @@ Both filters are registered in the Spring Security filter chain in ApplicationCo See the full implementation [here](example/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java): ```java http - .addFilterBefore(new WebEidMobileAuthInitFilter("/auth/mobile/init", "/auth/mobile/login", challengeNonceGenerator), - UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(new WebEidChallengeNonceFilter("/auth/challenge", challengeNonceGenerator), - UsernamePasswordAuthenticationFilter.class); + .addFilterBefore(new WebEidMobileAuthInitFilter("/auth/mobile/init", "/auth/mobile/login", challengeNonceGenerator, webEidMobileProperties), + UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(new WebEidChallengeNonceFilter("/auth/challenge", challengeNonceGenerator), + UsernamePasswordAuthenticationFilter.class) ``` Also, see general guidelines for implementing secure authentication services [here](https://github.com/SK-EID/smart-id-documentation/wiki/Secure-Implementation-Guide). From d4cc69a2445bf19babf2b84800afceb7ffbdf143 Mon Sep 17 00:00:00 2001 From: Sander Kondratjev Date: Mon, 30 Mar 2026 13:00:20 +0300 Subject: [PATCH 2/4] NFC-66 Readme updates to multi-cert implementation Signed-off-by: Sander Kondratjev --- README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bc4325de..51243bbf 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ public final class WebEidChallengeNonceFilter extends OncePerRequestFilter { } ``` -Similarly, the `WebEidMobileAuthInitFilter` handles `/auth/mobile/init` requests for Web eID for Mobile authentication flow by generating a challenge nonce and returning a deep link URI. This deep link contains both the challenge nonce and a login URI for the mobile authentication flow. +The `WebEidMobileAuthInitFilter` handles `/auth/mobile/init` requests for authentication flows using **Web eID token format v1.1**. It generates a challenge nonce and returns a deep link URI that embeds both the challenge nonce and the authentication endpoint required for initiating the v1.1 flow. See the full implementation [here](example/src/main/java/eu/webeid/example/security/WebEidMobileAuthInitFilter.java). ```java @@ -230,9 +230,12 @@ The gist of the validation is [in the `authenticate()` method](example/blob/main ```java try { - String nonce = challengeNonceStore.getAndRemove().getBase64EncodedNonce(); - X509Certificate userCertificate = tokenValidator.validate(authToken, nonce); - return WebEidAuthentication.fromCertificate(userCertificate, authorities); + final String nonce = challengeNonceStore.getAndRemove().getBase64EncodedNonce(); + final X509Certificate userCertificate = tokenValidator.validate(authToken, nonce); + final var signingCertificate = requireSigningCert && !CollectionUtils.isEmpty(authToken.getUnverifiedSigningCertificates()) + ? authToken.getUnverifiedSigningCertificates().getFirst() // NOTE: Handling multiple signing certificates is out of scope of this example. + : null; + return WebEidAuthentication.fromCertificate(userCertificate, signingCertificate, authorities); } catch (AuthTokenException e) { ... ``` @@ -252,6 +255,7 @@ try { - [Basic usage](#basic-usage-1) - [Extended configuration](#extended-configuration-1) - [Differences between version 1 and version 2](#differences-between-version-1-and-version-2) +- [Authentication token format versions](#authentication-token-format-versions) # Introduction @@ -266,7 +270,7 @@ In the following, - **origin** is defined as the website origin, the URL serving the web application, - **challenge nonce** (or challenge) is defined as a cryptographic nonce, a large random number that can be used only once, with at least 256 bits of entropy. -The Web eID authentication token is a JSON data structure that looks like the following example: +The Web eID authentication token (format **`web-eid:1.0`**) is a JSON data structure that looks like the following example: ```json { @@ -298,6 +302,55 @@ It contains the following fields: The value that is signed by the user’s authentication private key and included in the `signature` field is `hash(origin)+hash(challenge)`. The hash function is used before concatenation to ensure field separation as the hash of a value is guaranteed to have a fixed length. Otherwise the origin `example.com` with challenge nonce `.eu1234` and another origin `example.com.eu` with challenge nonce `1234` would result in the same value after concatenation. The hash function `hash` is the same hash function that is used in the signature algorithm, for example SHA256 in case of RS256. +The Web eID authentication token (format **`web-eid:1.1`**) is a JSON data structure that looks like the following example: + +```json +{ + "unverifiedCertificate": "MIIFozCCA4ugAwIBAgIQHFpdK-zCQsFW4...", + "algorithm": "RS256", + "signature": "HBjNXIaUskXbfhzYQHvwjKDUWfNu4yxXZha...", + "unverifiedSigningCertificates": [ + { + "certificate": "MIIFikACB3ugAwASAgIHHFrtdZ-zeQsas1...", + "supportedSignatureAlgorithms": [ + { + "cryptoAlgorithm": "ECC", + "hashFunction": "SHA-384", + "paddingScheme": "NONE" + } + ] + } + ], + "format": "web-eid:1.1", + "appVersion": "https://web-eid.eu/web-eid-app/releases/v2.0.0" +} +``` +It contains the following fields: + +- `unverifiedSigningCertificates`: an array of objects containing signing certificate information. + +Each object inside `unverifiedSigningCertificates` contains: + +- `certificate`: base64-encoded DER-encoded signing certificate, + +- `supportedSignatureAlgorithms`: list of supported algorithms in the following format: + + - `cryptoAlgorithm`: the cryptographic algorithm used for the key, + + - `hashFunction`: the hashing algorithm used, + + - `paddingScheme`: the padding scheme used (if applicable). + + +Allowed values are: + + cryptoAlgorithm: "ECC", "RSA" + + hashFunction: + "SHA-224", "SHA-256", "SHA-384", "SHA-512", + "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512" + + paddingScheme: "NONE", "PKCS1.5", "PSS" # Authentication token validation @@ -305,8 +358,12 @@ The authentication token validation process consists of two stages: - First, **user certificate validation**: the validator parses the token and extracts the user certificate from the *unverifiedCertificate* field. Then it checks the certificate expiration, purpose and policies. Next it checks that the certificate is signed by a trusted CA and checks the certificate status with OCSP. - Second, **token signature validation**: the validator validates that the token signature was created using the provided user certificate by reconstructing the signed data `hash(origin)+hash(challenge)` and using the public key from the certificate to verify the signature in the `signature` field. If the signature verification succeeds, then the origin and challenge nonce have been implicitly and correctly verified without the need to implement any additional security checks. +- Additional validation for **Web eID authentication tokens (format v1.1)**: + - **Subject match check**: The subject of the signing certificate must match the subject of the authentication certificate. + This ensures both certificates belong to the same user. + - **Signing certificate validation**: Expiration, key usage, and policies are checked. The certificate must be signed by a trusted certificate authority. OCSP is used to verify the revocation status. -The website back end must lookup the challenge nonce from its local store using an identifier specific to the browser session, to guarantee that the authentication token was received from the same browser to which the corresponding challenge nonce was issued. The website back end must guarantee that the challenge nonce lifetime is limited and that its expiration is checked, and that it can be used only once by removing it from the store during validation. +The website back end must look up the challenge nonce from its local store using an identifier specific to the browser session, to guarantee that the authentication token was received from the same browser to which the corresponding challenge nonce was issued. The website back end must guarantee that the challenge nonce lifetime is limited and that its expiration is checked, and that it can be used only once by removing it from the store during validation. ## Basic usage @@ -431,3 +488,17 @@ NonceGenerator generator = new NonceGeneratorBuilder() In version 1, the generated challenge nonces were stored in a JSR107 compatible cache. The goal of using a cache was to support stateful and stateless authentication with a universal API that uses the same underlying mechanism. However, in case the website had a CSRF vulnerability, this made the solution vulnerable to [forged login attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests) (the attacker could trick the victim to submit the authentication token with the attacker's challenge nonce to the website using a CSRF attack, so that the victim was authenticated to the website as the attacker). To mitigate this attack, in version 2 the requirement is that the library adopter must guarantee that the authentication token is received from the same browser to which the corresponding challenge nonce was issued. The recommended solution is to use a session-backed challenge nonce store, as in the code examples above. The library no longer uses the JSR107 cache API and provides a `ChallengeNonceStore` interface instead. In the internal implementation, the Web eID authentication token format changed in version 2. In version 1, the authentication token was in the OpenID X509 ID Token (JWT) format in order to be compatible with the standard OpenID Connect ID Token specification. During independent security review it was pointed out that any similarities of the Web eID authentication token to the JWT format are actually undesirable, as they would imply that the claims presented in the Web eID authentication token can be trusted and processed, while in fact they must be ignored, as they can be manipulated at the client side. The presence of the claims in the authentication token introduces a risk of vulnerabilities in case the authentication implementer decides to rely on any of them for making security critical decisions or decides to apply the same standard validation workflow that is applied to standard JWTs. Since there does not exist a standardized format for an authentication proof that corresponds to the requirements of the Web eID authentication protocol, a special purpose JSON-based format for the Web eID authentication token was adopted in version 2. The format is described in detail in the section *[Authentication token format](#authentication-token-format)*, and the full analysis of the format change is available in [this article](https://web-eid.github.io/web-eid-system-architecture-doc/web-eid-auth-token-v2-format-spec.pdf). + +# Authentication Token Format Versions + +The Web eID authentication protocol defines two token formats currently supported by this library: + +- **Format v1.0** – Used in desktop Web eID authentication flows with traditional smart card readers. + +- **Format v1.1** – An extended token format introduced for broader device compatibility and improved interoperability. + In addition to the fields present in v1.0, it includes: + - `unverifiedSigningCertificates` – an array of signing certificate entries. Each entry contains: + - `certificate` – a base64-encoded DER-encoded signing certificate; + - `supportedSignatureAlgorithms` – a list of supported signature algorithms associated with that certificate; + +Both token formats follow the same validation principles, differing only in the structure of embedded certificates and the additional verification steps required for v1.1. From fd9eeef1d5921f628172c40003e86cf0310d58ce Mon Sep 17 00:00:00 2001 From: Sander Kondratjev Date: Mon, 30 Mar 2026 13:38:43 +0300 Subject: [PATCH 3/4] NFC-66 Example readme updates Signed-off-by: Sander Kondratjev --- example/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/README.md b/example/README.md index 1d6a3054..35a1708f 100644 --- a/example/README.md +++ b/example/README.md @@ -118,7 +118,7 @@ The `src/main/java/eu/webeid/example` directory contains the Spring Boot applica - `security`: Web eID authentication token validation library integration with Spring Security - `AuthenticationProvider` and `AuthenticationProcessingFilter` for handling Web eID authentication tokens, - `WebEidChallengeNonceFilter` for issuing the challenge nonce required by the authentication flow, - - `WebEidMobileAuthInitFilter` for issuing the challenge nonce and generating the deep link with the authentication request, used to initiate the mobile authentication flow, + - `WebEidMobileAuthInitFilter` for issuing the challenge nonce and generating the authentication request link (OS-verified App Link / Universal Link), used to initiate the mobile authentication flow, - `WebEidAjaxLoginProcessingFilter` and `WebEidLoginPageGeneratingFilter` for handling login requests. - `service`: Web eID signing service implementation that uses DigiDoc4j, and DigiDoc4j runtime configuration. - `SigningService`: prepares ASiC-E containers and finalizes signatures. @@ -245,7 +245,7 @@ Strict Transport Security (HSTS) header and the `JSESSIONID` session cookie has ## Deployment -A Docker Compose configuration file `docker-compose.yml` is available in the root of the project for packaging the application in a Docker image so that it can be deployed with a container enginge. +A Docker Compose configuration file `docker-compose.yml` is available in the root of the project for packaging the application in a Docker image so that it can be deployed with a container engine. Build the Docker image with [Jib](https://github.com/GoogleContainerTools/jib) as follows: From 3d36d51b1e8f21a2c8440b84b776e1d382fe286b Mon Sep 17 00:00:00 2001 From: Sander Kondratjev Date: Tue, 31 Mar 2026 14:31:09 +0300 Subject: [PATCH 4/4] NFC-66 Example readme updates (review) Signed-off-by: Sander Kondratjev --- README.md | 52 +++++++++++++++++++++++------------------------ example/README.md | 14 ++++++------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 51243bbf..b7623ad7 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ public class SessionBackedChallengeNonceStore implements ChallengeNonceStore { ## 3. Configure the challenge nonce generator -The validation library needs to generate authentication challenge nonces and store them for later validation in the challenge nonce store. Overview of challenge nonce usage is provided in the [Web eID system architecture document](https://github.com/web-eid/web-eid-system-architecture-doc#authentication-1). The challenge nonce generator will be used in the REST endpoint that issues challenges; it is thread-safe and should be scoped as a singleton. +The validation library needs to generate authentication challenge nonces and store them for later validation in the challenge nonce store. Overview of challenge nonce usage is provided in the [Web eID system architecture document](https://github.com/web-eid/web-eid-system-architecture-doc#authentication-1). The challenge nonce generator will be used in the filter that issues challenges; it is thread-safe and should be scoped as a singleton. Configure the challenge nonce generator as follows: @@ -99,7 +99,7 @@ import eu.webeid.security.challenge.ChallengeNonceStore; ## 4. Add trusted certificate authority certificates -You must explicitly specify which **intermediate** certificate authorities (CAs) are trusted to issue the eID authentication and OCSP responder certificates. CA certificates can be loaded from either the truststore file, resources or any stream source. We use the [`CertificateLoader`](https://github.com/web-eid/web-eid-authtoken-validation-java/blob/main/src/main/java/eu/webeid/security/certificate/CertificateLoader.java) helper class to load CA certificates from resources here, but consider using [the truststore file](./blob/example/main/src/main/java/eu/webeid/example/config/ValidationConfiguration.java#L104-L123) instead. +You must explicitly specify which **intermediate** certificate authorities (CAs) are trusted to issue the eID authentication and OCSP responder certificates. CA certificates can be loaded from either the truststore file, resources or any stream source. We use the [`CertificateLoader`](src/main/java/eu/webeid/security/certificate/CertificateLoader.java) helper class to load CA certificates from resources here, but consider loading the truststore file (see [loadTrustedCACertificatesFromTrustStore](example/main/src/main/java/eu/webeid/example/config/ValidationConfiguration.java#L104-L123)) instead. First, copy the trusted certificates, for example `ESTEID2018.cer`, to `resources/cacerts/`, then load the certificates as follows: @@ -136,7 +136,7 @@ import eu.webeid.security.validator.AuthTokenValidatorBuilder; ## 6. Add a filter for issuing challenge nonces -Request Filters that issue challenge nonces for regular Web eID and Web eID for Mobile authentication flows are required for authentication. +Request Filters that issue challenge nonces for regular Web eID and Web eID for Mobile authentication flows are required for authentication. The filters must support POST requests. The `WebEidChallengeNonceFilter` handles `/auth/challenge` requests and issues a new nonce for regular Web eID authentication flow. @@ -204,7 +204,7 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, } ``` -Both filters are registered in the Spring Security filter chain in ApplicationConfiguration +Both filters are registered in the Spring Security filter chain in ApplicationConfiguration. See the full implementation [here](example/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java): ```java http @@ -222,11 +222,11 @@ Authentication consists of calling the `validate()` method of the authentication When using [Spring Security](https://spring.io/guides/topicals/spring-security-architecture) with standard cookie-based authentication, -- implement a custom authentication provider that uses the authentication token validator for authentication as shown [here](example/blob/main/src/main/java/eu/webeid/example/security/WebEidAuthenticationProvider.java), -- implement an AJAX authentication processing filter that extracts the authentication token and passes it to the authentication manager as shown [here](example/blob/main/src/main/java/eu/webeid/example/security/WebEidAjaxLoginProcessingFilter.java), -- configure the authentication provider and authentication processing filter in the application configuration as shown [here](example/blob/main/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java). +- implement a custom authentication provider that uses the authentication token validator for authentication as shown [here](example/src/main/java/eu/webeid/example/security/WebEidAuthenticationProvider.java), +- implement an AJAX authentication processing filter that extracts the authentication token and passes it to the authentication manager as shown [here](example/src/main/java/eu/webeid/example/security/WebEidAjaxLoginProcessingFilter.java), +- configure the authentication provider and authentication processing filter in the application configuration as shown [here](example/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java). -The gist of the validation is [in the `authenticate()` method](example/blob/main/src/main/java/eu/webeid/example/security/WebEidAuthenticationProvider.java#L74-L76) of the authentication provider: +The gist of the validation is [in the `authenticate()` method](example/src/main/java/eu/webeid/example/security/WebEidAuthenticationProvider.java#L74-L76) of the authentication provider: ```java try { @@ -235,7 +235,7 @@ try { final var signingCertificate = requireSigningCert && !CollectionUtils.isEmpty(authToken.getUnverifiedSigningCertificates()) ? authToken.getUnverifiedSigningCertificates().getFirst() // NOTE: Handling multiple signing certificates is out of scope of this example. : null; - return WebEidAuthentication.fromCertificate(userCertificate, signingCertificate, authorities); + return WebEidAuthentication.fromCertificate(userCertificate, signingCertificate, authorities); } catch (AuthTokenException e) { ... ``` @@ -259,7 +259,7 @@ try { # Introduction -The Web eID authentication token validation library for Java contains the implementation of the Web eID authentication token validation process in its entirety to ensure that the authentication token sent by the Web eID browser extension contains valid, consistent data that has not been modified by a third party. It also implements secure challenge nonce generation as required by the Web eID authentication protocol. It is easy to configure and integrate into your authentication service. +The Web eID authentication token validation library for Java contains the implementation of the Web eID authentication token validation process in its entirety to ensure that the authentication token sent by the Web eID browser extension or mobile application contains valid, consistent data that has not been modified by a third party. It also implements secure challenge nonce generation as required by the Web eID authentication protocol. It is easy to configure and integrate into your authentication service. The authentication protocol, authentication token format, validation requirements and challenge nonce usage is described in more detail in the [Web eID system architecture document](https://github.com/web-eid/web-eid-system-architecture-doc#authentication-1). @@ -358,10 +358,11 @@ The authentication token validation process consists of two stages: - First, **user certificate validation**: the validator parses the token and extracts the user certificate from the *unverifiedCertificate* field. Then it checks the certificate expiration, purpose and policies. Next it checks that the certificate is signed by a trusted CA and checks the certificate status with OCSP. - Second, **token signature validation**: the validator validates that the token signature was created using the provided user certificate by reconstructing the signed data `hash(origin)+hash(challenge)` and using the public key from the certificate to verify the signature in the `signature` field. If the signature verification succeeds, then the origin and challenge nonce have been implicitly and correctly verified without the need to implement any additional security checks. -- Additional validation for **Web eID authentication tokens (format v1.1)**: - - **Subject match check**: The subject of the signing certificate must match the subject of the authentication certificate. - This ensures both certificates belong to the same user. - - **Signing certificate validation**: Expiration, key usage, and policies are checked. The certificate must be signed by a trusted certificate authority. OCSP is used to verify the revocation status. +- Additional validation for **Web eID authentication tokens (format v1.1)**: the token must contain the `unverifiedSigningCertificates` field with at least one signing certificate entry. Each entry's `supportedSignatureAlgorithms` are validated against the set of allowed cryptographic algorithms, hash functions, and padding schemes. For each signing certificate, the following checks are performed: + - The subject must match the subject of the authentication certificate, ensuring both certificates belong to the same user. + - The issuing authority must match that of the authentication certificate, verified via the Authority Key Identifier (AKI) extension. + - The certificate must not be expired. + - The certificate must contain the non-repudiation key usage bit required for digital signatures. The website back end must look up the challenge nonce from its local store using an identifier specific to the browser session, to guarantee that the authentication token was received from the same browser to which the corresponding challenge nonce was issued. The website back end must guarantee that the challenge nonce lifetime is limited and that its expiration is checked, and that it can be used only once by removing it from the store during validation. @@ -449,7 +450,7 @@ The authentication protocol requires support for generating challenge nonces, la The `-Djava.security.egd=file:/dev/./urandom` command line argument is added to `pom.xml` to avoid the risk of having the code execution blocked unexpectedly during random generation. Without this, the JVM uses `/dev/random`, which can block, to seed the `SecureRandom` class. -The authentication protocol requires a REST endpoint that issues challenge nonces as described in section *[6. Add a REST endpoint for issuing challenge nonces](#6-add-a-rest-endpoint-for-issuing-challenge-nonces)*. +The authentication protocol requires a filter that issues challenge nonces as described in section *[6. Add a filter for issuing challenge nonces](#6-add-a-filter-for-issuing-challenge-nonces)*. Nonce usage is described in more detail in the [Web eID system architecture document](https://github.com/web-eid/web-eid-system-architecture-doc#authentication-1). @@ -469,18 +470,18 @@ The `generateAndStoreNonce()` method both generates the nonce and saves it in th ## Extended configuration -The following additional configuration options are available in `NonceGeneratorBuilder`: +The following additional configuration options are available in `ChallengeNonceGeneratorBuilder`: - `withNonceTtl(Duration duration)` – overrides the default challenge nonce time-to-live duration. When the time-to-live passes, the nonce is considered to be expired. Default challenge nonce time-to-live is 5 minutes. - `withSecureRandom(SecureRandom)` - allows to specify a custom `SecureRandom` instance. Extended configuration example: ```java -NonceGenerator generator = new NonceGeneratorBuilder() - .withChallengeNonceStore(store) - .withNonceTtl(Duration.ofMinutes(5)) - .withSecureRandom(customSecureRandom) - .build(); +ChallengeNonceGenerator generator = new ChallengeNonceGeneratorBuilder() + .withChallengeNonceStore(store) + .withNonceTtl(Duration.ofMinutes(5)) + .withSecureRandom(customSecureRandom) + .build(); ``` # Differences between version 1 and version 2 @@ -495,10 +496,9 @@ The Web eID authentication protocol defines two token formats currently supporte - **Format v1.0** – Used in desktop Web eID authentication flows with traditional smart card readers. -- **Format v1.1** – An extended token format introduced for broader device compatibility and improved interoperability. - In addition to the fields present in v1.0, it includes: - - `unverifiedSigningCertificates` – an array of signing certificate entries. Each entry contains: - - `certificate` – a base64-encoded DER-encoded signing certificate; - - `supportedSignatureAlgorithms` – a list of supported signature algorithms associated with that certificate; +- **Format v1.1** – An extended authentication token format that allows including signing certificate information in the authentication response. + - `unverifiedSigningCertificates` – an array of signing certificate entries. Each entry contains: + - `certificate` – a base64-encoded DER-encoded signing certificate; + - `supportedSignatureAlgorithms` – a list of supported signature algorithms associated with that certificate; Both token formats follow the same validation principles, differing only in the structure of embedded certificates and the additional verification steps required for v1.1. diff --git a/example/README.md b/example/README.md index 35a1708f..df35204e 100644 --- a/example/README.md +++ b/example/README.md @@ -118,7 +118,7 @@ The `src/main/java/eu/webeid/example` directory contains the Spring Boot applica - `security`: Web eID authentication token validation library integration with Spring Security - `AuthenticationProvider` and `AuthenticationProcessingFilter` for handling Web eID authentication tokens, - `WebEidChallengeNonceFilter` for issuing the challenge nonce required by the authentication flow, - - `WebEidMobileAuthInitFilter` for issuing the challenge nonce and generating the authentication request link (OS-verified App Link / Universal Link), used to initiate the mobile authentication flow, + - `WebEidMobileAuthInitFilter` for issuing the challenge nonce and generating the deep link with the authentication request, used to initiate the mobile authentication flow, - `WebEidAjaxLoginProcessingFilter` and `WebEidLoginPageGeneratingFilter` for handling login requests. - `service`: Web eID signing service implementation that uses DigiDoc4j, and DigiDoc4j runtime configuration. - `SigningService`: prepares ASiC-E containers and finalizes signatures. @@ -140,7 +140,7 @@ The `src/tests` directory contains the application test suite. The most importan As described in section [_4. Choose either the `dev` or `prod` profile_](#4-choose-either-the-dev-or-prod-profile) above, the application has two different configuration profiles: `dev` profile for running the application in development mode and `prod` profile for production mode. The `dev` profile is activated by default. -The profile-specific configuration files `src/main/resources/application-{dev,prod}.yaml` contain the `web-eid-auth-token.validation.use-digidoc4j-prod-configuration` setting that configures DigiDoc4j either in test or production mode, and a setting for configuring the origin URL as described in section [_2. Configure the origin URL_](#2-configure-the-origin-url) above. Additionally, the `web-eid-auth-token.validation.truststore-password` setting specifies the truststore password used in the `prod` profile. +The profile-specific configuration files `src/main/resources/application-{dev,prod}.yaml` contain the `web-eid-auth-token.validation.use-digidoc4j-prod-configuration` setting that configures DigiDoc4j either in test or production mode, and a setting for configuring the origin URL as described in section [_2. Configure the origin URL_](#2-configure-the-origin-url) above. Additionally, the `web-eid-auth-token.validation.truststore-password` setting specifies the truststore password used in the `prod` profile. The `web-eid-mobile` section configures the mobile authentication flow, including the `base-request-uri` for deep link generation and the `request-signing-cert` flag that controls whether the signing certificate is requested during authentication. The main configuration file `src/main/resources/application.yaml` is shared by all profiles and contains logging configuration and settings that make the session cookie secure behind a reverse proxy as described in section [_HTTPS support_](#https-support) below. @@ -150,9 +150,9 @@ Spring Security has CSRF protection enabled by default. Web eID requires CSRF pr ### Integration with Web eID components -Detailed overview of Java code changes required for integrating Web eID authentication token validation is available in the [_web-eid-authtoken-validation-java_ library README](https://github.com/web-eid/web-eid-authtoken-validation-java/blob/main/README.md). There are instructions for configuring the nonce generator, trusted certificate authority certificates, authentication token validator, Spring Security authentication integration and REST endpoints. The corresponding Java code is in the `src/main/java/eu/webeid/example/{config,security,web/rest}` directories. +Detailed overview of Java code changes required for integrating Web eID authentication token validation is available in the [_web-eid-authtoken-validation-java_ library README](https://github.com/web-eid/web-eid-authtoken-validation-java/README.md). There are instructions for configuring the nonce generator, trusted certificate authority certificates, authentication token validator, Spring Security authentication integration and security filters. The corresponding Java code is in the `src/main/java/eu/webeid/example/{config,security,web/rest}` directories. -A similar overview of JavaScript and HTML code changes required for authentication and digital signing with Web eID is available in the [web-eid.js library README](https://github.com/web-eid/web-eid.js/blob/main/README.md). The corresponding JavaScript and HTML code is in the `src/resources/{static,templates}` directories. +A similar overview of JavaScript and HTML code changes required for authentication and digital signing with Web eID is available in the [web-eid.js library README](https://github.com/web-eid/web-eid.js/README.md). The corresponding JavaScript and HTML code is in the `src/resources/{static,templates}` directories. ### Integration with DigiDoc4j components @@ -160,7 +160,7 @@ Java code examples that show how to create and sign data containers that hold si #### Using the Certificates' _Authority Information Access_ (AIA) extension in DigiDoc4j -In the `SigningService` constructor we have configured DigiDoc4j to use the AIA extension that contains the certificates’ OCSP service location with `signingConfiguration.setPreferAiaOcsp(true)`. Note that there may be limitations to using AIA URLs during signing as the services behind these URLs provide different security and SLA guarantees than dedicated OCSP services, so you should consider using a dedicated OCSP service instead. See the instructions in DigiDoc4j documentation and also the [corresponding section in _web-eid-authtoken-validation-java_ README](https://github.com/web-eid/web-eid-authtoken-validation-java/blob/main/README.md#certificates-authority-information-access-aia-extension). +In the `SigningService` constructor we have configured DigiDoc4j to use the AIA extension that contains the certificates’ OCSP service location with `signingConfiguration.setPreferAiaOcsp(true)`. Note that there may be limitations to using AIA URLs during signing as the services behind these URLs provide different security and SLA guarantees than dedicated OCSP services, so you should consider using a dedicated OCSP service instead. See the instructions in DigiDoc4j documentation and also the [corresponding section in _web-eid-authtoken-validation-java_ README](https://github.com/web-eid/web-eid-authtoken-validation-java/README.md#certificates-authority-information-access-aia-extension). #### Using DigiDoc4j in test mode with the `dev` profile @@ -232,9 +232,9 @@ Tomcat web server automatically if it detects the presence of the server.tomcat.protocol-header=x-forwarded-proto These settings are already enabled in the main configuration file `application.yaml`. See chapter -[9.3.12](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server) +[Running Behind a Front-end Proxy Server](https://docs.spring.io/spring-boot/3.5/how-to/webserver.html#howto.webserver.use-behind-a-proxy-server) and -[9.14.3](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-enable-https) +[Enable HTTPS When Running Behind a Proxy Server](https://docs.spring.io/spring-boot/3.5/how-to/security.html#howto.security.enable-https) in the official documentation for further details. ### How to verify that HTTPS is configured properly