<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z" -->

---
title: Build Secure Desktop Apps with JavaFX, Spring Boot &amp;...
description: A walkthrough of building a secure JavaFX desktop application that authenticates users through OAuth 2.0 using the Authorization Code flow with PKCE, since...
canonical: https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Build Secure Desktop Apps with JavaFX, Spring Boot &amp; PKCE OAuth 2.0 | daily.dev
og:description: A walkthrough of building a secure JavaFX desktop application that authenticates users through OAuth 2.0 using the Authorization Code flow with PKCE, since...
og:url: https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z
og:image: https://api.daily.dev/og/posts/FpRfLzE1z.png
og:image:alt: Build Secure Desktop Apps with JavaFX, Spring Boot &amp; PKCE OAuth 2.0
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Secure Desktop Apps with JavaFX, Spring Boot & PKCE OAuth 2.0

**[Coffee \+ Software](https://daily.dev/sources/coffee-software)** · 38 min read · 3 upvotes · 0 comments

## Summary

A walkthrough of building a secure JavaFX desktop application that authenticates users through OAuth 2.0 using the Authorization Code flow with PKCE, since desktop clients cannot safely store a client secret. The setup includes a Spring Authorization Server backed by Postgres and Flyway migrations, a local single-use web server to catch the OAuth callback, custom Spring Security classes (AuthorizationBrowser, SystemBrowserOAuth2Login, and a custom OAuth2AuthorizedClientProvider) to drive the browser-based login flow, and a resource server that validates the resulting token. It also covers wiring a RestClient with an OAuth2 interceptor, refactoring to a declarative HTTP interface client, and packaging the whole app as a GraalVM native image running with about 200MB of RAM.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.youtube.com/watch?v=gB7FIbxMEos>

## Questions this post answers

### How can a desktop application authenticate securely with OAuth2 if it can't store a client secret?

Use the Authorization Code flow with PKCE (Proof Key for Code Exchange), which removes the need for a client secret entirely. The app generates a random cryptographically secure verifier, hashes it with SHA-256 to create a challenge, sends the challenge to the authorization server, and later presents the original verifier when exchanging the authorization code for a token so the server can confirm they match.

_daily.dev surfaces practical security patterns like PKCE for developers hardening native and desktop clients._

### How do you handle the OAuth2 redirect callback in a native desktop application that has no web server?

Spin up a single-use, single-tenant local web server (for example on port 8385) that opens in the operating system's default browser when the user clicks sign in. Once the authorization server redirects back to that local endpoint with the authorization code, the app captures it, completes the token exchange, shuts down the temporary server, and stores the token.

_developers wiring desktop OAuth flows can track this kind of implementation pattern on daily.dev._

### Does using GraalVM native image affect memory usage for a JavaFX desktop app with embedded OAuth security?

A JavaFX application with an embedded PKCE-compliant OAuth2 web server, compiled to a GraalVM native image, uses roughly 200MB of real memory (RSS) according to macOS Activity Monitor, including private and shared memory. Startup is near-instant, and even running the same code unpacked on a JVM instead of as a native binary starts fast enough to be unnoticeable to end users.

_daily.dev helps developers weighing native image tradeoffs for desktop Java apps stay on top of real numbers._

---

Tags: [#java](https://daily.dev/tags/java), [#spring-boot](https://daily.dev/tags/spring-boot)

[View this post on daily.dev](https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Build Secure Desktop Apps with JavaFX, Spring Boot & PKCE OAuth 2.0","url":"https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z"},"datePublished":"2026-09-03T14:19:39.160Z","dateModified":"2026-09-03T14:25:21.353Z","description":"A walkthrough of building a secure JavaFX desktop application that authenticates users through OAuth 2.0 using the Authorization Code flow with PKCE, since...","image":"https://i.ytimg.com/vi/gB7FIbxMEos/sddefault.jpg","thumbnailUrl":"https://i.ytimg.com/vi/gB7FIbxMEos/sddefault.jpg","isAccessibleForFree":true,"articleSection":"Coffee + Software","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Coffee + Software","logo":"https://media.daily.dev/image/upload/s--nAGLloYn--/f_auto,q_auto/v1773648811/logos/coffee-software?_a=BAMAMiiu0","url":"https://daily.dev/sources/coffee-software"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"java,spring-boot","timeRequired":"PT38M","video":{"@type":"VideoObject","name":"Build Secure Desktop Apps with JavaFX, Spring Boot & PKCE OAuth 2.0","description":"A walkthrough of building a secure JavaFX desktop application that authenticates users through OAuth 2.0 using the Authorization Code flow with PKCE, since...","thumbnailUrl":"https://i.ytimg.com/vi/gB7FIbxMEos/sddefault.jpg","uploadDate":"2026-09-03T14:19:39.160Z","duration":"PT38M","url":"https://api.daily.dev/r/FpRfLzE1z","embedUrl":"https://www.youtube.com/embed/gB7FIbxMEos"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Coffee + Software","item":"https://daily.dev/sources/coffee-software"},{"@type":"ListItem","position":3,"name":"Build Secure Desktop Apps with JavaFX, Spring Boot & PKCE OAuth 2.0"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/build-secure-desktop-apps-with-javafx-spring-boot-pkce-oauth-2-0-fprflze1z#faq","mainEntity":[{"@type":"Question","name":"How can a desktop application authenticate securely with OAuth2 if it can't store a client secret?","acceptedAnswer":{"@type":"Answer","text":"Use the Authorization Code flow with PKCE (Proof Key for Code Exchange), which removes the need for a client secret entirely. The app generates a random cryptographically secure verifier, hashes it with SHA-256 to create a challenge, sends the challenge to the authorization server, and later presents the original verifier when exchanging the authorization code for a token so the server can confirm they match. daily.dev surfaces practical security patterns like PKCE for developers hardening native and desktop clients."}},{"@type":"Question","name":"How do you handle the OAuth2 redirect callback in a native desktop application that has no web server?","acceptedAnswer":{"@type":"Answer","text":"Spin up a single-use, single-tenant local web server (for example on port 8385) that opens in the operating system's default browser when the user clicks sign in. Once the authorization server redirects back to that local endpoint with the authorization code, the app captures it, completes the token exchange, shuts down the temporary server, and stores the token. developers wiring desktop OAuth flows can track this kind of implementation pattern on daily.dev."}},{"@type":"Question","name":"Does using GraalVM native image affect memory usage for a JavaFX desktop app with embedded OAuth security?","acceptedAnswer":{"@type":"Answer","text":"A JavaFX application with an embedded PKCE-compliant OAuth2 web server, compiled to a GraalVM native image, uses roughly 200MB of real memory (RSS) according to macOS Activity Monitor, including private and shared memory. Startup is near-instant, and even running the same code unpacked on a JVM instead of as a native binary starts fast enough to be unnoticeable to end users. daily.dev helps developers weighing native image tradeoffs for desktop Java apps stay on top of real numbers."}}]}
```

