Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions aspnetcore/blazor/call-web-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,25 @@ The [`System.Net.Http.Json`](https://www.nuget.org/packages/System.Net.Http.Json

## Use a token handler for web API calls

Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the next section.
Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the *Sample apps* section of this article.

For more information, see the following resources:

* <xref:blazor/security/additional-scenarios#use-a-token-handler-for-web-api-calls>
* *Secure an ASP.NET Core Blazor Web App with OpenID Connect (OIDC)*
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern)
* [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern-server)
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern)
* [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern-server)

## Microsoft identity platform for web API calls

Blazor Web Apps that use use [Microsoft identity platform](/entra/identity-platform/)/[Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra) can make streamlined calls using Entra-specific API. This approach is used by the `BlazorWebAppEntra` and `BlazorWebAppEntraBff` sample apps described in the *Sample apps* section of this article.

For more information, see the following resources:

* <xref:blazor/security/additional-scenarios#use-a-token-handler-for-web-api-calls>
* *Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID*
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern)
* [BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern-server)

## Sample apps

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/security/blazor-web-app-with-entra.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The following specification is covered:
* The app uses [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra), based on [Microsoft Identity Web](/entra/msal/dotnet/microsoft-identity-web/) packages.
* Automatic non-interactive token refresh is managed by the framework.
* The app uses server-side and client-side service abstractions to display generated weather data:
* When rendering the `Weather` component on the server to display weather data, the component uses the `ServerWeatherForecaster` on the server to directly obtain weather data (not via a web API call).
* When rendering the `Weather` component on the server to display weather data, the component uses the `ServerWeatherForecaster` on the server to obtain weather data.
* When the `Weather` component is rendered on the client, the component uses the `ClientWeatherForecaster` service implementation, which uses a preconfigured <xref:System.Net.Http.HttpClient> (in the client project's `Program` file) to make a web API call to the server project's Minimal API (`/weather-forecast`) for weather data. The Minimal API endpoint obtains the weather data from the `ServerWeatherForecaster` class and returns it to the client for rendering by the component.

## Sample solution
Expand Down
41 changes: 40 additions & 1 deletion aspnetcore/blazor/security/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ else
The server project implements `IWeatherForecaster` as `ServerWeatherForecaster`, which generates and returns mock weather data via its `GetWeatherForecastAsync` method:

```csharp
public class ServerWeatherForecaster() : IWeatherForecaster
internal sealed class ServerWeatherForecaster() : IWeatherForecaster
{
public readonly string[] summaries =
[
Expand All @@ -797,6 +797,45 @@ public class ServerWeatherForecaster() : IWeatherForecaster
}
```

Alternatively, the `ServerWeatherForecaster` can call an external web API using a [named HTTP Client and token handler approach](xref:blazor/call-web-api#use-a-token-handler-for-web-API-calls), as the following example demonstrates:

```csharp
internal sealed class ServerWeatherForecaster(IHttpClientFactory clientFactory) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
var request = new HttpRequestMessage(HttpMethod.Get, "/weather-forecast");
var client = clientFactory.CreateClient("ExternalApi");

var response = await client.SendAsync(request);

response.EnsureSuccessStatusCode();

return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
```

If the app uses [Microsoft identity platform](/entra/identity-platform/)/[Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra) (see <xref:blazor/call-web-api#microsoft-identity-platform-for-web-api-calls>), the `ServerWeatherForecaster` might appear like the following class to make external web API calls:

```csharp
internal sealed class ServerWeatherForecaster(IDownstreamApi downstreamApi) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
var response = await downstreamApi.CallApiForUserAsync("DownstreamApi",
options =>
{
options.RelativePath = "/weather-forecast";
});

return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
```

The server project maintains a secure web API endpoint for client weather data calls:

```csharp
Expand Down