Domo
Domo

Reputation: 609

Download File in Blazor Server Side with Authentication

I have a Blazor Server Side Web Application that uses the default authorization and authentication.

app.UseAuthentication()
app.UseAuthorization()

I can protect my pages with

@attribute [Authorize]

I have a login page with anonymous access to authenticate. This works fine.

Now I need a way to let the user download files from this authorized pages. Surprisingly I haven't found any straightforward way to do this.

One workaround is to build an API Controller with the filename as a path argument and give the user a link to it.

[Route("api/[controller]")]
public class FileController{

  [HttpGet("download/{filename}")]
  public async Task<IActionResult> Download([FromRoute] string filename){
  
    //Do some checks and get file from Filesystem

    return file;
  }
}

And in the .razor file

<a href="@CalculateDownloadLink("file.txt")" target="_blank"></a>

private string CalculateDownloadLink(string filename){
  return $"{NavigationManager.BaseUri}/api/file/download/{filename}"
}

This is a dumbed down version. In reality the filenames are generic. This works too.

Now I want to add Authentication to the API Controller because I don't want anyone guessing filenames. But I don't know how.

Of Course the [Authorize] Attribute doesn't work because the code is outside the circuit scope. I can't figure out how to use any build-in Authorization to make this work.

Is there a better way to download files from a Blazor app?

Upvotes: 10

Views: 2359

Answers (2)

Brian Parker
Brian Parker

Reputation: 14573

Your controller is not a controller. It does not implement Controller...

[Authorize]
public class FileController : Controller
{
    ...
}

FYI: If you add the download attribute to the anchor the file will only download when clicked.

<a download href="@CalculateDownloadLink("file.txt")">Download file.txt</a>

I made a junk repo that works if you need me to post it.

Upvotes: 0

Tiny Town Software
Tiny Town Software

Reputation: 177

A bit late answering your question, but [Authorize] on the controller should work. Have you tried it? Controller methods get the same cookies that Blazor pages get.

But there is a better way to download a file from Blazor without a need for navigation. See this blog post.

Upvotes: 0

Related Questions