Skip to content

andreas-valtech/Aspire.OptimizelyContentDeliveryAuth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aspire + Optimizely CMS 12 + Keycloak

This repository landed on exactly the local setup I wanted to try: Optimizely CMS 12, SQL Server and Keycloak in the same Aspire-orchestrated development loop, with a web application that handles both interactive login and machine-to-machine calls.

It started smaller than that. At first it was mostly a way to poke at several things I had been curious about at the same time: Aspire, Keycloak, Testcontainers and what Codex is actually good for as a project grows while you think out loud. The result was not a DXP or CMS 13 exercise, but something more grounded and, for me, more useful: getting CMS 12, the database and the identity server to start up together, importing a ready-made realm and giving a developer a reproducible way to test both auth flows locally.

While I was working on this, Avantibit Alloy + Aspire Scaffold also appeared. That post is close in spirit, but the focus here is different. There is a clearer path towards Alloy, DXP and CMS 13-like reasoning there. Here the goal is much narrower: a working local CMS 12 environment where SQL Server and Keycloak run in the same setup and where authentication can actually be tested directly.

What the solution does

  • Aspire starts SQL Server and Keycloak together with the web application.
  • Keycloak imports the realm configuration from Aspire.OptimizelyContentDeliveryAuth.AppHost/realm-export.json.
  • The web application uses OIDC + cookie for interactive browser login.
  • The same web application accepts bearer tokens for machine-to-machine calls.
  • Two .http files show how to test the flows locally.

Architecture in brief

  • Aspire.OptimizelyContentDeliveryAuth.AppHost Orchestrates SQL Server, Keycloak and the web application.
  • Aspire.OptimizelyContentDeliveryAuth.Web The CMS 12 application.
  • Aspire.OptimizelyContentDeliveryAuth.AppHost/realm-export.json The versioned Keycloak export that makes the setup reproducible.
  • login.http Simple entry point for interactive login.
  • machine-to-machine.http Fetches a token via client_credentials and calls the same protected endpoint.

Authentication setup

The important thing in the web application is that authentication is no longer an either-or choice.

  • If the request arrives with Authorization: Bearer ..., JWT bearer is used.
  • If the request comes from a browser without a bearer token, a cookie is used as the local session.
  • If the browser is not already logged in, an OpenID Connect challenge against Keycloak is triggered.

This means https://localhost:5000/userinfo works in both cases:

  • The browser is sent to Keycloak and returns with a cookie session.
  • A client with an access token can call the same endpoint directly.

Prerequisites

  • .NET 10 SDK for AppHost and Aspire tooling
  • .NET 8 SDK for the web project
  • Docker Desktop
  • HTTPS development certificate for ASP.NET Core

Starting the solution

Run from the repository root:

 dotnet run --project .\Aspire.OptimizelyContentDeliveryAuth.AppHost

When AppHost starts, the following happens:

  1. SQL Server starts in a container.
  2. Keycloak starts in a container.
  3. The optimizely realm is imported from the export file.
  4. The web application starts and uses the same local environment.

Initial login credentials

Keycloak admin

  • Username: admin
  • Password: abc123

This is for local development only and comes from the AppHost configuration.

Interactive demo user

The versioned realm export also includes a regular test user:

  • Username: editor
  • Password: Passw0rd!

Machine-to-machine client

The realm export contains a confidential client for client_credentials:

  • Client id: optimizely-api
  • Client secret: d4f9a2b7-c3e1-4f8a-b6d2-9e7c3a1f5b8d

Important: All credentials above are for local development only. They are hardcoded in realm-export.json, http-client.env.json and AppHost.cs to make it easy to get started. Never use these values in a shared, public or production-adjacent environment. Replace passwords and client secrets with strong, unique values if you expose the environment beyond your local machine.

Interactive browser client

The OIDC client for browser login is:

  • Client id: optimizely-web
  • Redirect URI: https://localhost:5000/signin-oidc

Testing interactive login

Use login.http.

The file does two things:

  1. Starts login via the web application at /login.
  2. Fetches /userinfo after the browser session is established.

Practical flow:

  1. Start the solution with AppHost.
  2. Open login.http.
  3. Run the first request in browser mode.
  4. Log in to Keycloak with editor / Passw0rd!.
  5. Then run the request against /userinfo.

You should then receive the name, authentication type and claims from the established session.

Testing machine-to-machine

Use machine-to-machine.http together with http-client.env.json.

The file contains two requests:

  1. Fetch an access token from Keycloak via client_credentials.
  2. Call https://localhost:5000/userinfo with the bearer token.

If your HTTP client does not automatically carry over access_token between requests, you can paste the token manually into the second request. The point here is that the entire test flow is documented and version-controlled in the .http files rather than living in loose notes.

Why the realm export matters

realm-export.json is the key to making this feel like a real example rather than a demo you have to click together by hand every time.

It contains:

  • the optimizely realm
  • the browser client optimizely-web
  • the machine client optimizely-api
  • a demo user for interactive login

This means the setup can be cloned, started and understood without first building up Keycloak manually in the admin UI.

Why HTTP files instead of just screenshots

I wanted the auth flows to be easy to try again and easy to read. The .http files therefore became a better documentation surface than just text:

  • they show exact endpoints
  • they show which flow is used
  • they can be re-run when the setup changes
  • they serve as living notes for the next iteration

A few words about Testcontainers, Aspire and Codex

The project became a small laboratory for several ideas at once.

  • Testcontainers was part of the thinking when I explored how much could be verified automatically.
  • Aspire ultimately became the natural hub for the local runtime experience.
  • Keycloak became the identity piece I wanted to bring into the same loop.
  • Codex became the tool that helped bring together implementation, authentication setup and documentation while the project was still taking shape.

That is perhaps also the most accurate description of the repository: not a finished production pattern for everything, but a well-functioning local playground for trying several modern building blocks together.

Files to look at

  • Aspire.OptimizelyContentDeliveryAuth.AppHost/AppHost.cs
  • Aspire.OptimizelyContentDeliveryAuth.AppHost/realm-export.json
  • Aspire.OptimizelyContentDeliveryAuth.Web/Startup.cs
  • Aspire.OptimizelyContentDeliveryAuth.Web/UserInformationController.cs
  • login.http
  • machine-to-machine.http
  • http-client.env.json

Troubleshooting

Keycloak seems to ignore the realm import

Because the containers use persistent volumes, stale state may survive between runs. If you want to start completely fresh, you can remove the persistent Keycloak volume and restart AppHost.

Login redirects to the wrong URL

Verify that the web application is running on https://localhost:5000 and that the optimizely-web Keycloak client still has https://localhost:5000/signin-oidc as the redirect URI.

Bearer token is rejected

Confirm that the token was issued by the optimizely realm and that you are using the optimizely-api client with client_credentials.

Summary

This repository does not focus on DXP, not on CMS 13, and not on covering every possible Optimizely variant. It focuses on something simpler and more concrete: getting CMS 12, SQL Server and Keycloak to live in the same local Aspire setup, with a version-controlled realm export, .http files for testing and an authentication configuration that handles both humans and machines.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages