Skip to content

Keycloak Magic Link MFA Setup with Mideye

Keycloak is an open-source identity and access management (IAM) platform that provides single sign-on (SSO) via OpenID Connect (OIDC), SAML 2.0, and OAuth 2.0.

Mideye Server can provide multi-factor authentication (MFA) for Keycloak using the Mideye Auth API. A custom Java authenticator (SPI) calls the Mideye REST endpoint during the login flow, sends a push notification or SMS to the user’s phone, and waits for the response.

Web App(your app)Keycloak(IdP)Mideye Server(MFA) OIDC ID TokenHTTPSAccept / Reject UserKeycloakMideye Server 1. Login (username + password)2. GET /api/sfwa/auth?msisdn=+46701234567 3. Push or SMS to phone4. User taps Accept5. {"code":"TOUCH_ACCEPTED"}6. Success (ID token)
  1. User clicks “Sign in” → application redirects to Keycloak
  2. User enters username + password
  3. The custom authenticator reads the user’s phone number from a Keycloak user attribute
  4. It calls GET /api/sfwa/auth?msisdn=<phone> on the Mideye Server
  5. Mideye sends a push notification (Mideye+) or SMS magic link to the user
  6. The user taps Accept (or the API times out / user rejects)
  7. Keycloak issues OIDC tokens and redirects back to the application
  • Keycloak 22 or later (tested with 26.x)
  • Mideye Server 5 or 6 with a configured Magic Link endpoint
  • API key generated for that endpoint
  • Network access from Keycloak to Mideye Server on TCP port 8443 (HTTPS)
  • Java 17+ to build the SPI (or use the pre-built JAR)

Step 1: Build or download the authenticator SPI

Section titled “Step 1: Build or download the authenticator SPI”

The authenticator SPI source code and a pre-built JAR are available on GitHub:

Download mideye-keycloak-spi-1.0.0.jar from keycloak/providers/ in the repository and place it in Keycloak’s providers/ directory.

Terminal window
cd keycloak/spi
mvn clean package -DskipTests
cp target/mideye-keycloak-spi-1.0.0.jar /opt/keycloak/providers/

After adding the JAR, rebuild Keycloak’s provider cache:

Terminal window
/opt/keycloak/bin/kc.sh build

Restart Keycloak for the new provider to take effect.

Step 2: Register the phone number attribute

Section titled “Step 2: Register the phone number attribute”

The authenticator reads each user’s phone number from a Keycloak user attribute. You must register this attribute in the realm’s User Profile schema.

  1. In the Keycloak admin console, go to Realm settings → User profile
  2. Click Create attribute
  3. Set:
    • Attribute name: phoneNumber (or your preferred name)
    • Display name: Phone Number
    • Who can edit: Admin, User
    • Who can view: Admin, User
  4. Save

Then set the phone number on each user:

  1. Go to Users → select a user → Attributes tab
  2. Set phoneNumber to the user’s international phone number (e.g., +46701234567)
  1. In the Keycloak admin console, go to Authentication → Flows
  2. Click Create flow
  3. Enter a name (e.g., Browser with Mideye MFA) and click Create
  4. Click Add execution and add Cookie (set to Alternative)
  5. Click Add sub-flow, name it Forms (set to Alternative)
  6. Inside the Forms sub-flow:
    • Click Add execution → add Username Password Form (set to Required)
    • Click Add execution → add Mideye Magic Link Authenticator (set to Required)

The resulting flow should look like:

ExecutionRequirement
CookieAlternative
Forms (sub-flow)Alternative
  ↳ Username Password FormRequired
  ↳ Mideye Magic Link AuthenticatorRequired
  1. In the flow editor, click the ⚙ Settings icon on the Mideye Magic Link Authenticator row
  2. Configure the following:
SettingDescriptionExample
Mideye Server URLBase URL of the Magic Link endpointhttps://mideye.example.com:8443/api/sfwa
API KeyThe API key for the endpointyour-api-key
Phone AttributeKeycloak user attribute containing the phone numberphoneNumber
Timeout (seconds)How long to wait for user response60
Skip TLS VerificationDisable certificate validation (dev/test only)false
  1. Click Save
  1. Go to Authentication → Flows
  2. In the Browser flow dropdown at the top, select your new flow (Browser with Mideye MFA)
  3. Click Bind flow (or use the action menu → Bind flow)

New browser logins to this realm will now require Mideye MFA after the password step.

A complete Docker Compose environment is available in the GitHub repository. It includes Keycloak, a database, the pre-built SPI JAR, and a test OIDC web page:

Terminal window
git clone https://github.com/mideye/mideye-magic-link-examples.git
cd mideye-magic-link-examples/keycloak
cp .env.example .env # edit with your Mideye Server details
docker compose up -d

Then open http://localhost:8080 and sign in to the admin console to configure the flow.

  • Verify the JAR is in Keycloak’s providers/ directory and that you ran kc.sh build
  • Check that the authentication flow is bound to the browser flow
  • Confirm the Mideye Magic Link Authenticator execution is set to Required

Authentication fails with connection error

Section titled “Authentication fails with connection error”
  • Verify network connectivity from Keycloak to Mideye Server on port 8443
  • Check that the Mideye Server URL is correct (include /api/sfwa path)
  • For self-signed certificates in test environments, set Skip TLS Verification to true
  • Confirm the user has the phoneNumber attribute set (with international prefix)
  • Check that the Phone Attribute setting matches the attribute name exactly
  • Increase the timeout value in the authenticator settings
  • Verify the user’s phone number is enrolled in Mideye Server
  • Check Mideye Server logs for delivery failures