1
0

Add passkeys project: WebAuthn ceremonies, a software authenticator and the one-time-token fallback

Fourth Maven project in the repository. Registration and authentication run end to
end with no browser and no hardware key: VirtualAuthenticator emits real CBOR
attestation objects and real ES256 assertion signatures, and tools/PasskeyCeremony.java
drives the live HTTP endpoints with them.

Profiles cover userVerification REQUIRED, DIRECT attestation, a disallowed origin and
JDBC persistence. Eleven doc chapters and twelve captured transcripts under docs/passkeys
and docs/output/pk-*.txt, all regenerated by passkeys/scripts/run-all.sh.
This commit is contained in:
2026-08-25 22:54:40 +05:30
parent e9381dc5be
commit f6dd692177
59 changed files with 3567 additions and 4 deletions

View File

@@ -0,0 +1,92 @@
[← index](README.md) · next: [02 — The minimum configuration](02-minimum-configuration.md)
# Versions, artifacts and the 7.0 split
## The dependency the tutorials forget
Passkey support arrived in Spring Security **6.4**, and at that time it lived inside
`spring-security-web` — which meant it was already on the classpath of every Spring
Boot application that used `spring-boot-starter-security`. As of Spring Security **7.0** it
does not. The classes were moved into a new artifact, `spring-security-webauthn`, which
`spring-boot-starter-security` does **not** pull in.
The move is visible in the jars:
```
$ unzip -l spring-security-web-6.5.11.jar | grep -c -i webauthn
135
$ unzip -l spring-security-web-7.1.1.jar | grep -i webauthn
10036 org/springframework/security/spring-security-webauthn.js
$ unzip -l spring-security-webauthn-7.1.1.jar | grep -c -i webauthn
139
```
The package names did **not** change — everything is still
`org.springframework.security.web.webauthn.*`. That is what makes the upgrade awkward: your
imports keep compiling against a stale local repository and fail on a clean build, and the
DSL method `http.webAuthn(..)` lives in `spring-security-config`, which is present either
way. Nothing tells you what is wrong except a `ClassNotFoundException` or a missing method.
```xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-webauthn</artifactId>
</dependency>
```
No version: `spring-boot-dependencies:4.1.1` manages it, at 7.1.1.
## What did not move
Two things were left behind in `spring-security-web`:
| artefact | where it lives | why it matters |
|---|---|---|
| `spring-security-webauthn.js` | `spring-security-web` | the browser-side script the default pages load |
| `user-credentials-schema.sql` | `spring-security-web` | the DDL for `JdbcUserCredentialRepository` |
| `user-entities-schema.sql` | `spring-security-web` | the DDL for `JdbcPublicKeyCredentialUserEntityRepository` |
`spring-security-webauthn` depends on `spring-security-web`, so all three are still reachable
&mdash; but a search inside the webauthn jar for the schema files the Javadoc points at comes
up empty, which is confusing the first time. See [09 &mdash; Persistence](09-persistence.md).
## The versions this module was built and run against
| | |
|---|---|
| JDK | Temurin **25.0.4.1+1** (current LTS) |
| Spring Boot | **4.1.1** |
| Spring Framework | **7.0.9** |
| Spring Security | **7.1.1** (GA 20 August 2026) |
| `spring-security-webauthn` | **7.1.1** |
| WebAuthn4J | **0.31.9.RELEASE** |
| Jackson | **3.1.5** (`tools.jackson`) |
| Tomcat | **11.0.24** |
| H2 | **2.4.240** (jdbc profile only) |
| Maven | 3.9.11 |
Two details behind that table are worth keeping:
**WebAuthn4J 0.31.9 is a Jackson 3 library.** Its POM declares
`tools.jackson.core:jackson-databind:3.2.1` and
`tools.jackson.dataformat:jackson-dataformat-cbor:3.2.1`. Spring Boot 4.1.1 manages Jackson at
3.1.5 and wins, so what actually resolves is `jackson-dataformat-cbor-3.1.5.jar`. Everything
in this module ran on that combination. If you are still on a Jackson 2 application, this is
a real constraint rather than a footnote.
**`spring-security-webauthn` 7.0.7 and 7.1.1 contain exactly the same set of classes.** A
class-by-class diff of the two jars is empty; only the pinned WebAuthn4J version moved, from
0.31.6 to 0.31.9. Nothing in this article is 7.1-specific in the way that, say,
`csrf.spa()` was 7.0-specific &mdash; it applies to the whole 7.x line, and mostly to 6.4 and
6.5 as well once you account for the artifact split.
## What Spring Boot does not do
There is no WebAuthn auto-configuration, and there are no `spring.security.webauthn.*`
properties. Grepping `spring-boot-autoconfigure-4.1.1.jar` and `spring-boot-security-4.1.1.jar`
for `webauthn` returns nothing. Every relying party setting in this module is Java
configuration, because Java configuration is the only option.
[&larr; index](README.md) &middot; next: [02 &mdash; The minimum configuration](02-minimum-configuration.md)