Skip to content

Repository files navigation

Spring User Framework Demo Application

License Java

A demo application for the Spring User Framework. It runs the framework's user-management surface (registration with email verification, login, passkeys, MFA, OAuth2 and OIDC, password reset, profile editing, account deletion) behind a working Thymeleaf and Bootstrap UI, and adds a small event-management domain on top to show how application code builds on the framework's identity and authorization. The HTML, JavaScript, and configuration here are meant to be copied into your own application as a starting point.

Registration page

Documentation for this demo is in docs/; the framework's own documentation lives in its repository.

Version compatibility

Demo version Spring Boot Spring User Framework Java Branch or tag
main 4.1.x 5.3.x 21 main
1.0.0-springboot3 3.5.x 3.5.x 17 v1.0.0-springboot3

main is on Spring Boot 4.1.0 and framework 5.3.0 (build.gradle). For the Spring Boot 3.5.6 and framework 3.5.1 combination on Java 17, git checkout v1.0.0-springboot3 after cloning.

What this demo shows

Capability Where it lives Details
Application-specific user profile sharing the framework user's key user/profile/ EXTENDING.md
Cleaning up application data when an account is deleted UserProfileDeletionListener EXTENDING.md
An application domain (events) using privilege-based access control event/, roles in application.yml EXTENDING.md
Allowing or denying registrations through the RegistrationGuard SPI DomainRegistrationGuard, registration-guard profile AUTHENTICATION.md
Passkey sign-in, enrollment, management, and passwordless registration static/js/user/ (register.js, webauthn-*.js) AUTHENTICATION.md
Two-factor login, password plus passkey application-mfa.yml, user/mfa/ AUTHENTICATION.md
OAuth2 login with Google and Facebook application-local.yml-example AUTHENTICATION.md
OIDC login against a bundled Keycloak, as a runnable stack docker-compose-keycloak.yml, keycloak/ AUTHENTICATION.md
Remember-me cookies login.html, application.yml AUTHENTICATION.md
Admin page and API that lock and unlock accounts AdminController, AdminAPIController AUTHENTICATION.md
Reference templates, JavaScript, and message bundle to copy templates/, static/js/ EXTENDING.md
Replacing a framework service with your own CustomUserEmailService EXTENDING.md
A test-only API, profile-gated and loopback-only, for E2E runs TestDataController EXTENDING.md
Browser tests covering the flows above playwright/ TESTING.md

Project layout

src/main/java/com/digitalsanctuary/spring/demo/
├── controller/       AdminController, AdminAPIController, PageController
├── event/            the example domain: entity, repository, service, page and API controllers
├── registration/     DomainRegistrationGuard, the RegistrationGuard SPI sample
├── service/          CustomUserEmailService, a framework service replaced with @Primary
├── test/             api/ the test-only API, config/ its security config; playwright-test only
├── user/profile/     the profile entity, repository, service, session holder, and listeners
├── util/             LocaleConfiguration
└── web/              DemoTemplateModelAdvice
src/main/resources/
├── static/js/        user/ (one module per page), admin/, utils/, shared.js
├── templates/        layout.html plus fragments/, user/, event/, admin/, mail/
├── messages/         messages.properties, the UI and validation message bundle
├── application.yml   base configuration, overridden by application-<profile>.yml where needed
└── data-local.sql    sample events, loaded under the local profile
src/test/java/com/digitalsanctuary/spring/
├── demo/             tests for this application's own code
└── user/             tests against the framework's user-management surface
playwright/           E2E specs, fixtures, and playwright.config.ts
keycloak/             realm export and TLS material for the Keycloak stack

Not every profile has its own file: local is a gitignored copy of application-local.yml-example, test lives in src/test/resources/application-test.properties, and registration-guard has no file at all. docs/CONFIGURATION.md lists what each one overrides.

Quick start

Docker

Nothing to install but Docker:

git clone https://github.com/devondragon/SpringUserFrameworkDemoApp.git
cd SpringUserFrameworkDemoApp
docker compose up --build

The app image is built from source inside Docker, so the first build takes several minutes. When it is up, open http://localhost:8080 and register at http://localhost:8080/user/register.html. This stack sets USER_REGISTRATION_SENDVERIFICATIONEMAIL=false, so accounts are enabled at registration and you can log in immediately. Its mailserver container is a relay with no route to real inboxes, so nothing it accepts will reach an actual mailbox. The stack runs under the dev profile and loads no sample events.

Stop it with Ctrl-C, then docker compose down -v to remove the containers and their data.

Locally with Gradle

Needs JDK 21 (mise.toml pins it) and a running Docker daemon: bootRun starts the MariaDB container defined in compose.dev.yaml and stops it with the app.

git clone https://github.com/devondragon/SpringUserFrameworkDemoApp.git
cd SpringUserFrameworkDemoApp
cp src/main/resources/application-local.yml-example src/main/resources/application-local.yml
./gradlew bootRun --args='--spring.profiles.active=local'

application-local.yml is gitignored, so credentials you put in it stay out of git. Copying it also turns off the verification email and loads the sample events in data-local.sql. Then open http://localhost:8080, register at http://localhost:8080/user/register.html, and browse the API at http://localhost:8080/swagger-ui.html.

To use a database you manage yourself instead of the container, set spring.docker.compose.enabled: false and your own spring.datasource.* values; see CONFIGURATION.md.

With Keycloak

docker compose -f docker-compose-keycloak.yml up -d --build --wait runs the app against a bundled Keycloak and its imported demo realm. Ports, credentials, and the login walkthrough are in keycloak/README.md and AUTHENTICATION.md.

Profiles

Profile What it is for
local Everyday local development; needs application-local.yml copied from the example
dev Debug-heavy dev server; what the compose.yaml Docker stack runs
prd Production settings: env-driven datasource and URLs, strict cookies, template caching
test The JUnit suite on H2, applied automatically by ./gradlew test
playwright-test Add-on: enables the loopback-only test API and turns off the verification and password-reset emails for E2E runs
docker-keycloak OIDC against the bundled Keycloak; set for you inside docker-compose-keycloak.yml
mfa Add-on: requires PASSWORD plus WEBAUTHN, for example local,mfa
registration-guard Add-on: activates the domain-restricted registration guard, for example local,registration-guard

Pick a base profile with --spring.profiles.active=, and list add-ons after it, comma-separated. With no --args at all, bootRun still runs local (build.gradle:114-124). Full per-profile override lists are in CONFIGURATION.md.

Documentation

This demo:

  • docs/CONFIGURATION.md: profiles, the properties this demo sets, environment variables, mail, and security settings.
  • docs/DEVELOPMENT.md: prerequisites, running the app, the Compose files, Gradle tasks, logs, LiveReload, and IDE setup.
  • docs/TESTING.md: the JUnit suite, disabled tests, the Playwright suite and its test API, and CI.
  • docs/EXTENDING.md: each framework extension point, the demo code that uses it, and what to write in your own app.
  • docs/AUTHENTICATION.md: every authentication path here, how to run it, and its configuration.
  • keycloak/README.md: the Keycloak stack, its realm export, and its credentials.
  • CHANGELOG.md: what changed, by date.

The framework:

Testing

./gradlew test            # JUnit suite, test profile, H2
./gradlew playwrightTest  # E2E; starts the app itself

Run both from the repository root. playwrightTest depends on playwrightBrowsers and playwrightInstall, so it installs the npm dependencies and the browsers on its first run.

Details, including the MFA-only Playwright project and the test-only API, are in docs/TESTING.md.

Contributing

Issues and pull requests are welcome at SpringUserFrameworkDemoApp. Follow the patterns already in the code, add tests for new behavior, and make sure ./gradlew test passes before opening a pull request. Changes to the library itself belong in the framework repository, which has its own CONTRIBUTING.md.

License

Apache License 2.0; see LICENSE.

The application is based on the principles in the Baeldung Spring Security Course.

Disclaimer: This is a demo project provided as-is with no guarantees of performance, security, or production readiness.

About

A Spring Boot Application demonstrating the use of the SpringUserFramework Library with example HTML and JS

Resources

Stars

7 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages