Disable request verification token in ASP.NET Core - asp.net-core

ASP.NET Core MVC seems to inject a request verification token in all of my forms:
<form class="actions" method="post">
<input type="submit" class="btn btn-primary" value="Yes">
<a class="btn btn-secondary" href="/some/url">No</a>
<input name="__RequestVerificationToken" type="hidden" value="...">
</form>
I'm handling CSRF in Ajax and don't want this extra input element in all of my forms. Any way to disable it?
The element is added even without a call to AddAntiforgery in Startup.cs. I'm running on ASP.NET Core 3.1.

Antiforgery middleware is added to the Dependency injection container when one of the following APIs is called in Startup.ConfigureServices:
AddMvc
MapRazorPages
MapControllerRoute
MapBlazorHub
Details please check this document
To disable it, try below IgnoreAntiforgeryToken attribute
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Details can be found here

The token is appended by the Form Tag Helper. If you don't need the other features of the Tag Helper, it can be removed using #removeTagHelper (in view or globally by adding to _ViewImports.cshtml):
#removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
See ASP.NET Core documentation for further details/options.

Just idea I would make reference to that [IgnoreAntiforgeryToken] can be used to disable the global [AutoValidateAntiForgeryToken] attribute on certain actions if needed.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(new IgnoreAntiforgeryTokenAttribute());
});
}
}

Related

Can we use TagHelper in a razor component?

Can we use TagHelper in a razor component?
Cannot use TagHelper or httpHelper in a razor file
How do I import TagHelper?
<h3>Curent person #People.Skip(personIndex).First().FirstName</h3>
<input type="button" class="btn btn-primary" #onclick="PreviousPerson" value="Previous Person"/>
<input type="button" #onclick="NextPerson" value="Next Person"/>
#foreach (var item in #People) {
<tr>
<td>#Html.DisplayFor(modelItem => item.FirstName)</td>
<td><a asp-action="Edit" asp-route-id="#item.BusinessEntityId">Edit</a></td>
</tr>
}
#code {
[Parameter]
public IEnumerable<EcoleWeb.Areas.Persons.Models.PersonModel> People { get; set;}
private int personIndex;
private void NextPerson()
{
if (personIndex < People.Count() - 1)
personIndex++;
}
private void PreviousPerson()
{
if (personIndex > 0)
personIndex--;
}
}
Integrating Razor components into Razor Pages and MVC apps in a hosted Blazor WebAssembly app is supported in ASP.NET Core in .NET 5.0 or later.
So you needs to make sure your version of project is .NET 5.0 or later firstly.
And then if you want to use tag helper in razor component,you need to add the following code:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
For more details,you can refer to the official doc.
TagHelper are not supported in Blazor, For more information

How do I display a delete confirmation dialog before deleting a row in a DevExtreme DataGrid on a Razor page?

I am using DevExtreme and razor pages in a Asp.NetCore web application.
I would like to inject client side delete confirmation dialog when deleting a row.
Currently I'm using an asp-action on the controller to make the call to do the delete.
I'm not sure how/where to do this in client side (cshtml file).
I assume that I'd be somehow using javascript/jquery for this?
Are there existign 3rd party open source libraries that I should use for client side dialogs/message boxes?
DevExtreme DataGrid definition in cshtml file.
#(Html.DevExtreme().DataGrid<Customer>()
.DataSource(Model)
.Columns(columns => {
columns.AddFor(m => m.CustomerName);
columns.AddFor(m => m.CustomerId).CellTemplate(
<form asp-action="DeleteCustomer" method="post">
<input type="hidden" value="<%- data.CustomerId %>" name="CustomerId" />
<input type="image" src="/icon/close.png" />
</form>
</text>).Caption("");
});
Server side control action code:
[HttpPost]
public async Task<IActionResult> DeleteCustomer(Guid customerId)
{
// Call WebApi Service to delete row
return RedirectToAction("Index");
}
I believe the datagrid has a built-in function for confirming the delete action on the client side. Might not be exactly what you were looking for but it could be a good start.
Here is the link to the demo page: https://demos.devexpress.com/ASPNetCore/Demo/DataGrid/RowEditingAndEditingEvents/

Oppeniddict - How to skip logout prompt?

I am using velusia sample, I want the client app to skip the log out prompt page, is there any specific way to achieve this, or should I implement it my self ?
How you handle logout requests is up to you. To trigger a redirection to the client application (when a post_logout_redirect_uri is set) without displaying a consent form, trigger an ASP.NET Core Logout operation pointing to OpenIddict:
// Returning a SignOutResult will ask OpenIddict to redirect the user agent
// to the post_logout_redirect_uri specified by the client application or to
// the RedirectUri specified in the authentication properties if none was set.
return SignOut(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
That said, I wouldn't recommend doing that: not requiring user consent or a form of anti-forgery protection - the id_token_hint can help, use AuthenticateAsync() to retrieve the principal from it - may make targeted DOS attacks possible.
According to your description, I suggest you could try to set a js code to automatically click the logout button in the server side.
More details, you could refer to below codes:
Modify the server's logout view as below:
#using Microsoft.Extensions.Primitives
<div class="jumbotron">
<h1>Log out</h1>
<p class="lead text-left">Are you sure you want to sign out?</p>
<form asp-controller="Authorization" asp-action="Logout" method="post">
#* Flow the request parameters so they can be received by the LogoutPost action: *#
#foreach (var parameter in Context.Request.HasFormContentType ?
(IEnumerable<KeyValuePair<string, StringValues>>) Context.Request.Form : Context.Request.Query)
{
<input type="hidden" name="#parameter.Key" value="#parameter.Value" />
}
<input class="btn btn-lg btn-success" id="Confirm" name="Confirm" type="submit" value="Yes" />
</form>
</div>
#section scripts{
<script>
$(document).ready(function() {
console.log("Fired");
document.getElementById("Confirm").click();
});
</script>
}
You can also change the HTTP method to GET instead of POST based on Velusia sample:
[HttpGet("logout")]
public async Task<IActionResult> LogoutPost()
{
await HttpContext.SignOutAsync(Clients.CmsApp);
await HttpContext.SignOutAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
return SignOut(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
}

In Razor Pages, what is the recommended way to run an action with no UI

I want to implement a sign-out method which just signs the user out and redirects to the home page.
How would I set up the routing and would the code go into a controller, or do I need to create a new Page for this? Would seem odd as it doesn't require a UI.
asp-page specify the page name which the sign-out method is in , The asp-page-handler attribute is a companion to asp-page. asp-page-handler generates URLs that submit to each of the handler methods defined by a page. Change your _LoginPartial.cshtml as follows :
#if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello #User.Identity.Name!</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-page="/Index" asp-page-handler="SignOut">Logout</a>
</li>
}
IndexModel of Home page , the RedirectToPage parameter is combined with the path of the current page to compute the name of the destination page.
public class IndexModel : PageModel
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public IndexModel(SignInManager<ApplicationUser> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public void OnGet()
{
}
public async Task<IActionResult> OnGetSignOut()
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
return RedirectToPage("/Index");
}
}
Result:
Reference for RedirectToPage :https://learn.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-3.0&tabs=visual-studio#url-generation-for-pages
Create a method named GetSignOut() then add a button or an <a></a> tag and add this to its attributes asp-route-handler="signout"
Finally in your GetSignOut() do your signout related stuff and finally return redirectToPage("pageName")
The original Razor Pages project template included an AccountController that had one method - Logout. The justification was that the Logout process did not require a UI, so it seemed odd to create a Razor Page for it when the purpose behind Razor Pages is to generate HTML.
If you scaffold Identity into an existing project, you now get a Logout.cshtml file, which redirects the use to a return URL if one is provided, or displays "you have been logged out" otherwise.
So both approaches tend to suggest that the recommendation is to use Razor Pages for HTML generation, and controllers for non-HTML related services.

How to sign out over HttpContext in server-side Blazor

I access the HttpContext in a Blazor server-side view to manually log out. I added this line to Startup.cs: services.AddHttpContextAccessor(); and inject it in the view with #inject IHttpContextAccessor HttpContextAccessor.
I've got a log out button which tries to execute this code:
await HttpContextAccessor.HttpContext.SignOutAsync("Cookies");
but I get the following error message:
System.InvalidOperationException: 'Headers are read-only, response has already started.'
How can I prevent this error?
If you scaffolded Identity and overridden the old "LogOut.cshtml" from when you created the project via template, the Logout button won't logout. Assume you've used the default IdentityUser model. I ran into this issue and just wanted to add this if anyone else had this problem as well. I'm using Blazor Server with .Net 5.0.3's template. You can remove the Logout.cshtml.cs after as well.
Replace this \Areas\Identity\Pages\Account\LogOut.cshtml
#page
#model LogoutModel
#{
ViewData["Title"] = "Log out";
}
<header>
<h1>#ViewData["Title"]</h1>
#{
if (User.Identity.IsAuthenticated)
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Page("/", new { area = "" })" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
</form>
}
else
{
<p>You have successfully logged out of the application.</p>
}
}
</header>
Replace with
#page
#using Microsoft.AspNetCore.Identity
#attribute [IgnoreAntiforgeryToken]
#inject SignInManager<IdentityUser> SignInManager
#functions {
public async Task<IActionResult> OnPost()
{
if (SignInManager.IsSignedIn(User))
{
await SignInManager.SignOutAsync();
}
return Redirect("~/");
}
}
This tripped me up too, but you need the logout functionality to be on a Razor Page (not a Blazor component). Create a Logout page and put your logout code in the OnGetAsync() method.
Your logout button can then link to the logout page.
http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4316/A-Demonstration-of-Simple-Server-side-Blazor-Cookie-Authentication.aspx - this is a helpful example
Don't use IHttpContextAccessor.
I guess that you're using ASP.NET Core Blazor authentication and authorization new system. If not, then start with it right now. Live is too short to be wasted over other things. This is the best product created so far for Blazor's authentication and authorization, and it is based on the Identity UI (This is not Blazor, of course). Additionally, there are a couple of Components which enable controlling the flow of authentication and authorization in your application, such as displaying a "Log in" button and a "Log out" button in your layout, interchangeably altering depending on your authentication state, etc.
Please, go to this page and start learning this excellent system, and then come here for specific issues you face:
https://learn.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.0&tabs=visual-studio
Hope this helps...