0

I have a Blazor server app that I want to add a web api controller to that can be accessed from Postman and eventually other apps. The Blazor app needs authentication, but not the web api. I tried adding AllowAnonymous, but I am getting an authentication error calling it from Postman:

HTTP Error 401.2 - Unauthorized You are not authorized to view this page due to invalid authentication headers.

I suspect our security proxy is adding the headers:

enter image description here

Is it possible to host an unsecured (AllowAnonymous) web api inside an authenticated Blazor Server app?

Maybe I just need to craft my api call a certain way?

Controller:

[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class ProfileController : ControllerBase
{
    [HttpGet("{year}", Name = "GetProfileResults")]
    public async Task<IActionResult> GetProfileResults(int year)
    {
        var profileResults = repo.GetResults(year);
        return Ok(profileResults);
    }
}
0

2 Answers 2

2

You have to add another http client with no tokens attached.

Program.cs

builder.Services.AddHttpClient(
    name: "Anon.ServerAPI",
    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

RazorPage.razor.cs

[Inject]
public IHttpClientFactory HttpClientFactory { get; set; }

protected override async Task OnInitializedAsync()
{
    http = HttpClientFactory.CreateClient("Anon.ServerAPI");
    videos = await http.GetFromJsonAsync<VideoDto[]>("api/YoutubeVideos");
}
Sign up to request clarification or add additional context in comments.

4 Comments

Is there a way to emulate that in Postman?
@SteveGreene if there is no security Postman should just work.
This answers how to consume anonymous 3rd party APIs from inside a Blazor app. The question is how to host an anonymous web API in a Blazor Server app so that the 3rd party clients can consume it without facing auth challenge.
@alex.z This works with the API as described...
2

The key point to host a public API in a Blazor Server app is to ensure the API routing takes precedence over others.

In Program.cs (or Startup.cs):

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.MapControllers(); // the order is important, this ensures API takes precedence.
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");

    app.Run();

Alternatively for endpoint routing:

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        app.MapControllers(); // the order is important, this ensures API takes precedence.
        app.MapBlazorHub();
        app.MapFallbackToPage("/_Host");
    });

    app.Run();

Next, the controller. In your example the code is completely correct. It must use [AllowAnonymous] at the controller level or at specific actions as usual.

[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class ProfileController : ControllerBase
{
    [HttpGet("{year}", Name = "GetProfileResults")]
    public async Task<IActionResult> GetProfileResults(int year)
    {
        var profileResults = repo.GetResults(year);
        return Ok(profileResults);
    }
}

That should be enough to route the call to API before Blazor takes over the security.

Last but not the least is the default exception configuration handling code added to Blazor projects by default:

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

Please be aware that when this code is used any unhandled exceptions during an API call will be caught by the error handler which doesn't respect API [AllowAnonymous] settings and may trigger the authentication challenge configured for Blazor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.