| File: Program.cs | Web Access |
| Project: src\playground\EntraId\EntraId.Web\EntraId.Web.csproj (EntraId.Web) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net; using System.Text; using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Identity.Web; var builder = WebApplication.CreateBuilder(args); // Add service defaults & Aspire client integrations. builder.AddServiceDefaults(); // The AppHost's WithReference(entraWeb) fills in the AzureAd section with the tenant and client IDs. builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration); builder.Services.AddAuthorization(); builder.Services.AddAntiforgery(); var app = builder.Build(); // The sign-in handler builds the redirect URI from the request URL, and README.md registers only the HTTPS one. app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) => { if (context.User.Identity is not { IsAuthenticated: true } identity) { return Page("Entra ID playground", """ <p>You're not signed in.</p> <p><a href="/signin">Sign in with Microsoft Entra ID</a></p> """); } var antiforgeryTokens = antiforgery.GetAndStoreTokens(context); return Page("Entra ID playground", $""" <p>Signed in as <strong>{WebUtility.HtmlEncode(identity.Name)}</strong>.</p> <form method="post" action="/signout"> <input type="hidden" name="{antiforgeryTokens.FormFieldName}" value="{antiforgeryTokens.RequestToken}"> <button type="submit">Sign out</button> </form> """); }); app.MapGet("/signin", () => Results.Challenge(new AuthenticationProperties { RedirectUri = "/" })); app.MapPost("/signout", async (HttpContext context, IAntiforgery antiforgery) => { // The form on the home page carries an antiforgery token, so another site can't sign the user out. if (!await antiforgery.IsRequestValidAsync(context)) { return Results.BadRequest(); } // Signing out of both schemes deletes the app's cookie, then ends the Entra ID session. Entra ID sends the browser back // to /signout-callback-oidc, which must be a registered redirect URI, and the handler then redirects to "/". return Results.SignOut( new AuthenticationProperties { RedirectUri = "/" }, [CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme]); }); app.MapDefaultEndpoints(); app.Run(); static IResult Page(string title, string body) => Results.Content($""" <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>{title}</title> </head> <body> <h1>{title}</h1> {body} </body> </html> """, "text/html", Encoding.UTF8);