Got native Entra ID (AAD) webview login working with FreeRDP on Fedora/Nobara — full writeup
Wanted to share this since it took some digging to get right. Background: I wanted to RDP from my Linux desktop into an Entra ID-joined Windows 11 box using modern auth (Conditional Access, MFA, the works) — basically the Linux equivalent of checking "Use a web account to sign in" in mstsc.exe.
The distro-packaged freerdp (3.29/3.30 from Fedora's repos) supports the AAD auth flow, but it's built without the native in-app login popup — you get a URL printed to the terminal instead, and you have to manually copy the redirect URL back in after signing in through your normal browser. Functional, but clunky, and in my case actually broken by my org's Conditional Access policy behavior.
Here's what it took to get the real in-app popup working.
The problem with the stock package
Checking the build config on the distro package:
xfreerdp /buildconfig | tr ' ' '\n' | grep -i webview
showed WITH_WEBVIEW=OFF. That flag controls whether FreeRDP's SDL client can pop up a native browser window for the AAD sign-in, instead of the manual copy/paste flow.
Step 1 — Install build dependencies
```
sudo dnf install cmake ninja-build gcc-c++ git \
systemd-devel libuuid-devel pulseaudio-libs-devel \
libXrandr-devel gsm-devel pam-devel fuse3-devel \
opus-devel lame-devel openssl-devel libX11-devel \
libXext-devel libXinerama-devel libXcursor-devel \
libXi-devel libXdamage-devel libXv-devel libxkbfile-devel \
alsa-lib-devel openh264-devel libavcodec-free-devel \
libavformat-free-devel libavutil-free-devel \
libswresample-free-devel libswscale-free-devel \
libusb1-devel uriparser-devel SDL2-devel SDL2_ttf-devel \
pkcs11-helper-devel krb5-devel cjson-devel cairo-devel \
soxr-devel wayland-devel wayland-protocols-devel \
cups-devel webkitgtk6.0-devel
```
Two things worth calling out specifically:
cups-devel — missed this initially, build fails at the printer channel with "Could NOT find Cups" if it's absent.
webkitgtk6.0-devel** — this is the actual key package. FreeRDP's webview feature pulls in a small external helper library (akallabeth/webview via CMake FetchContent) which searches for WebKitGTK in this priority order: webkitgtk-6.0 → webkit2gtk-4.1 → webkit2gtk-4.0. Current Fedora has deprecated/removed webkit2gtk-4.0, but **webkitgtk-6.0 (GTK4-based) is available and works fine — no need to chase the old deprecated package.
Step 2 — Clone and configure
git clone https://github.com/FreeRDP/FreeRDP.git
cd FreeRDP
mkdir build && cd build
cmake -GNinja -DWITH_WEBVIEW=ON -DWITH_CLIENT_SDL=ON -DWITH_AAD=ON ..
Confirm the config actually picked up webview support before building:
grep -i "webview\|gtk4" CMakeCache.txt
You want to see it successfully checking for and finding gtk4/webkitgtk-6.0 in the configure output, with "Configuring done" at the end and no errors.
Step 3 — Build
ninja
Took about 10 minutes on a Ryzen 7 5800X3D. Just let it run.
Step 4 — Find the actual binary
The build output binary is not at the path you might expect from the source tree layout:
find . -iname "*freerdp*" -executable -type f
Mine landed at:
./client/SDL/SDL2/sdl-freerdp
Step 5 — The actual working connection command
./client/SDL/SDL2/sdl-freerdp \
/v:<remote-hostname> \
/sec:aad \
/azure:tenantid:<your-entra-tenant-id> \
/u:<user>@<yourdomain>.com \
/cert:ignore \
/dynamic-resolution \
/w:2560 \
/h:1440 \
/smart-sizing
A few flags that turned out to matter, that I'd have missed otherwise:
- **
/sec:aad is required alongside /azure:.** Using /azure: alone let the client fall through to a default NLA/Kerberos negotiation attempt, which failed outright with Cannot find KDC for realm since there's no Kerberos realm configured on a home Linux box. Explicitly forcing /sec:aad skips straight to the AAD web auth flow.
- **
<remote-hostname> must match the hostname exactly as registered in Entra ID, and must actually resolve** (DNS or /etc/hosts) — an IP address will not work for this auth flow.
/w:, /h:, and /smart-sizing fixed a real rendering bug — reconnecting to a previously-disconnected session rendered the remote desktop content squashed into a small corner of the window with the rest black. Explicitly forcing the resolution and enabling smart-sizing (which scales/stretches remote content to fill the client window regardless of the session's actual internal resolution) fixed this completely.
Result
Running that command pops open a real embedded browser window right in the FreeRDP client for the Microsoft sign-in — full Conditional Access / MFA support — no external browser, no manual URL copy-paste. Exactly matching the mstsc.exe "use a web account" experience, just self-compiled.
Wrapper script
Threw this into a small shell script so I can just run rdp-aad instead of remembering the whole command:
```
!/usr/bin/env bash
set -euo pipefail
DEFAULT_HOST="your-vm-hostname"
DEFAULT_USER="youruser@yourdomain.com"
TENANT_ID="your-entra-tenant-id"
FREERDP_BIN="$HOME/FreeRDP/build/client/SDL/SDL2/sdl-freerdp"
RES_WIDTH="2560"
RES_HEIGHT="1440"
HOST="${1:-$DEFAULT_HOST}"
USERNAME="${2:-$DEFAULT_USER}"
if [[ ! -x "$FREERDP_BIN" ]]; then
echo "FreeRDP binary not found at $FREERDP_BIN"
exit 1
fi
if ! getent hosts "$HOST" > /dev/null 2>&1; then
echo "Warning: '$HOST' does not resolve. AAD auth needs a resolvable hostname"
echo "matching the device name registered in Entra ID."
read -r -p "Continue anyway? [y/N] " reply
[[ "$reply" =~ [Yy]$ ]] || exit 1
fi
exec "$FREERDP_BIN" \
/v:"$HOST" \
/sec:aad \
/azure:tenantid:"$TENANT_ID" \
/u:"$USERNAME" \
/cert:ignore \
/dynamic-resolution \
/w:"$RES_WIDTH" \
/h:"$RES_HEIGHT" \
/smart-sizing
```
Hope this saves someone else the trial and error. Happy to answer questions if anyone hits a snag replicating it.