Skip to content

Add a Blazor OIDC sample with Aspire #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 18, 2023
Merged

Conversation

halter73
Copy link
Member

@halter73 halter73 commented Dec 9, 2023

.NET 8 Blazor web app with OIDC

This sample features:

  • A .NET 8 Blazor Web App with global auto interactivty.
    • This adds a PersistingAuthenticationStateProvider and PersistentAuthenticationStateProvider services to the
      server and client blazor apps respectively to capture authentication state and flow it between the server and client.
  • OIDC authentication with Microsoft Entra without using any Entra-specific packages.
    • The goal is that this sample can be used as a starting point for any OIDC authentication flow.
  • A minimal API backend using the JwtBearerHandler to validate JWT tokens saved by the Blazor app in the sign-in cookie.
  • The BFF pattern using Aspire service discovery and YARP for proxying the requests to /weatherforecast on the backend with the access_token stored in the cookie.
  • Automatic non-interactive token refresh with the help of a custom CookieOidcRefresher.

Running the sample

  1. Configure the OIDC provider. If using Microsoft Entra, you follow along with the comments in Program.cs. Here's an excerpt:

    // Save the access and refresh tokens in the cookie, so we can authenticate requests to the "weatherapi" service.
    // The offline_access scope is required for the refresh token.
    oidcOptions.SaveTokens = true;
    oidcOptions.Scope.Add("offline_access");
    // The "Weather.Get" scope is configured in the Azure or Entra portal under "Expose an API".
    // This is necessary for MinimalApiJwt to be able to validate the access token with AddBearerJwt.
    oidcOptions.Scope.Add("https://{directory-name}.onmicrosoft.com/{client-id}/Weather.Get");
    
    // The "common" authority should be used for multi-tenant applications. You can also use the common
    // authority for single-tenant applications, but that requires a custom IssuerValidator as shown in the comments below.
    //oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    oidcOptions.Authority = "https://login.microsoftonline.com/{tenant-id}/v2.0/";
    oidcOptions.ClientId = "{client-id}";
    
    // ClientSecret should not be compiled into the application assembly or checked into source control.
    // Instead consider user-secrets, Azure KeyVault and/or environment variables. Authentication scheme configuration
    // is automatically read from builder.Configuration["Authentication:Schemes:{SchemeName}:{PropertyName}"],
    // so ClientSecret will be read from "Authentication:Schemes:MicrosoftOidc:ClientSecret" configuration.
    //oidcOptions.ClientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    
    // This configures the OIDC handeler to do authorization code flow only. Implicit grants and hybrid flows are unnecessary
    // in this mode. You do not need to check either box for the authorization endpoint to return access tokens or ID tokens.
    // The OIDC handler will automatically request the appropriate tokens using the code returned from the authorization endpoint.
    oidcOptions.ResponseType = "code";
  2. Navigate to Aspire/Aspire.AppHost and dotnet run. This should start both the BlazorWebOidc`` and MinimalApiJwt` projects.

@guardrex @JeremyLikness

This is intended to cover scenario number 2 in dotnet/aspnetcore#49668.

Copy link
Collaborator

@guardrex guardrex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Devs will have a fantastic time getting started with this sample.

I'll write a companion article to go with this and ping you guys for review. I hope to write it this week, but it might get pushed to next week.

Copy link
Member

@JeremyLikness JeremyLikness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely love this sample. The inline comments, use of Aspire, Microsoft Entra support, let's get it out there!!!!

@guardrex
Copy link
Collaborator

Merging now ... I'll get on to the article to go with this as soon as I can, but I'm currently mired in 8.0 snippet sample cross-links, which will take the rest of this week. I'll get on the new article as soon as I can in early '24.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants