Add Antiforgery to the FormTagHelper pre-check for processing.
- Added a test case to the HtmlGeneration functional test (the one verifying complex FormTagHelpers). - Added unit test verifying antiforgery behavior when it's the only provided parameter. #6006
This commit is contained in:
parent
5c8a161ace
commit
ef0333ac6a
|
|
@ -242,7 +242,15 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
}
|
}
|
||||||
|
|
||||||
TagBuilder tagBuilder = null;
|
TagBuilder tagBuilder = null;
|
||||||
if (Action == null && Controller == null && Route == null && _routeValues == null && Fragment == null && Area == null && Page == null)
|
if (Action == null &&
|
||||||
|
Controller == null &&
|
||||||
|
Route == null &&
|
||||||
|
_routeValues == null &&
|
||||||
|
Fragment == null &&
|
||||||
|
Area == null &&
|
||||||
|
Page == null &&
|
||||||
|
// Antiforgery will sometime be set globally via TagHelper Initializers, verify it was provided in the cshtml.
|
||||||
|
!context.AllAttributes.ContainsName(AntiforgeryAttributeName))
|
||||||
{
|
{
|
||||||
// Empty form tag such as <form></form>. Let it flow to the output as-is and only handle anti-forgery.
|
// Empty form tag such as <form></form>. Let it flow to the output as-is and only handle anti-forgery.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Form</title>
|
<title>Form</title>
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
<h2>Form Tag Helper Test</h2>
|
<h2>Form Tag Helper Test</h2>
|
||||||
|
|
||||||
<form></form>
|
<form></form>
|
||||||
|
<form action="/HtmlGeneration_Home/Form" method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
||||||
<form action="/HtmlGeneration_Home/Form" method="post"></form>
|
<form action="/HtmlGeneration_Home/Form" method="post"></form>
|
||||||
<form action="/HtmlGeneration_Home/Form" method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
<form action="/HtmlGeneration_Home/Form" method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
||||||
<form action="/HtmlGeneration_Home/Form" method="post"></form>
|
<form action="/HtmlGeneration_Home/Form" method="post"></form>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,60 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
{
|
{
|
||||||
public class FormTagHelperTest
|
public class FormTagHelperTest
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ProcessAsync_AspAntiforgeryAloneGeneratesProperFormTag()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedTagName = "form";
|
||||||
|
var metadataProvider = new TestModelMetadataProvider();
|
||||||
|
var tagHelperContext = new TagHelperContext(
|
||||||
|
tagName: "form",
|
||||||
|
allAttributes: new TagHelperAttributeList()
|
||||||
|
{
|
||||||
|
{ "asp-antiforgery", true }
|
||||||
|
},
|
||||||
|
items: new Dictionary<object, object>(),
|
||||||
|
uniqueId: "test");
|
||||||
|
var output = new TagHelperOutput(
|
||||||
|
expectedTagName,
|
||||||
|
attributes: new TagHelperAttributeList(),
|
||||||
|
getChildContentAsync: (useCachedResult, encoder) =>
|
||||||
|
{
|
||||||
|
var tagHelperContent = new DefaultTagHelperContent();
|
||||||
|
tagHelperContent.SetContent("Something");
|
||||||
|
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||||
|
});
|
||||||
|
var urlHelper = new Mock<IUrlHelper>();
|
||||||
|
var htmlGenerator = new TestableHtmlGenerator(metadataProvider, urlHelper.Object);
|
||||||
|
var viewContext = TestableHtmlGenerator.GetViewContext(
|
||||||
|
model: null,
|
||||||
|
htmlGenerator: htmlGenerator,
|
||||||
|
metadataProvider: metadataProvider);
|
||||||
|
viewContext.HttpContext.Request.Path = "/home/index";
|
||||||
|
var expectedPostContent = HtmlContentUtilities.HtmlContentToString(
|
||||||
|
htmlGenerator.GenerateAntiforgery(viewContext),
|
||||||
|
HtmlEncoder.Default);
|
||||||
|
var formTagHelper = new FormTagHelper(htmlGenerator)
|
||||||
|
{
|
||||||
|
ViewContext = viewContext,
|
||||||
|
Antiforgery = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await formTagHelper.ProcessAsync(tagHelperContext, output);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(2, output.Attributes.Count);
|
||||||
|
var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("method"));
|
||||||
|
Assert.Equal("post", attribute.Value);
|
||||||
|
attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("action"));
|
||||||
|
Assert.Equal("/home/index", attribute.Value);
|
||||||
|
Assert.Empty(output.PreContent.GetContent());
|
||||||
|
Assert.True(output.Content.GetContent().Length == 0);
|
||||||
|
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||||
|
Assert.Equal(expectedTagName, output.TagName);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ProcessAsync_EmptyHtmlStringActionGeneratesAntiforgery()
|
public async Task ProcessAsync_EmptyHtmlStringActionGeneratesAntiforgery()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
<h2>Form Tag Helper Test</h2>
|
<h2>Form Tag Helper Test</h2>
|
||||||
|
|
||||||
<form></form>
|
<form></form>
|
||||||
|
<form asp-antiforgery="true"></form>
|
||||||
<form asp-controller="HtmlGeneration_Home" asp-action="Form"></form>
|
<form asp-controller="HtmlGeneration_Home" asp-action="Form"></form>
|
||||||
<form asp-controller="HtmlGeneration_Home" asp-action="Form" asp-antiforgery="true"></form>
|
<form asp-controller="HtmlGeneration_Home" asp-action="Form" asp-antiforgery="true"></form>
|
||||||
<form asp-controller="HtmlGeneration_Home" asp-action="Form" asp-antiforgery="false"></form>
|
<form asp-controller="HtmlGeneration_Home" asp-action="Form" asp-antiforgery="false"></form>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue