-
Notifications
You must be signed in to change notification settings - Fork 80
docs(upload): Add KB for Antiforgery integration #1872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
db65b16
docs(upload): Add KB for Antiforgery integration
dimodi 027c69d
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi a6d1723
Update components/upload/troubleshooting.md
dimodi ea49ce3
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 210b6a6
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 5ade126
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi edead98
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi fc1bcb4
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi a3b1e41
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi e838aed
Update components/upload/events.md
dimodi 7d5433a
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 285cf10
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 76cc99f
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 32ac1d6
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 7a6d8f8
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 8a7e536
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 64fbfa6
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi 0617eac
Update knowledge-base/upload-validateantiforgerytoken.md
dimodi d83070a
improve bullet point
dimodi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,229 @@ | ||
| --- | ||
| title: Upload Files with Antiforgery Validation | ||
| description: Learn how to setup the Telerik Blazor Upload to work with .NET controllers that use the ValidateAntiForgeryToken attribute. Configure Blazor apps with antiforgery validation. | ||
| type: how-to | ||
| page_title: How to Upload Files with Antiforgery Validation | ||
| slug: upload-kb-validateantiforgerytoken | ||
| position: | ||
| tags: telerik, blazor, upload | ||
| ticketid: 1626509, 1637325 | ||
| res_type: kb | ||
| --- | ||
|
|
||
| ## Environment | ||
|
|
||
| <table> | ||
| <tbody> | ||
| <tr> | ||
| <td>Product</td> | ||
| <td>Upload for Blazor</td> | ||
| </tr> | ||
| </tbody> | ||
| </table> | ||
|
|
||
|
|
||
| ## Description | ||
|
|
||
| This KB article answers the following questions: | ||
|
|
||
| * How to use the Telerik Blazor Upload component with controllers that are decorated with the `[ValidateAntiForgeryToken]` attribute? | ||
| * How to upload files to controllers that require antiforgery validation? | ||
| * How to set antiforgery tokens in the Upload's `OnUpload` and `OnRemove` events? | ||
|
|
||
|
|
||
| ## Solution | ||
|
|
||
| Here are the suggested steps to configure .NET Core Blazor antiforgery validation and integrate it with the Telerik Upload component. | ||
|
|
||
| 1. Add services and configurations to `Program.cs`: | ||
| * Add `builder.Services.AddRazorPages();` | ||
| * Add `builder.Services.AddHttpContextAccessor();` | ||
dimodi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * (optional) Add `builder.Services.AddAntiforgery()` with custom `HeaderName` or `FormFieldName`. | ||
| * Verify that `app.UseAntiforgery();` is present. | ||
| * Add `app.MapDefaultControllerRoute();` to configure routing. | ||
| 1. [Implement the `Save` and `Remove` controller methods]({%slug upload-overview%}#implement-controller-methods). | ||
| 1. Decorate the controller class or specific action methods with `[ValidateAntiForgeryToken]` | ||
| 1. Configure the Razor component, which contains the Telerik Blazor Upload: | ||
| * Inject `AntiforgeryStateProvider` to use its `GetAntiforgeryToken()` method. | ||
| * Inject `IAntiforgery` to use its `GetAndStoreTokens(httpContext)` method. | ||
| * Inject `IHttpContextAccessor` to use its `HttpContext` property in the `GetAndStoreTokens()` method. | ||
| * Execute `GetAndStoreTokens()` and/or `GetAntiforgeryToken()` in `OnInitialized` to obtain the required antiforgery information. | ||
| * Add the required antiforgery information in the Upload component's [`OnUpload` and `OnRemove` event handlers]({%slug upload-events%}). | ||
|
|
||
| The code snippets below assume that the application name is `BlazorAppName`. | ||
|
|
||
| >caption Using Telerik Blazor Upload with antiforgery validation | ||
|
|
||
| <div class="skip-repl"></div> | ||
|
|
||
| ````Program.cs | ||
| // This is not the complete Program.cs file, but only the relevant bits. | ||
|
|
||
| using Microsoft.AspNetCore.Http.Features; | ||
| // Required by ValidateAntiForgeryTokenAttribute() | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using Microsoft.AspNetCore.Server.Kestrel.Core; | ||
|
|
||
| var builder = WebApplication.CreateBuilder(args); | ||
|
|
||
| // ... | ||
|
|
||
| // Required by MapDefaultControllerRoute() | ||
| builder.Services.AddRazorPages(); | ||
|
|
||
| // Not necessary due to AddRazorPages() | ||
| //builder.Services.AddControllersWithViews(options => | ||
| //{ | ||
| // options.Filters.Add(new ValidateAntiForgeryTokenAttribute()); | ||
| //}); | ||
|
|
||
| // Required by Antiforgery.GetAndStoreTokens() in Razor components | ||
| builder.Services.AddHttpContextAccessor(); | ||
|
|
||
| // This statement and the custom names are optional. | ||
| builder.Services.AddAntiforgery(options => { | ||
| options.HeaderName = "X-CSRF-TOKEN-HEADERNAME"; | ||
| options.FormFieldName = "X-CSRF-TOKEN-FORMFIELDNAME"; | ||
| }); | ||
|
|
||
| builder.Services.AddTelerikBlazor(); | ||
|
|
||
| // ASP.NET Core Upload file size limit | ||
| builder.Services.Configure<FormOptions>(options => | ||
| { | ||
| options.MultipartBodyLengthLimit = 4_294_967_296; // 4 GB | ||
| }); | ||
| // Kestrel Upload file size limit | ||
| builder.Services.Configure<KestrelServerOptions>(options => | ||
| { | ||
| options.Limits.MaxRequestBodySize = 4_294_967_296; // 4 GB | ||
| }); | ||
|
|
||
| var app = builder.Build(); | ||
|
|
||
| // ... | ||
|
|
||
| app.UseAntiforgery(); | ||
|
|
||
| // Requires AddRazorPages() or AddControllersWithViews() | ||
| app.MapDefaultControllerRoute(); | ||
|
|
||
| // ... | ||
|
|
||
| app.Run(); | ||
| ```` | ||
| ````Razor | ||
| @using Microsoft.AspNetCore.Antiforgery | ||
|
|
||
| @inject AntiforgeryStateProvider AfStateProvider | ||
| @inject IAntiforgery Antiforgery | ||
| @inject IHttpContextAccessor HttpContextAccessor | ||
| @inject NavigationManager NavigationManager | ||
|
|
||
| <PageTitle>Home</PageTitle> | ||
|
|
||
| <TelerikUpload SaveUrl="@UploadSaveUrl" | ||
| RemoveUrl="@UploadRemoveUrl" | ||
| OnUpload="@OnUploadUpload" | ||
| OnRemove="@OnUploadRemove" /> | ||
|
|
||
| @code { | ||
| private string UploadSaveUrl => ToAbsoluteUrl("api/upload/save"); | ||
| private string UploadRemoveUrl => ToAbsoluteUrl("api/upload/remove"); | ||
|
|
||
| private string? AntiforgeryHeaderName { get; set; } | ||
| private string? AntiforgeryHeaderToken { get; set; } | ||
| private string? AntiforgeryFormFieldName { get; set; } | ||
| private string? AntiforgeryFormValue { get; set; } | ||
|
|
||
| private void OnUploadUpload(UploadEventArgs args) | ||
| { | ||
| // There is no need to post both antiforgery header and data. | ||
| // Only one of them is enough. | ||
|
|
||
| args.RequestHeaders.Add(AntiforgeryHeaderName, AntiforgeryHeaderToken); | ||
| args.RequestData.Add(AntiforgeryFormFieldName, AntiforgeryFormValue); | ||
| } | ||
|
|
||
| private void OnUploadRemove(UploadEventArgs args) | ||
| { | ||
| // There is no need to post both antiforgery header and data. | ||
| // Only one of them is enough. | ||
|
|
||
| args.RequestHeaders.Add(AntiforgeryHeaderName, AntiforgeryHeaderToken); | ||
| args.RequestData.Add(AntiforgeryFormFieldName, AntiforgeryFormValue); | ||
| } | ||
|
|
||
| protected override void OnInitialized() | ||
| { | ||
| // Obtain the antiforgery header name and value. | ||
| if (HttpContextAccessor.HttpContext != null) | ||
| { | ||
| var afTokenSet = Antiforgery.GetAndStoreTokens(HttpContextAccessor.HttpContext); | ||
| AntiforgeryHeaderName = afTokenSet.HeaderName; | ||
| AntiforgeryHeaderToken = afTokenSet.RequestToken; | ||
| } | ||
|
|
||
| // Obtain the antiforgery form field name and value. | ||
| var afRequestToken = AfStateProvider.GetAntiforgeryToken(); | ||
| if (afRequestToken != null) | ||
| { | ||
| AntiforgeryFormFieldName = afRequestToken.FormFieldName; | ||
| AntiforgeryFormValue = afRequestToken.Value; | ||
| } | ||
|
|
||
| base.OnInitialized(); | ||
| } | ||
|
|
||
| private string ToAbsoluteUrl(string url) | ||
| { | ||
| return $"{NavigationManager.BaseUri}{url}"; | ||
| } | ||
| } | ||
| ```` | ||
| ````Controller | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace BlazorAppName.Controllers | ||
| { | ||
| [ValidateAntiForgeryToken] | ||
| [Route("api/[controller]/[action]")] | ||
| public class UploadController : ControllerBase | ||
| { | ||
| public IWebHostEnvironment HostingEnvironment { get; set; } | ||
|
|
||
| public UploadController(IWebHostEnvironment hostingEnvironment) | ||
| { | ||
| HostingEnvironment = hostingEnvironment; | ||
| } | ||
|
|
||
| [HttpPost] | ||
| public async Task<IActionResult> Save(IFormFile files) | ||
| { | ||
| // Save the file... | ||
|
|
||
| return new EmptyResult(); | ||
| } | ||
|
|
||
| [HttpPost] | ||
| public async Task<IActionResult> Remove([FromForm] string files) | ||
| { | ||
| // Delete the file... | ||
|
|
||
| return new EmptyResult(); | ||
| } | ||
| } | ||
| } | ||
| ```` | ||
|
|
||
|
|
||
| ## Disclaimer | ||
|
|
||
| > This article contains code snippets and suggestions that relate to general .NET programming and antiforgery setup of a Blazor application. The provided implementation is just an example and is strictly outside the Telerik support scope. The primary resource for antiforgery configuration is the Microsoft documentation. See [Blazor authentication and authorization](https://learn.microsoft.com/en-us/aspnet/core/blazor/security/). | ||
ikoevska marked this conversation as resolved.
Show resolved
Hide resolved
dimodi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| ## See Also | ||
|
|
||
| * [Upload Overview]({%slug upload-overview%}) | ||
| * [Upload Events]({%slug upload-events%}) | ||
| * [Upload Troubleshooting]({%slug upload-troubleshooting%}) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.