// Sign in with CodeB - ASP.NET Core (Microsoft.AspNetCore.Authentication.OpenIdConnect). // European Digital Identity Wallet users can also arrive via /logineu.html; // server-side treatment is identical. // [oidc-signin-cookbook 2026-07-23] // dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect; var builder = WebApplication.CreateBuilder(args); builder.Services .AddAuthentication(o => { o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(o => { o.Authority = "https://"; o.ClientId = ""; o.ClientSecret = ""; // omit for public clients o.ResponseType = OpenIdConnectResponseType.Code; o.UsePkce = true; // S256 o.CallbackPath = "/oidc-callback"; o.Scope.Add("openid"); o.Scope.Add("profile"); o.Scope.Add("email"); o.GetClaimsFromUserInfoEndpoint = true; o.SaveTokens = true; // Discovery -> /.well-known/openid-configuration; id_token // signature verified against JWKS automatically. }); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapGet("/", (HttpContext ctx) => ctx.User.Identity?.IsAuthenticated == true ? Results.Json(new { sub = ctx.User.FindFirst("sub")?.Value, name = ctx.User.FindFirst("preferred_username")?.Value, role = ctx.User.FindFirst("role")?.Value ?? "user" }) : Results.Challenge() ); app.Run();