What Is a Redirect URI in Keycloak?
A complete, zero-jargon walkthrough of the humble setting that decides where Keycloak is allowed to send a user back after login — and why getting it wrong is one of the most common ways an OAuth-style login flow gets exploited.
Imagine ordering a package online and being asked to specify exactly where it should be delivered. If the delivery company blindly shipped to whatever address anyone typed in at checkout — including someone other than you — packages meant for you could end up in a stranger’s hands. Sensible delivery services instead keep a verified list of addresses tied to your account and refuse to ship anywhere else. A Redirect URI in Keycloak solves the exact same problem, but for logins: it’s the pre-approved list of addresses Keycloak is allowed to send a freshly authenticated user’s proof of identity back to. By the end of this guide, you’ll understand exactly why this setting exists, how it’s used, and what happens when it’s configured carelessly.
ACore Concepts
Before touching architecture, let’s build the vocabulary — starting with what a Redirect URI actually is and the problem it exists to solve.
A Redirect URI is a web address that Keycloak is explicitly permitted to send a user’s browser back to, once login has completed successfully. When an application asks Keycloak to authenticate a user, it includes a “please send them back to this address afterward” instruction as part of the request. Keycloak checks that requested address against a pre-registered list of allowed Redirect URIs for that specific application — and only proceeds if there’s a match. This single check is one of the most important, and most frequently misconfigured, security settings in the entire login process.
The reason this matters becomes clear once you consider what travels back through that redirect: proof of a successful login, often in the form of an authorization code or token. If Keycloak could be tricked into sending that proof to an address controlled by an attacker instead of the legitimate application, the attacker could potentially intercept it and impersonate the user. Restricting Redirect URIs to a known, pre-approved list closes that door.
Picture a courier company that only delivers packages to addresses you’ve registered in advance with your account, refusing any last-minute “actually, deliver it here instead” request typed in by whoever happens to be placing the order. Even if someone tries to sneak in a different delivery address during checkout, the courier simply won’t accept it unless that exact address was pre-approved. A Redirect URI works the same way — Keycloak refuses to send login proof anywhere that wasn’t registered in advance for that application.
A few terms recur constantly in any Redirect URI conversation, and getting them straight now makes the rest of this guide far easier to follow:
Redirect URI
The specific web address Keycloak is allowed to send the browser back to after a successful login, registered in advance on the Client’s configuration.
Client
The application registered inside Keycloak that initiates login requests — each Client maintains its own separate list of allowed Redirect URIs.
Authorization Code
A short-lived value delivered to the Redirect URI after login, which the application exchanges for a full token — this is typically what a Redirect URI is protecting.
Wildcard
A flexible matching pattern (such as a trailing asterisk) that allows a range of addresses to match a single registered Redirect URI entry, useful but riskier if used too broadly.
Open Redirect
A vulnerability where an application can be tricked into sending sensitive data to an address it shouldn’t — precisely what strict Redirect URI validation is designed to prevent.
redirect_uri Parameter
The value an application actually sends along with its login request, specifying where it wants the user returned — this is what gets checked against the registered list.
It’s worth being precise about one common confusion: a Redirect URI is not the same thing as the application’s general website address. An application might have many pages, but only the specific address meant to receive the login response — usually a dedicated callback endpoint — needs to be registered as a Redirect URI. Registering broader addresses than necessary widens the attack surface without adding any real benefit.
A Redirect URI answers “where is Keycloak allowed to send login proof back to?” It is a security boundary, not simply a convenience setting for navigation — treating it as an afterthought is one of the most common real-world configuration mistakes.
BArchitecture & Components
The Redirect URI doesn’t operate alone — it’s one checkpoint inside a small ecosystem of cooperating components. Let’s map that ecosystem out.
Every Redirect URI setting belongs to a specific Client — an application registered inside a Keycloak Realm. Around that relationship sit the components responsible for requesting, validating, and using the redirect.
graph TD
APP["Application
(Client)"] -->|"1. Sends login request
with requested redirect_uri"| KC["Keycloak"]
KC -->|"2. Checks against"| LIST["Registered Redirect URIs
(Client Configuration)"]
LIST -->|"3. Match found"| KC
LIST -->|"3b. No match"| REJECT["Login Rejected"]
KC -->|"4. User authenticates"| U["User Browser"]
KC -->|"5. Sends auth code
to approved Redirect URI"| APP
APP -->|"6. Exchanges code for token"| KC
Fig 1 — How a requested Redirect URI is checked before any login proof is sent
Each labeled component in that diagram has a distinct job:
Application (Client)
Initiates the login flow and specifies which address it wants the user sent back to once authentication succeeds.
Keycloak
Receives the login request, checks the requested Redirect URI against the Client’s registered list, and only proceeds if it’s an approved match.
Registered Redirect URIs
The pre-configured list of approved addresses stored on the Client’s settings — the single source of truth Keycloak checks every request against.
User Browser
Carries the authentication request to Keycloak and, after a successful login, carries the response back to the approved Redirect URI.
Realm
The isolation space each Client — and therefore each Client’s own Redirect URI list — belongs to, kept entirely separate from other Realms.
Authorization Code / Token
The sensitive proof of login that actually travels to the Redirect URI — the exact reason this address needs to be tightly controlled.
Picture a hotel’s front desk handing over a room key only to someone standing at one of the hotel’s own verified checkout counters — never to someone waving from across the street claiming to be an employee. The registered Redirect URI list is that set of verified counters. No matter how convincingly a request claims to be legitimate, if the requested delivery address isn’t on the pre-approved list, the front desk simply won’t hand anything over.
An important architectural nuance: each Client in Keycloak maintains its own independent Redirect URI list. A mobile app, a web application, and an internal admin tool — even if built by the same team — are typically registered as separate Clients, each with a Redirect URI list scoped precisely to that application’s own actual callback addresses, rather than sharing one broad, loosely-defined list across everything.
CHow Redirect URI Validation Works Internally
Now let’s open the hood and see exactly how Keycloak decides whether a requested redirect address is acceptable.
When an application initiates a login request, it includes a parameter — commonly named redirect_uri — specifying exactly where it wants Keycloak to send the response. Before Keycloak does anything else with that request, it compares this requested value against the list of Redirect URIs registered for that specific Client. If no entry in the registered list matches, Keycloak refuses to proceed with the login at all, rather than silently falling back to some default or ignoring the mismatch.
Keycloak supports both exact-match Redirect URIs (an address must be identical, character for character) and pattern-based entries using a trailing wildcard, which allow a defined range of addresses — such as anything under a specific path — to match. Exact matches offer the tightest security; wildcards trade some of that precision for configuration flexibility, and should be scoped as narrowly as the application genuinely requires.
Once a match is confirmed, Keycloak proceeds with authentication, and — assuming the user successfully proves their identity — sends the resulting authorization code or token back to that verified address, and only that address. The application then typically exchanges this short-lived code for a full token through a separate, direct backend request, adding another layer of protection beyond the redirect check alone.
What Keycloak Checks
- Whether the requested redirect_uri exactly matches, or matches a registered wildcard pattern, for that specific Client
- Whether the Client itself is valid and enabled in the current Realm
- Whether any other required request parameters are present and well-formed
What Happens on a Mismatch
- Keycloak rejects the request outright, before any login screen is even shown
- No authorization code or token is issued to the unverified address
- The mismatch is typically recorded in Keycloak’s event logs for review
This strict, fail-closed behavior — reject by default unless there’s an explicit match — is what gives the Redirect URI setting its real protective value. A permissive or overly broad configuration undermines this protection just as effectively as having no check at all.
DData Flow & Lifecycle
Let’s trace one complete journey — from an application starting a login request, to the user landing back safely inside it, with a look at what happens when things go wrong.
sequenceDiagram
participant APP as Application
participant U as User Browser
participant KC as Keycloak
APP->>U: Redirect to Keycloak, requesting redirect_uri = https://app.example.com/callback
U->>KC: Arrive at Keycloak with login request
KC-->>KC: Check redirect_uri against registered list for this Client
alt Matches registered entry
KC-->>U: Show login page
U->>KC: Submit credentials
KC-->>U: Redirect back with authorization code
U->>APP: Deliver code to /callback
APP->>KC: Exchange code for token (backend request)
KC-->>APP: Issue signed token
else No match found
KC-->>U: Reject request — invalid redirect_uri
end
Fig 2 — A matched Redirect URI completes the login; a mismatch stops it before it starts
Notice the key detail: the rejection, when it happens, occurs before the user ever sees a login screen. Keycloak doesn’t authenticate the user first and then decide where to send them — it validates the destination first, precisely because the whole point is to prevent sensitive login proof from ever being generated for an unverified address in the first place.
Client Registration
An administrator registers the application as a Client and defines its list of allowed Redirect URIs during initial setup.
Login Request Initiated
The application redirects the user’s browser to Keycloak, including its intended redirect_uri as part of the request.
Validation
Keycloak checks the requested address against the Client’s registered list before doing anything else.
Authentication (if valid)
Only after a match is confirmed does Keycloak present the login screen and verify the user’s Credentials.
Response Delivery
Keycloak sends the authorization code or token exclusively to the verified, approved address.
Code Exchange
The application exchanges the short-lived code for a full token through a separate, direct backend call to Keycloak.
Ongoing Maintenance
As the application evolves — new environments, new domains — its Redirect URI list is updated deliberately, never left broader than necessary.
A Redirect URI that was appropriate during development — such as a broad wildcard covering an entire testing domain — is easy to forget about and carry unchanged into production, quietly leaving a far wider allowed destination range than the live application actually needs.
EAdvantages, Disadvantages & Trade-offs
Strict Redirect URI validation is a clear security win, but configuring it involves real trade-offs between precision and convenience.
Advantages
- Prevents sensitive login proof from ever being sent to an attacker-controlled address
- Fails closed by default — an unmatched request is rejected outright, not silently allowed through
- Scoped per Client, so one application’s configuration mistake doesn’t widen the attack surface for every other application
- Supports both exact matches and controlled wildcard patterns, balancing precision with practical flexibility
- Rejections are logged, giving administrators visibility into misconfigured or potentially malicious requests
Disadvantages & Trade-offs
- Overly broad wildcard patterns can quietly undermine the protection the setting is meant to provide
- Legitimate configuration changes — new environments, renamed domains — require deliberate updates to the Redirect URI list, adding operational overhead
- Development-time convenience settings are easy to accidentally leave in place for production
- Debugging a rejected login can be confusing for developers unfamiliar with exactly how the matching rules work
OWN REDIRECT LIST
LOGIN PROOF SENT
= WIDER ATTACK SURFACE
That last row captures the essential trade-off: the tighter and more precise a Redirect URI list, the stronger the protection — but also the more configuration discipline it demands as an application evolves across environments. Loosening the list “just to make development easier” is a common shortcut that quietly weakens the exact protection this setting exists to provide.
Real Consideration: Wildcards Are a Trade, Not a Free Convenience
A wildcard entry like an entire domain followed by a trailing match-anything pattern might save a few minutes of configuration work, but it also means any address under that domain — including ones an attacker might control through a misconfigured subdomain or an unrelated internal tool — could become a valid destination for login proof. Scoping wildcards as narrowly as the real application structure allows is almost always worth the extra few minutes.
FSecurity
The Redirect URI setting exists almost entirely for security reasons — so it’s worth understanding the specific attacks it defends against.
Exact-Match Redirect URIs
Registering the precise, full callback address rather than a broad pattern offers the strongest possible protection against redirect manipulation.
Narrowly Scoped Wildcards
When flexibility is genuinely needed, limiting a wildcard pattern to the smallest reasonable path or subdomain range keeps the protection largely intact.
HTTPS-Only Redirect URIs
Requiring registered addresses to use encrypted HTTPS connections prevents login proof from being transmitted in a form that could be intercepted over plain, unencrypted traffic.
Short-Lived Authorization Codes
Even with a correctly matched Redirect URI, the authorization code delivered there expires quickly, limiting the window in which it could be misused if somehow intercepted.
Environment-Specific Client Registration
Keeping development, staging, and production as separate Clients with their own tightly scoped Redirect URI lists prevents a loose development setting from ever reaching production.
Regular Configuration Review
Periodically reviewing each Client’s registered Redirect URIs catches stale, overly broad, or forgotten entries before they become a real exposure.
A well-known real-world attack class here is the open redirect exploit, where an attacker crafts a malicious login link pointing to a legitimate Keycloak instance but attempts to specify a redirect_uri under their own control. Strict Redirect URI validation is precisely what defeats this — the malicious address simply won’t match anything on the registered list, and the login attempt is rejected before any sensitive proof is ever generated.
Think of a company mailroom that only forwards sensitive internal documents to desks listed on an approved internal directory — never to a handwritten desk number scrawled on the outside of an incoming request, no matter how official that request looks. The approved directory is the registered Redirect URI list; refusing anything outside it is what keeps sensitive material from ending up somewhere it was never meant to go.
Decision
Register exact-match Redirect URIs wherever possible, reserving wildcard patterns only for cases where an application’s structure genuinely requires them, and scoping any wildcard as narrowly as possible.
Reasoning
Every character of flexibility added to a Redirect URI pattern is a character of potential attacker opportunity. Exact matches eliminate that ambiguity entirely wherever the application’s design allows it.
Trade-off Accepted
Slightly more configuration entries to maintain as an application adds new environments or callback paths, in exchange for eliminating an entire class of redirect-based attacks.
GMonitoring, Logging & Metrics
Because a rejected Redirect URI often signals either a configuration problem or an active attempt at abuse, it deserves consistent monitoring attention.
Keycloak logs login requests that fail Redirect URI validation, giving administrators a centralized way to notice both legitimate configuration drift — an application that changed domains without updating its registration — and genuinely suspicious activity, such as repeated attempts using unfamiliar, unregistered addresses.
| What Gets Logged | Why It Matters | Example Signal |
|---|---|---|
| Rejected redirect_uri mismatch | Flags either a misconfiguration or a potential attack attempt | Request for app.example.com Client with an unregistered redirect address |
| Redirect URI list changes | Tracks who widened or narrowed a Client’s allowed destinations, and when | Wildcard entry added to a previously exact-match-only Client |
| Repeated mismatches from one source | Can indicate automated probing against a Client’s login endpoint | Same IP address generating multiple invalid redirect_uri attempts |
| Successful logins by Client | Provides a baseline of normal redirect destinations actually in use | 99% of successful logins for a Client use one specific callback path |
A sudden cluster of redirect_uri mismatch rejections against a single Client, especially from varied or unfamiliar sources, is worth investigating — it can indicate someone actively probing for a gap in that Client’s Redirect URI configuration.
These logs also help catch configuration drift before it becomes a real incident — for example, noticing that a Client’s actual, day-to-day traffic never uses a broad wildcard entry that was configured “just in case,” which is a strong signal that entry could safely be narrowed or removed entirely.
HDesign Patterns & Anti-patterns
Years of real-world Keycloak deployments have surfaced Redirect URI habits that hold up well, and ones that reliably cause security gaps.
Exact-Match by Default
Starting every Client with precise, exact-match Redirect URI entries, and only introducing a wildcard when there’s a genuine, documented need for one.
Separate Clients Per Environment
Registering development, staging, and production as distinct Clients, each with its own tightly scoped Redirect URI list matching only that environment’s real addresses.
Periodic Redirect URI Audits
Regularly reviewing each Client’s registered list against its actual, current callback addresses, removing anything stale or no longer in use.
HTTPS Enforcement
Requiring every registered Redirect URI to use HTTPS, closing off the possibility of login proof traveling over an unencrypted connection.
Anti-pattern: Overly Broad Wildcards “Just in Case”
- Registering an entire domain with a broad trailing wildcard to avoid future configuration updates
- Never revisiting whether that broad pattern is actually needed once the application’s real structure is known
- Unintentionally widening the set of addresses login proof could be sent to, far beyond what the application genuinely uses
Anti-pattern: Development Settings Reaching Production
- Using the same Client, with the same loose Redirect URI list, across development and production environments
- Leaving convenience-driven, broad development entries in place after an application goes live
- Discovering the oversight only after an incident, rather than through a routine pre-launch review
One especially instructive anti-pattern is what security reviewers sometimes call “copy-paste Redirect URIs” — a new Client is set up by duplicating an existing one’s configuration, including its Redirect URI list, without checking whether those specific entries actually apply to the new application. Over time, this produces Clients carrying registered destinations that have nothing to do with what they actually use, quietly widening the overall attack surface across the deployment.
IBest Practices & Common Mistakes
A practical checklist distilled from real deployments — the habits that keep Redirect URI configuration tight and trustworthy.
Prefer Exact Matches Over Wildcards
Register the precise callback address whenever possible, reserving pattern-based entries for genuine, documented needs only.
Separate Clients by Environment
Keep development, staging, and production Redirect URI lists entirely separate, each scoped to that environment’s actual addresses.
Require HTTPS on Every Entry
Avoid registering plain, unencrypted addresses as Redirect URIs — sensitive login proof should never travel over an unprotected connection.
Audit Redirect URI Lists Periodically
Regularly compare each Client’s registered entries against what the application actually uses, removing anything stale or unnecessarily broad.
Avoid Copy-Pasting Configuration Blindly
When creating a new Client from an existing template, deliberately review and correct the Redirect URI list rather than assuming it already fits.
Treat Rejections as Signal, Not Just Noise
Investigate repeated Redirect URI mismatches rather than dismissing them purely as routine developer errors — some genuinely are attempted probing.
Registering a broad wildcard “temporarily” during initial development, then never revisiting it before the application goes live — turning a short-term convenience into a long-term, unreviewed security gap.
Assuming HTTPS enforcement elsewhere in the system automatically covers Redirect URI configuration too, and registering a plain, unencrypted address without noticing the gap.
JReal-World & Industry Examples
Redirect URI validation isn’t a theoretical concept — it’s quietly protecting real login flows across many kinds of applications.
Single-Page Web Applications
Modern browser-based applications typically register one or two precise callback paths as their Redirect URIs, matching exactly where their login-handling code lives, rather than broad domain-wide patterns.
Mobile Applications
Mobile apps often register custom URI schemes or app-specific deep links as their Redirect URIs, letting Keycloak hand login proof directly back to the native app rather than a browser page.
Multi-Environment Enterprise Deployments
Large organizations running separate development, staging, and production instances of the same application commonly register each as its own Client, keeping Redirect URI lists cleanly scoped per environment rather than sharing one broad configuration across all of them.
Third-Party Integration Platforms
Platforms that let external developers build integrations against a company’s systems often require each registered integration to specify its exact callback address upfront, precisely mirroring how Keycloak’s own Redirect URI validation works.
A particularly instructive real-world lesson comes from widely reported open-redirect vulnerabilities across the industry: in nearly every case, the root cause traces back to a login system validating the redirect destination too loosely, whether through an overly broad wildcard or a missing check entirely. This consistently reinforces why Redirect URI configuration deserves the same careful, security-first attention as any other core authentication setting, not an afterthought bolted on during initial application setup.
KFrequently Asked Questions
LSummary and Key Takeaways
A quick recap of everything this guide has covered — the mental model to carry forward.
A Redirect URI in Keycloak is the pre-approved address a user’s browser is allowed to be sent back to after a successful login, and it exists almost entirely as a security boundary. Keycloak checks every login request’s intended destination against a Client’s registered list before proceeding, refusing outright if there’s no match. Precise, exact-match entries offer the strongest protection; wildcards trade some of that precision for flexibility and should be scoped as narrowly as real application needs allow. Getting this setting right is a small configuration detail with an outsized security impact.
Key Takeaways
- A Redirect URI is a security boundary, not just a navigation setting: it decides where sensitive login proof is allowed to be sent.
- Validation happens before authentication: Keycloak checks the requested destination first, refusing invalid requests before any login screen appears.
- Each Client maintains its own independent Redirect URI list, keeping one application’s configuration mistakes from widening the attack surface elsewhere.
- Exact matches offer the strongest protection; wildcards trade precision for flexibility and should be scoped as narrowly as possible.
- Strict Redirect URI validation is what defeats open-redirect-style attacks, preventing login proof from reaching an attacker-controlled address.
- Development convenience settings are the most common real-world source of overly broad configuration, especially when they’re never revisited before going live.
- Periodic audits matter: comparing registered entries against actual application usage catches stale or unnecessarily broad configuration before it becomes a real exposure.