diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/AntiforgeryExtensions.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/AntiforgeryExtensions.cs
new file mode 100644
index 0000000000..630316e182
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/AntiforgeryExtensions.cs
@@ -0,0 +1,81 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Text.Encodings.Web;
+using Microsoft.AspNetCore.Antiforgery;
+using Microsoft.AspNetCore.Html;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore.Mvc.ViewFeatures
+{
+ public static class AntiforgeryExtensions
+ {
+ ///
+ /// Generates an <input type="hidden"> element for an antiforgery token.
+ ///
+ /// The instance.
+ /// The associated with the current request.
+ ///
+ /// A containing an <input type="hidden"> element. This element should be put
+ /// inside a <form>.
+ ///
+ ///
+ /// This method has a side effect:
+ /// A response cookie is set if there is no valid cookie associated with the request.
+ ///
+ public static IHtmlContent GetHtml(this IAntiforgery antiforgery, HttpContext httpContext)
+ {
+ if (antiforgery == null)
+ {
+ throw new ArgumentNullException(nameof(antiforgery));
+ }
+
+ if (httpContext == null)
+ {
+ throw new ArgumentNullException(nameof(httpContext));
+ }
+
+ var tokenSet = antiforgery.GetAndStoreTokens(httpContext);
+ return new InputContent(tokenSet);
+ }
+
+ private class InputContent : IHtmlContent
+ {
+ private readonly string _fieldName;
+ private readonly string _requestToken;
+
+ public InputContent(AntiforgeryTokenSet tokenSet)
+ {
+ _fieldName = tokenSet.FormFieldName;
+ _requestToken = tokenSet.RequestToken;
+ }
+
+ // Though _requestToken normally contains only US-ASCII letters, numbers, '-', and '_', must assume the
+ // IAntiforgeryTokenSerializer implementation has been overridden. Similarly, users may choose a
+ // _fieldName containing almost any character.
+ public void WriteTo(TextWriter writer, HtmlEncoder encoder)
+ {
+ var builder = writer as IHtmlContentBuilder;
+ if (builder != null)
+ {
+ // If possible, defer encoding until we're writing to the response.
+ // But there's little reason to keep this IHtmlContent instance around.
+ builder
+ .AppendHtml("");
+ }
+
+ writer.Write("");
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/AntiforgeryExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/AntiforgeryExtensionsTest.cs
new file mode 100644
index 0000000000..33a2f370bf
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/AntiforgeryExtensionsTest.cs
@@ -0,0 +1,37 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Antiforgery;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Internal;
+using Microsoft.AspNetCore.Mvc.TestCommon;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Mvc.ViewFeatures
+{
+ ///
+ /// Extension methods for .
+ ///
+ public class AntiforgeryExtensionsTest
+ {
+ [Fact]
+ public void GetHtml_RendersInputField()
+ {
+ // Arrange
+ var antiforgery = new Mock(MockBehavior.Strict);
+ var tokenSet = new AntiforgeryTokenSet("request-token", "cookie-token", "form-field", "header");
+ antiforgery
+ .Setup(a => a.GetAndStoreTokens(It.IsAny()))
+ .Returns(tokenSet);
+
+ // Act
+ var inputElement = AntiforgeryExtensions.GetHtml(antiforgery.Object, new DefaultHttpContext());
+
+ // Assert
+ Assert.Equal(
+ @"",
+ HtmlContentUtilities.HtmlContentToString(inputElement));
+ }
+ }
+}