Interview question
Stream an authorized file download
Authorizes metadata before opening storage and streams the file with safe headers and range support.
TL;DR
Authorizes metadata before opening storage and streams the file with safe headers and range support.
Resource authorization, stream ownership, range requests, content disposition, storage abstraction, and cancellation.
Practice the problem like a real interview: restate, reason, implement, and test.
Load document metadata, authorize its owner or support reader, then stream from private storage. Return a safe filename and never expose the storage key.
Next in API Implementation Labs: Downstream Boundary
A 500 MB file starts downloading without allocating 500 MB in the API process; an unauthorized id reveals no metadata.
I use database metadata as the authorization resource and the storage key only after access succeeds. Results.Stream transfers incrementally and can support seekable range requests for large downloads.
app.MapGet("/documents/{id:guid}/content", async Task<IResult> (
Guid id, AppDbContext db, IAuthorizationService authorization,
IPrivateFileStorage storage, ClaimsPrincipal user, CancellationToken ct) =>
{
var document = await db.Documents.AsNoTracking()
.SingleOrDefaultAsync(x => x.Id == id, ct);
if (document is null) return Results.NotFound();
var allowed = await authorization.AuthorizeAsync(user, document,
new ReadDocumentRequirement());
if (!allowed.Succeeded) return Results.NotFound();
var stored = await storage.OpenReadAsync(document.StorageKey, ct);
if (stored is null) return Results.NotFound();
return Results.Stream(stored.Stream,
contentType: document.ContentType,
fileDownloadName: FileNames.ForDownload(document.OriginalName),
lastModified: stored.LastModified,
entityTag: stored.ETag,
enableRangeProcessing: stored.Stream.CanSeek);
}).RequireAuthorization();
Streaming bounds application memory, while range support depends on a seekable stream or storage provider integration. The framework disposes the result stream after the response completes.
ReadAllBytesAsync.Share the question with a concise Core-answer excerpt and invite other developers to add their perspective.
Help improve the interview library.
Say thanks with a standalone, one-time $5 contribution. No account required.
Aporeon is shaped by Aleksandar Tomovski, a software developer with experience on both sides of technical interviews. Content is reviewed for accuracy, natural spoken delivery, useful depth, and honest trade-offs.