New to Telerik ReportingStart a free 30-day trial

Using the Native Blazor Report Viewer with the Report Server for .NET

This article explains how to configure the Native Blazor Report Viewer to connect to Telerik Report Server for .NET using token-based authentication.

Telerik Report Server for .NET is a server-based reporting solution that stores and manages reports centrally. Token authentication is the recommended security approach, as it provides better protection than username/password credentials and allows for token rotation without code changes.

Any user account can authenticate with the Report Server, including the Guest User, provided there is an enabled token in the user's token collection. Personal tokens follow the JWT structure and are managed through the Report Server interface.

Prerequisites

  • Existing .NET 8 and higher Blazor Server App or .NET 8 and higher hosted Blazor WebAssembly App.
  • Review the Native Blazor Report Viewer Requirements.
  • Installed and running Telerik Report Server for .NET.
  • Report Server for .NET's User that will connect from the viewer should have at least one enabled Token.
  • Report Server for .NET should contain at least one report that can be accessed by the User account.

Configuring the Native Blazor Report Viewer to work with the Report Server for .NET

  1. Add NuGet package reference to the Telerik.ReportViewer.BlazorNative package hosted on the Progress Telerik proprietary NuGet feed. Ensure that the Telerik NuGet feed is added to the NuGet Package Sources by following How to add the Telerik private NuGet feed to Visual Studio.

  2. (Optional) The Native Blazor Report Viewer depends on version 14.0.0 of the Telerik UI for Blazor product. If Telerik UI for Blazor is already used in your Blazor application, this step can be skipped. Otherwise, add the Telerik UI for Blazor JS and its Kendo theme dependencies to the head element of the Pages/_Layout.cshtml (Blazor Server) or wwwroot/index.html (Blazor WebAssembly), or Components/App.razor (Blazor Web App):

    HTML
    <script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js" defer></script>
    
    @* The version of the Kendo Utils should be updated according to the version of the Kendo theme used by the Telerik UI for Blazor package. *@
    @* The version of the Kendo Theme can be seen in the release notes of the Telerik UI for Blazor version - https://www.telerik.com/support/whats-new/blazor-ui/release-history. *@
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/themes/14.3.0/utils/all.css" />
    <link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" />
    <link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-font-icons/font-icons.css" />
  3. Add the Native Blazor Report Viewer's JS and CSS dependencies to the head element of the Pages/_Layout.cshtml (Blazor Server) or wwwroot/index.html (Blazor WebAssembly), or Components/App.razor (Blazor Web App).

    HTML
    <link href="_content/Telerik.ReportViewer.BlazorNative/css/reporting-blazor-viewer.css" rel="stylesheet" />
    <script src="_content/Telerik.ReportViewer.BlazorNative/js/reporting-blazor-viewer.js"></script>
  4. Configure the project to recognize all Telerik components without explicit @using statements on every .razor file by adding the following code to your ~/_Imports.razor:

    RAZOR
    @using Telerik.Blazor
    @using Telerik.Blazor.Components
    @using Telerik.ReportViewer.BlazorNative
  5. Wrap the content of the main layout file(by default, the ~/Shared/MainLayout.razor file in the Blazor project) with a razor component called TelerikLayout.razor:

    RAZOR
    @inherits LayoutComponentBase
    
    <TelerikRootComponent>
        @Body
    </TelerikRootComponent>
  6. Set up an endpoint on the server that will securely return the token used by the Report Server for .NET to authorize. For example, create an environment variable in the launchSettings.json file named RS_NET_TOKEN and store the token in it. Then, the endpoint can be configured to read and return the value of the environment variable:

    C#
    app.MapGet("/rs-token", () =>
    {
        return Environment.GetEnvironmentVariable("RS_NET_TOKEN") ?? string.Empty;
    })
    .RequireAuthorization();

    For Blazor WebAssembly applications where the server is not available, the token can be injected on the .RAZOR page at build-time. Use appsettings.{Environment}.json files (they are bundled at build time) and read the token from the configuration.

    Never hardcode tokens directly in client-side code. Always retrieve them from a secure server endpoint or build-time configuration. Store tokens as environment variables or in secure configuration stores, and ensure the token endpoint is properly secured with authentication and authorization.

  7. Configure an HttpClient in the Program.cs file that will be injected on the .RAZOR page on the next step when we make an HTTP request to get the token from the server.

    C#
    builder.Services.AddHttpClient();
  8. Create a method in the RAZOR or RAZOR.CS file of the Blazor component that returns a Task<string> with the token retrieved from the Report Server:

    RAZOR
    @inject HttpClient Http
    @inject NavigationManager Nav
    
    @code {
        private string _cachedRsToken;
        private readonly SemaphoreSlim _tokenLock = new(1, 1);
    
        // /rs-token returns plain text: token
        async Task<string> GetRsNetAccessToken()
        {
            if (_cachedRsToken is not null)
                return _cachedRsToken;
    
            await _tokenLock.WaitAsync();
            try
            {
                if (_cachedRsToken is not null) // double-check after lock
                    return _cachedRsToken;
    
                var uri = Nav.ToAbsoluteUri("/rs-token");
                try
                {
                    var raw = await Http.GetStringAsync(uri);
                    _cachedRsToken = raw?.Trim() ?? string.Empty;
                }
                catch (Exception)
                {
                    _cachedRsToken = string.Empty;
                }
            }
            finally
            {
                _tokenLock.Release();
            }
    
            return _cachedRsToken;
        }
    }
  9. Use the ReportServerSettings fragment to provide the URL to the Report Server for .NET, and the GetRsNetAccessToken function that the Native Blazor Report Viewer will execute internally to retrieve the token.

    RAZOR
    <ReportViewer @bind-ReportSource="@ReportSource"
                  ServiceType="@ReportViewerServiceType.ReportServer"
                  Height="800px"
                  Width="100%">
        <ReportViewerSettings>
            <ReportServerSettings Url="http://yourreportserver:port/" GetPersonalAccessToken="GetRsNetAccessToken"></ReportServerSettings>
        </ReportViewerSettings>
    </ReportViewer>
  10. Finally, run the project to see the rendered report.

Token Management Best Practices

The token storage approach shown earlier in this article (using launchSettings.json and environment variables) is suitable for development, but requires additional considerations for production environments.

Development

For local development, store the token in launchSettings.json:

JSON
{
  "profiles": {
    "YourApp": {
      "commandName": "Project",
      "environmentVariables": {
        "RS_NET_TOKEN": "your-development-token-here"
      }
    }
  }
}

Production

Do NOT use launchSettings.json in production. This file is excluded from deployments and is intended for development only.

Choose one of these approaches for production:

  1. Environment Variables (Azure App Service, IIS, Linux hosting):

    • Set the RS_NET_TOKEN environment variable through your hosting platform's configuration UI
    • Restart the application after changing the value
    • Environment variables are read automatically by .NET configuration system
  2. Azure Key Vault (Recommended for Azure deployments):

    C#
    builder.Configuration.AddAzureKeyVault(
            new Uri($"https://{keyVaultName}.vault.azure.net/"),
            new DefaultAzureCredential());
    
    // Token is now available via Configuration
    var token = builder.Configuration["RS_NET_TOKEN"];
  3. AWS Secrets Manager (for AWS hosting):

    C#
    builder.Configuration.AddSecretsManager();
    
    // Token is now available via Configuration
    var token = builder.Configuration["RS_NET_TOKEN"];

    Create the secret using AWS CLI:

    bash
    aws secretsmanager create-secret \
    	--name RS_NET_TOKEN \
    	--secret-string "your-report-server-token-here"
  4. User Secrets (Development alternative to launchSettings.json):

    bash
    dotnet user-secrets set "RS_NET_TOKEN" "your-token-here"

Token Rotation

Report Server for .NET tokens should be rotated periodically:

  1. Create a new token in Report Server for .NET
  2. Update the environment variable or secret store with the new token
  3. Restart the application to load the new token
  4. Disable the old token in Report Server after confirming the new one works

Multiple tokens can be enabled simultaneously for a single user account, allowing zero-downtime rotation. Enable the new token before disabling the old one.

Troubleshooting

Token Not Retrieved

If the viewer cannot retrieve the token, verify:

  • The token endpoint is accessible from the client
  • The HttpClient is properly configured and injected
  • The environment variable RS_NET_TOKEN is set correctly
  • The token has not expired

CORS Issues

If you encounter CORS errors when accessing the token endpoint:

  • Ensure CORS is properly configured in Program.cs
  • Verify the endpoint allows requests from your Blazor application's origin
  • Check browser console for specific CORS error messages

Guest User Access

The Guest User can only authenticate using tokens. It does not have a password and cannot use username/password authentication. Ensure at least one enabled token is added to the Guest User account by an administrator: Guest User Administration.

See Also