Blazor WebAssembly 3.2.0 Preview 2 release now available

Daniel

A new preview update of Blazor WebAssembly is now available! Here’s what’s new in this release:

  • Integration with ASP.NET Core static web assets
  • Token-based authentication
  • Improved framework caching
  • Updated linker configuration
  • Build Progressive Web Apps

Get started

To get started with Blazor WebAssembly 3.2.0 Preview 2 install the latest .NET Core 3.1 SDK.

NOTE: Version 3.1.102 or later of the .NET Core SDK is required to use this Blazor WebAssembly release! Make sure you have the correct .NET Core SDK version by running dotnet --version from a command prompt.

Once you have the appropriate .NET Core SDK installed, run the following command to install the update Blazor WebAssembly template:

dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview2.20160.5

That’s it! You can find additional docs and samples on https://blazor.net.

Upgrade an existing project

To upgrade an existing Blazor WebAssembly app from 3.2.0 Preview 1 to 3.2.0 Preview 2:

  • Update your package references and namespaces as described below:
    • Microsoft.AspNetCore.Blazor -> Microsoft.AspNetCore.Components.WebAssembly
    • Microsoft.AspNetCore.Blazor.Build -> Microsoft.AspNetCore.Components.WebAssembly.Build
    • Microsoft.AspNetCore.Blazor.DevServer -> Microsoft.AspNetCore.Components.WebAssembly.DevServer
    • Microsoft.AspNetCore.Blazor.Server -> Microsoft.AspNetCore.Components.WebAssembly.Server
    • Microsoft.AspNetCore.Blazor.HttpClient -> Microsoft.AspNetCore.Blazor.HttpClient (unchanged)
    • Microsoft.AspNetCore.Blazor.DataAnnotations.Validation -> Microsoft.AspNetCore.Components.DataAnnotations.Validation
    • Microsoft.AspNetCore.Blazor.Mono -> Microsoft.AspNetCore.Components.WebAssembly.Runtime
    • Mono.WebAssembly.Interop -> Microsoft.JSInterop.WebAssembly
  • Update all Microsoft.AspNetCore.Components.WebAssembly.* package references to version 3.2.0-preview2.20160.5.
  • In Program.cs add a call to builder.Services.AddBaseAddressHttpClient().
  • Rename BlazorLinkOnBuild in your project files to BlazorWebAssemblyEnableLinking.
  • If your Blazor WebAssembly app is hosted using ASP.NET Core, make the following updates in Startup.cs in your Server project:
    • Rename UseBlazorDebugging to UseWebAssemblyDebugging.
    • Remove the calls to services.AddResponseCompression and app.UseResponseCompression() (response compression is now handled by the Blazor framework).
    • Replace the call to app.UseClientSideBlazorFiles<Client.Program>() with app.UseBlazorFrameworkFiles().
    • Replace the call to endpoints.MapFallbackToClientSideBlazor<Client.Program>("index.html") with endpoints.MapFallbackToFile("index.html").

Hopefully that wasn’t too painful!

NOTE: The structure of a published Blazor WebAssembly app has also changed as part of this release, which may require you to update how you deploy your apps. See the “Integration with ASP.NET Core static web assets” section below for details.

Integration with ASP.NET Core static web assets

Blazor WebAssembly apps now integrate seamlessly with how ASP.NET Core handles static web assets. Blazor WebAssembly apps can use the standard ASP.NET Core convention for consuming static web assets from referenced projects and packages: _content/{LIBRARY NAME}/{path}. This allows you to easily pick up static assets from referenced component libraries and JavaScript interop libraries just like you can in a Blazor Server app or any other ASP.NET Core web app.

Blazor WebAssembly apps are also now hosted in ASP.NET Core web apps using the same static web assets infrastructure. After all, a Blazor WebAssembly app is just a bunch of static files!

This integration simplifies the startup code for ASP.NET Core hosted Blazor WebAssembly apps and removes the need to have an assembly reference from the server project to the client project. Only the project reference is needed, so setting ReferenceOutputAssembly to false for the client project reference is now supported.

Building on the static web assets support in ASP.NET Core also enables new scenarios like hosting ASP.NET Core hosted Blazor WebAssembly apps in Docker containers. In Visual Studio you can add docker support to your Blazor WebAssembly app by right-clicking on the Server project and selecting Add > Docker support.

As a result of this change, the structure of the published output of a Blazor WebAssembly app is now more consistent with other ASP.NET Core apps. A Blazor WebAssembly app is now published to the /bin/Release/netstandard2.1/publish/wwwroot folder (a dist folder is no longer generated). To publish a standalone Blazor WebAssembly app as a static site, copy the contents of the published wwwroot folder to your static site host. If the Blazor WebAssembly app is hosted in an ASP.NET Core app, the client Blazor WebAssembly app is published into the wwwroot folder of the published server app just like any other static web asset.

Token-based authentication

Blazor WebAssembly now has built-in support for token-based authentication.

Blazor WebAssembly apps are secured in the same manner as Single Page Applications (SPAs). There are several approaches for authenticating users to SPAs, but the most common and comprehensive approach is to use an implementation based on the OAuth 2.0 protocol, such as OpenID Connect (OIDC). OIDC allows client apps, like a Blazor WebAssembly app, to verify the user identity and obtain basic profile information using a trusted provider.

Using the Blazor WebAssembly project template you can now quickly create apps setup for authentication using:

  • ASP.NET Core Identity and IdentityServer
  • An existing OpenID Connect provider
  • Azure Active Directory

Authenticate using ASP.NET Core Identity and IdentityServer

Authentication for Blazor WebAssembly apps can be handled using ASP.NET Core Identity and IdentityServer. ASP.NET Core Identity handles authenticating users while IdentityServer handles the necessary protocol endpoints.

To create a Blazor WebAssembly app setup with authentication using ASP.NET Core Identity and IdentityServer run the following command:

dotnet new blazorwasm --hosted --auth Individual -o BlazorAppWithAuth1

If you’re using Visual Studio, you can create the project by selecting the “ASP.NET Core hosted” option and the selecting “Change Authentication” > “Individual user accounts”.

Blazor authentication

Run the app and try to access the Fetch Data page. You’ll get redirected to the login page.

Blazor login

Register a new user and log in. You can now access the Fetch Data page.

Fetch data authorized

The Server project is configured to use the default ASP.NET Core Identity UI, as well as IdentityServer, and JWT authentication:

// Add the default ASP.NET Core Identity UI
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

// Add IdentityServer with support for API authorization
services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

// Add JWT authentication
services.AddAuthentication()
    .AddIdentityServerJwt();

The Client app is registered with IdentityServer in the appsettings.json file:

"IdentityServer": {
  "Clients": {
    "BlazorAppWithAuth1.Client": {
      "Profile": "IdentityServerSPA"
    }
  }
},

In the Client project, the services needed for API authorization are added in Program.cs:

builder.Services.AddApiAuthorization();

In FetchData.razor the IAccessTokenProvider service is used to acquire an access token from the server. The token may be cached or acquired without the need of user interaction. If acquiring the token succeeds, it is then applied to the request for weather forecast data using the standard HTTP Authorization header. If acquiring the token silently fails, the user is redirected to the login page:

protected override async Task OnInitializedAsync()
{
    var httpClient = new HttpClient();
    httpClient.BaseAddress = new Uri(Navigation.BaseUri);

    var tokenResult = await AuthenticationService.RequestAccessToken();

    if (tokenResult.TryGetToken(out var token))
    {
        httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.Value}");
        forecasts = await httpClient.GetJsonAsync<WeatherForecast[]>("WeatherForecast");
    }
    else
    {
        Navigation.NavigateTo(tokenResult.RedirectUrl);
    }
}

For additional details on using Blazor WebAssembly with ASP.NET Core Identity and IdentityServer see Secure an ASP.NET Core Blazor WebAssembly hosted app with Identity Server

Authenticate using an existing OpenID Connect provider

You can setup authentication for a standalone Blazor WebAssembly using any valid OIDC provider. Once you’ve registered your app with the OIDC provider you configure the Blazor WebAssembly app to use that provider by calling AddOidcAuthentication in Program.cs:

builder.Services.AddOidcAuthentication(options =>
{
    options.ProviderOptions.Authority = "{AUTHORITY}";
    options.ProviderOptions.ClientId = "{CLIENT ID}";
});

You can create a standalone Blazor WebAssembly app that uses a specific OIDC provider for authentication using the following command:

dotnet new blazorwasm --auth Individual --client-id "{CLIENT ID}" --authority "{AUTHORITY}"

For more details on configuring authentication for a standalone Blazor WebAssembly app see Secure an ASP.NET Core Blazor WebAssembly standalone app with the Authentication library

Authenticate using Azure AD & Azure AD B2C

You can also setup Blazor WebAssembly apps to use Azure Active Directory (Azure AD) or Azure Active Directory Business-to-Customer (Azure AD B2C) for authentication. When authenticating using Azure AD or Azure AD B2C authentication is handled using the new Microsoft.Authentication.WebAssembly.Msal library, which is based on the Microsoft Authentication Library (MSAL.js).

To learn how to setup authentication for Blazor WebAssembly app using Azure AD or Azure AD B2C see:

Additional authentication resources

This is just a sampling of the new authentication capabilities in Blazor WebAssembly. To learn more about how Blazor WebAssembly supports authentication see Secure ASP.NET Core Blazor WebAssembly.

Improved framework caching

If you look at the network trace of what’s being download for a Blazor WebAssembly app after it’s initially loaded, you might think that Blazor WebAssembly has been put on some sort of extreme diet:

Blazor network

Whoa! Only 159kB? What’s going on here?

When a Blazor WebAssembly app is initially loaded, the runtime and framework files are now stored in the browser cache storage:

Blazor cache

When the app loads, it first uses the contents of the blazor.boot.json to check if it already has all of the runtime and framework files it needs in the cache. If it does, then no additional network requests are necessary.

You can still see what the true size of the app is during development by checking the browser console:

Blazor loaded resources

Updated linker configuration

You may notice with this preview release that the download size of the app during development is now a bit larger, but build times are faster. This is because we no longer run the .NET IL linker during development to remove unused code. In previous Blazor previews we ran the linker on every build, which slowed down development. Now we only run the linker for release builds, which are typically done as part of publishing the app. When publishing the app with a release build (dotnet publish -c Release), the linker removes any unnecessary code and the download size is much more reasonable (~2MB for the default template).

If you prefer to still run the .NET IL linker on each build during development, you can turn it on by adding <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> to your project file.

Build Progressive Web Apps with Blazor

A Progressive Web App (PWA) is a web-based app that uses modern browser APIs and capabilities to behave like a native app. These capabilities can include:

  • Working offline and always loading instantly, independently of network speed
  • Being able to run in its own app window, not just a browser window
  • Being launched from the host operating system (OS) start menu, dock, or home screen
  • Receiving push notifications from a backend server, even while the user is not using the app
  • Automatically updating in the background

A user might first discover and use the app within their web browser like any other single-page app (SPA), then later progress to installing it in their OS and enabling push notifications.

Blazor WebAssembly is a true standards-based client-side web app platform, so it can use any browser API, including the APIs needed for PWA functionality.

Using the PWA template

When creating a new Blazor WebAssembly app, you’re offered the option to add PWA features. In Visual Studio, the option is given as a checkbox in the project creation dialog:

image

If you’re creating the project on the command line, you can use the --pwa flag. For example,

dotnet new blazorwasm --pwa -o MyNewProject

In both cases, you’re free to also use the “ASP.NET Core hosted” option if you wish, but don’t have to do so. PWA features are independent of how the app is hosted.

Installation and app manifest

When visiting an app created using the PWA template option, users have the option to install the app into their OS’s start menu, dock, or home screen.

The way this option is presented depends on the user’s browser. For example, when using desktop Chromium-based browsers such as Edge or Chrome, an Add button appears within the address bar:

image

On iOS, visitors can install the PWA using Safari’s Share button and its Add to Homescreen option. On Chrome for Android, users should tap the Menu button in the upper-right corner, then choose Add to Home screen.

Once installed, the app appears in its own window, without any address bar.

image

To customize the window’s title, color scheme, icon, or other details, see the file manifest.json in your project’s wwwroot directory. The schema of this file is defined by web standards. For detailed documentation, see https://developer.mozilla.org/en-US/docs/Web/Manifest.

Offline support

By default, apps created using the PWA template option have support for running offline. A user must first visit the app while they are online, then the browser will automatically download and cache all the resources needed to operate offline.

Important: Offline support is only enabled for published apps. It is not enabled during development. This is because it would interfere with the usual development cycle of making changes and testing them.

Warning: If you intend to ship an offline-enabled PWA, there are several important warnings and caveats you need to understand. These are inherent to offline PWAs, and not specific to Blazor. Be sure to read and understand these caveats before making assumptions about how your offline-enabled app will work.

To see how offline support works, first publish your app, and host it on a server supporting HTTPS. When you visit the app, you should be able to open the browser’s dev tools and verify that a Service Worker is registered for your host:

image

Additionally, if you reload the page, then on the Network tab you should see that all resources needed to load your page are being retrieved from the Service Worker or Memory Cache:

image

This shows that the browser is not dependent on network access to load your app. To verify this, you can either shut down your web server, or instruct the browser to simulate offline mode:

image

Now, even without access to your web server, you should be able to reload the page and see that your app still loads and runs. Likewise, even if you simulate a very slow network connection, your page will still load almost immediately since it’s loaded independently of the network.

To learn more about building PWAs with Blazor, check out the documentation.

Known issues

There are a few known issues with this release that you may run into:

  • When building a Blazor WebAssembly app using an older .NET Core SDK you may see the following build error:

    error MSB4018: The "ResolveBlazorRuntimeDependencies" task failed unexpectedly.
    error MSB4018: System.IO.FileNotFoundException: Could not load file or assembly '\BlazorApp1\obj\Debug\netstandard2.1\BlazorApp1.dll'. The system cannot find the file specified.
    error MSB4018: File name: '\BlazorApp1\obj\Debug\netstandard2.1\BlazorApp1.dll' 
    error MSB4018:    at System.Reflection.AssemblyName.nGetFileInformation(String s)
    error MSB4018:    at System.Reflection.AssemblyName.GetAssemblyName(String assemblyFile)
    error MSB4018:    at Microsoft.AspNetCore.Components.WebAssembly.Build.ResolveBlazorRuntimeDependencies.GetAssemblyName(String assemblyPath)
    error MSB4018:    at Microsoft.AspNetCore.Components.WebAssembly.Build.ResolveBlazorRuntimeDependencies.ResolveRuntimeDependenciesCore(String entryPoint, IEnumerable`1 applicationDependencies, IEnumerable`1 monoBclAssemblies)
    error MSB4018:    at Microsoft.AspNetCore.Components.WebAssembly.Build.ResolveBlazorRuntimeDependencies.Execute()
    error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
    error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask)
    

    To address this issue, upgrade to version 3.1.102 or later of the .NET Core 3.1 SDK.

  • You may see the following warning when building from the command-line:

    CSC : warning CS8034: Unable to load Analyzer assembly C:\Users\user\.nuget\packages\microsoft.aspnetcore.components.analyzers\3.1.0\analyzers\dotnet\cs\Microsoft.AspNetCore.Components.Analyzers.dll : Assembly with same name is already loaded
    

    This issue will be fixed in a future update to the .NET Core SDK. To workaround this issue, add the <DisableImplicitComponentsAnalyzers>true</DisableImplicitComponentsAnalyzers> property to the project file.

  • The following error may occur when publishing an ASP.NET Core hosted Blazor app with the .NET IL linker disabled:

    An assembly specified in the application dependencies manifest (BlazorApp1.Server.deps.json) was not found
    

    This error occurs when assemblies shared by the server and Blazor client project get removed during publish (see https://github.com/dotnet/aspnetcore/issues/19926).

    To workaround this issue, ensure that you publish with the .NET IL linker enabled. To publish with the linker enabled:

    • Publish using a Release build configuration: dotnet publish -c Release. The .NET IL linker is automatically run for Release builds, but not for Debug builds.
    • Don’t set BlazorWebAssemblyEnableLinking to false in your client project file.

    If you’re hitting issues running with the linker disabled, you may need to configure the linker to preserve code that is being called using reflection. See https://docs.microsoft.com/aspnet/core/host-and-deploy/blazor/configure-linker for details.

Feedback

We hope you enjoy the new features in this preview release of Blazor WebAssembly! Please let us know what you think by filing issues on GitHub.

Thanks for trying out Blazor!

144 comments

Comments are closed. Login to edit/delete your existing comments

  • Christophe MOMMER

    Blazor is going into the best way it can !

    Can’t wait to use it.

    Any guide to migrate from Blazor Server to Blazor WASM ?

  • Lucas Elzinga

    Is there any location that we can see the coming updates, I have tried to find a location that I can always visit to see the current roadmap for future updates.. I know there is a larger update coming out in May but how can I find out what is planned to be within that release?

  • Ismel Martínez Díaz

    Hello.

    I try to use the generated files in a test python host.

    First I create a folder blazor-test and put these files into it

    _framework (folder)
    css (folder)
    sample-data (folder)
    favicon.ico
    index.html

    Then, I run the command python -m http.server 8000 to host the files using a lightweight python http server.

    So, next step I load the page http://localhost:8000 into a browser.

    The SPA load fine !!! All ok.

    I can navigate to /, to /counter and to /fetchdata.

    But, when I want to reload the /fetchdata page or the /counter page, I get 404 File not found page.

    Do you think use the url hash #! or # to solve this problem?

    Thanks.

    • Patrizio Ricciardello

      I guess you need to use something like in PHP mod rewrite to point any request to the main index page.
      Would make sense, since the Webserver searches for a Ressource at the location.
      It works initially because blazor just rewrite the URL without an additional request. Since I am not a python programmer I can’t give a solution

  • Jonny Olliff-Lee

    Hi, only just saw this post thanks to a colleague. Thank you to the Blazor team for more awesome improvements with this version!

    After upgrading though I’ve ran an into an issue at build time. I upgraded the packages and built, all good. Then I ran a git clean -xdf, and built and got the following error:

     Fatal error in Mono IL Linker
    C:\Users\jonathan.ollifflee\.nuget\packages\microsoft.aspnetcore.components.webassembly.build\3.2.0-preview2.20160.5\targets\Blazor.MonoRuntime.targets(245,5): error : Unhandled exception. Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'obj\Release\netstandard2.1\BlazorTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' [D:\dev\BlazorTest\src\BlazorTest\BlazorTest.csproj]
       ---> Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'obj\Release\netstandard2.1\BlazorTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
         at Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
         at Mono.Linker.AssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
         at Mono.Linker.LinkContext.Resolve(IMetadataScope scope)
         at Mono.Linker.LinkContext.Resolve(IMetadataScope scope)
         at Mono.Linker.LinkContext.Resolve(String name)
         at Mono.Linker.Steps.ResolveFromAssemblyStep.Process()
         at Mono.Linker.Steps.BaseStep.Process(LinkContext context)
         at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
         at Mono.Linker.Pipeline.Process(LinkContext context)
         at Mono.Linker.Driver.Run(ILogger customLogger)
         at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger)
         at Mono.Linker.Driver.Main(String[] args)
    C:\Users\jonathan.ollifflee\.nuget\packages\microsoft.aspnetcore.components.webassembly.build\3.2.0-preview2.20160.5\targets\Blazor.MonoRuntime.targets(245,5): error : ILLink failed with exit code -532462766. [D:\dev\BlazorTest\src\BlazorTest\BlazorTest.csproj]

    Nothing gets outputed to the bin folder (which is why the DLL can’t be found). If I revert back to a previous commit, and rebuild all is well again.

    Any thoughts?

    • Daniel RothMicrosoft employee

      For some reason the BlazorTest.dll failed to build or couldn’t be found by the .NET IL linker. Can you try building with the linker disabled? Set <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> in your project file.

      • Jonny Olliff-Lee

        Thank you for your reply Daniel. It turns out I just can’t follow simple instructions! I only have .NET Core SDK v3.1.101 installed, just updated to v3.1.201 and all is working!

  • Nikola Nikolov

    Hallo Daniel,

    Up to now i have used Role Based Authorisation as per the example provided by Chris Sainty – https://chrissainty.com/securing-your-blazor-apps-configuring-role-based-authorization-with-client-side-blazor/ – and the same has worked really well.

    Now I have updated to the new version of blazor.net and I really couldn figgure out how to have the Roles worked again with IdentityServer4.

    I will be verry gratefull If you provide me with an example or link how to implement Roles as well.

    Thanks in advance.

    Nikola

      • Nikola Nikolov

        Hallo Daniel and thank you very much for the quick response. At the end it have worked, but I have used Chris Santy ApiAuthenticationProvider instead of the new provided ApiAthenticationProvider with following settings in Startup.

        if (!_environment.IsDevelopment())
        {
        var cert = new X509Certificate2(@"cert/cert.pfx", "password");
        services.AddCertificateManager();
        var keysFolder = Path.Combine(_environment.ContentRootPath, "Keys");

        services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(keysFolder))
        .SetApplicationName("myProject")
        .SetDefaultKeyLifetime(TimeSpan.FromDays(90)).ProtectKeysWithCertificate(cert);
        }

        services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt;
        options.UseSqlServer(
        Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;(options =&gt; options.SignIn.RequireConfirmedAccount = false)
        .AddEntityFrameworkStores&lt;ApplicationDbContext&gt;();
        services.AddMvc();
        services.AddIdentityServer()
        .AddApiAuthorization&lt;ApplicationUser, ApplicationDbContext&gt;();

        //services.AddAuthentication()
        // .AddIdentityServerJwt();
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =&gt;
        {
        options.TokenValidationParameters = new TokenValidationParameters
        {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = Configuration["JwtIssuer"],
        ValidAudience = Configuration["JwtAudience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
        };
        }).AddIdentityServerJwt();

        services.AddControllersWithViews();
        services.AddRazorPages();
        }

        • Wil Wilder Apaza Bustamante

          I am also having with Chris Sainty Role Based Authorisation. It no longer works after updating my app. Could you please help me with middle configuration source code how you got this working?

      • Juergen

        Hi Daniel,
        yesterday, in asp.net community standup, Steve Sanderson shew a project “MyAppWithIdentityRoles”, which seems to be exactly what we need. Might it be possible, to get a look on its implementation?
        Thanks, for your great work!

        • Daniel RothMicrosoft employee

          Hi Juergen,

          We’ll get this better documented soon, but for now here’s how you use roles with ApiAuthorization + Blazor WebAssembly:

          • Configure Identity to use roles by calling AddRoles

            services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)
            .AddRoles()
            .AddEntityFrameworkStores();

          • Configure identity server to put the role claim into the id token and the access token and prevent the default mapping for roles in the JwtSecurityTokenHandler.

            services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
            options.IdentityResources["openid"].UserClaims.Add("role");
            options.ApiResources.Single().UserClaims.Add("role");
            });

            // Need to do this as it maps "role" to ClaimTypes.Role and causes issues
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

          • On your blazor application use [Authorize(Roles = "admin")] or any other role your app defines.
          • On your protected resource APIs use [Authorize(Roles = "admin")] or any other role your app defines.

          I hope this helps!

          • Juergen

            Hi Daniel,
            thank you for your help! I will try it tomorrow, thank you!

  • Sonja Bijou

    FYI, the WebAssembly template goes missing in VS 2019 16.6.0 Preview 1 when you install the .NET 5 Preview 1 SDK, and reappears when you uninstall it.

    • Jean Jacques Uzabumuhire

      This is disturbing, I am also having the same issue when I try to migrate my existing WebAssembly from .NET Core 3.1 to .NET 5.0

      • Daniel RothMicrosoft employee

        Hi Sonja, Jean. The Blazor WebAssembly template isn’t included with .NET 5 just yet. That won’t happen until after we ship Blazor WebAssembly 3.2 in May. So, when you install the .NET 5 SDK it becomes your active SDK and you won’t see a Blazor WebAssembly template until you install it as described in our Blazor getting started instructions (https://docs.microsoft.com/aspnet/core/blazor/get-started). Once you install the Blazor WebAssembly template, you should be able to create Blazor WebAssembly projects both from the command-line interface and from Visual Studio. Because Blazor WebAssembly 3.2 targets .NET Core 3.1, the template will only show up in Visual Studio when you have .NET Core 3.1 selected. See https://github.com/dotnet/aspnetcore/issues/20007#issuecomment-601357069 for more details.

        • Sonja Bijou

          Hi Daniel, I had suspected that, but FYI, once .NET 5 is installed (well, for me anyway), the WASM template disappears from VS when .NET Core 3.1 is selected as well. Not a biggie for me, as I’m playing with a lot of preview stuff, so understand things may be a bit fragile. I can just get around it by temporarily uninstalling .NET 5 if I need to use the template. In fact, even easier, I’ve committed the results of the various WASM template options in my sandbox repo, and branch for playing with different scenarios. And of course there’s always the command line, which I haven’t tested with .NET 5 installed yet. But thought you’d want it on your radar.

          • Daniel RothMicrosoft employee

            Hi Sonja. You still need to install the Blazor WebAssembly template again after installing .NET 5. Each .NET Core SDK that you have installed has its own copy of the project templates, so you need to install the Blazor WebAssembly template on top of each .NET Core SDK that you want to use, including .NET 5. The target framework dropdown in the Create a New Blazor App dialog doesn’t change the active SDK. It only changes what runtime version you want to target with the app.

          • Sonja Bijou

            Thanks Daniel. Still not working for me unfortunately. Am confirming that I’m in .net 5 with dotnet –version, and then ran dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview2.20160.5, and restarted VS, but still don’t have the wasm template until I uninstall .net 5.

  • Kai Peng

    Great and really needed new features!

    I am working on a test blazor wasm project which needs authentication. Want to use the new authentication feature for sure. Those code snippets in Javier and Luke’s article is great: https://docs.microsoft.com/en-us/aspnet/core/security/blazor/webassembly/standalone-with-authentication-library?view=aspnetcore-3.1

    Is there anywhere on GitHub we can download the complete code examples with these new features? Thanks!

  • Endy Tjahjono

    Hi Dan,

    Is the May target going to be affected by the COVID19 issue?

    • Daniel RothMicrosoft employee

      Hi Endy. Everything still seems to be on track for May. We’re grateful that so far everyone on the team seems to be healthy and well, and folks are all working hard from home to get the final touches on Blazor WebAssembly done for the May release.

      We also understand that not everyone has been as fortunate. Just this past weekend, an elderly neighbor and close friend to my family passed away from COVID-19 after a week long struggle. Just this morning we found out a that the middle aged daughter of a family friend was in the hospital recovering from a cancer surgery, but then contracted COVID-19, which ended her promising recovery. It really struck close to home (in a very literal sense) just how serious this whole situation is.

      So stay safe everyone! Take appropriate precautions and we’ll get through this.

      • Rod Macdonald

        Hi Daniel, these are very hard hitting things to hear indeed. The situation is accelerating towards us all – we’re very close to a complete lockdown in the UK. I’ve had to pack in my work for now (new business, disaster), and to lift spirits and get working on something positive, wondered if there was any chance of bringing Build forwards assuming the sessions will ultimately be online?

        Of course even doing something within the confines of a recording studio might be too challenging.

        • Daniel RothMicrosoft employee

          Hi Rod. I’m sorry to hear about your business! The economic impact of this pandemic are certainly deep and far reaching.

          From what I understand, BUILD is still happening, it’s just been turned into a virtual event: https://www.microsoft.com/build. Details are still pending on how exactly the event will be handled, but there will undoubtedly be lots of cool stuff announced!

  • Stian Kraggerud

    Hi,

    After upgrading to 3.2.0, all links stopped working. The url changes in the browser, but nothing happens. There is no error in the console when I press a link.
    If I enter the path to the page directly in the browser the page loads, but not when I use NavLink component.

    Any idea?

    Regards
    Stian

      • Stian Kraggerud

        Great, but is it possible to send you the whole project directly?

        • Daniel RothMicrosoft employee

          Hi Stian. It’s most helpful to us if you can isolate the issue to as small a project as possible instead of sharing with us your whole application. You can then share the project with us as a GitHub repo, or as an attached zip file, or whatever works best for you.