diff --git a/Mvc.sln b/Mvc.sln index 34855cae18..6d9e31cbc3 100644 --- a/Mvc.sln +++ b/Mvc.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 +VisualStudioVersion = 14.0.23017.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}" EndProject @@ -58,8 +58,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ContentNegotiationWebSite", "test\WebSites\ContentNegotiationWebSite\ContentNegotiationWebSite.xproj", "{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AntiForgeryWebSite", "test\WebSites\AntiForgeryWebSite\AntiForgeryWebSite.xproj", "{A353B17E-A940-4CE8-8BF9-179E24A9041F}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AddServicesWebSite", "test\WebSites\AddServicesWebSite\AddServicesWebSite.xproj", "{6A0B65CE-6B01-40D0-840D-EFF3680D1547}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FiltersWebSite", "test\WebSites\FiltersWebSite\FiltersWebSite.xproj", "{1976AC4A-FEA4-4587-A158-D9F79736D2B6}" @@ -174,6 +172,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Extens EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Extensions.Test", "test\Microsoft.AspNet.Mvc.Extensions.Test\Microsoft.AspNet.Mvc.Extensions.Test.xproj", "{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AntiforgeryTokenWebSite", "test\WebSites\AntiforgeryTokenWebSite\AntiforgeryTokenWebSite.xproj", "{A353B17E-A940-4CE8-8BF9-179E24A9041F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -394,16 +394,6 @@ Global {C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|x86.ActiveCfg = Release|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|x86.ActiveCfg = Debug|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Any CPU.Build.0 = Release|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|x86.ActiveCfg = Release|Any CPU {6A0B65CE-6B01-40D0-840D-EFF3680D1547}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6A0B65CE-6B01-40D0-840D-EFF3680D1547}.Debug|Any CPU.Build.0 = Debug|Any CPU {6A0B65CE-6B01-40D0-840D-EFF3680D1547}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -1052,6 +1042,18 @@ Global {5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|x86.ActiveCfg = Release|Any CPU {5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|x86.Build.0 = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|x86.ActiveCfg = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Debug|x86.Build.0 = Debug|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Any CPU.Build.0 = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|x86.ActiveCfg = Release|Any CPU + {A353B17E-A940-4CE8-8BF9-179E24A9041F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1079,7 +1081,6 @@ Global {62735776-46FF-4170-9392-02E128A69B89} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {EE1AB716-F102-4CA3-AD2C-214A44B459A0} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} - {A353B17E-A940-4CE8-8BF9-179E24A9041F} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {6A0B65CE-6B01-40D0-840D-EFF3680D1547} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {1976AC4A-FEA4-4587-A158-D9F79736D2B6} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {A192E504-2881-41DC-90D1-B7F1DD1134E8} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} @@ -1137,5 +1138,6 @@ Global {FCFE6024-2720-49B4-8257-9DBC6114F0F1} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {B2CA101A-87E6-4DD2-9BB2-28DA68EF1A94} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E} {5DF6EFA5-865E-450B-BF83-DE9CE88EB77C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1} + {A353B17E-A940-4CE8-8BF9-179E24A9041F} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} EndGlobalSection EndGlobal diff --git a/samples/TagHelperSample.Web/Views/Home/Create.cshtml b/samples/TagHelperSample.Web/Views/Home/Create.cshtml index aa005405f5..0da02ba4e5 100644 --- a/samples/TagHelperSample.Web/Views/Home/Create.cshtml +++ b/samples/TagHelperSample.Web/Views/Home/Create.cshtml @@ -8,9 +8,9 @@

Create

-@* anti-forgery is on by default *@ -@*
tag helper will special-case only elements with an "asp-action" or "asp-anti-forgery" attribute. *@ - +@* antiforgery is on by default *@ +@* tag helper will special-case only elements with an "asp-action" or "asp-antiforgery" attribute. *@ +
@* validation summary tag helper will target just
elements and append the list of errors *@ @* - i.e. this helper, like - var inputTag = new TagBuilder("input", _htmlEncoder) - { - Attributes = - { - { "type", "hidden" }, - { "name", _config.FormFieldName }, - { "value", _serializer.Serialize(formToken) } - } - }; - return inputTag; - } - - // [ ENTRY POINT ] - // Generates a (cookie, form) serialized token pair for the current user. - // The caller may specify an existing cookie value if one exists. If the - // 'new cookie value' out param is non-null, the caller *must* persist - // the new value to cookie storage since the original value was null or - // invalid. This method is side-effect free. - public AntiForgeryTokenSet GetTokens([NotNull] HttpContext httpContext, string cookieToken) - { - CheckSSLConfig(httpContext); - var deSerializedcookieToken = DeserializeTokenDoesNotThrow(cookieToken); - var tokenSet = GetTokens(httpContext, deSerializedcookieToken); - - var serializedCookieToken = Serialize(tokenSet.CookieToken); - var serializedFormToken = Serialize(tokenSet.FormToken); - return new AntiForgeryTokenSet(serializedFormToken, serializedCookieToken); - } - - private AntiForgeryTokenSetInternal GetTokens(HttpContext httpContext, AntiForgeryToken cookieToken) - { - var newCookieToken = ValidateAndGenerateNewCookieToken(cookieToken); - if (newCookieToken != null) - { - cookieToken = newCookieToken; - } - var formToken = _generator.GenerateFormToken( - httpContext, - ExtractIdentity(httpContext), - cookieToken); - - return new AntiForgeryTokenSetInternal() - { - // Note : The new cookie would be null if the old cookie is valid. - CookieToken = newCookieToken, - FormToken = formToken - }; - } - - private string Serialize(AntiForgeryToken token) - { - return (token != null) ? _serializer.Serialize(token) : null; - } - - // [ ENTRY POINT ] - // Given an HttpContext, validates that the anti-XSRF tokens contained - // in the cookies & form are OK for this request. - public async Task ValidateAsync([NotNull] HttpContext httpContext) - { - CheckSSLConfig(httpContext); - - // Extract cookie & form tokens - var cookieToken = _tokenStore.GetCookieToken(httpContext); - var formToken = await _tokenStore.GetFormTokenAsync(httpContext); - - // Validate - _validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), cookieToken, formToken); - } - - // [ ENTRY POINT ] - // Given the serialized string representations of a cookie & form token, - // validates that the pair is OK for this request. - public void Validate([NotNull] HttpContext httpContext, string cookieToken, string formToken) - { - CheckSSLConfig(httpContext); - - // Extract cookie & form tokens - var deserializedCookieToken = DeserializeToken(cookieToken); - var deserializedFormToken = DeserializeToken(formToken); - - // Validate - _validator.ValidateTokens( - httpContext, - ExtractIdentity(httpContext), - deserializedCookieToken, - deserializedFormToken); - } - - - /// - /// Generates and sets an anti-forgery cookie if one is not available or not valid. Also sets response headers. - /// - /// The HTTP context associated with the current call. - public void SetCookieTokenAndHeader([NotNull] HttpContext httpContext) - { - CheckSSLConfig(httpContext); - - var cookieToken = GetCookieTokenDoesNotThrow(httpContext); - cookieToken = ValidateAndGenerateNewCookieToken(cookieToken); - - SaveCookieTokenAndHeader(httpContext, cookieToken); - } - - // This method returns null if oldCookieToken is valid. - private AntiForgeryToken ValidateAndGenerateNewCookieToken(AntiForgeryToken cookieToken) - { - if (!_validator.IsCookieTokenValid(cookieToken)) - { - // Need to make sure we're always operating with a good cookie token. - var newCookieToken = _generator.GenerateCookieToken(); - Debug.Assert(_validator.IsCookieTokenValid(newCookieToken)); - return newCookieToken; - } - - return null; - } - - private void SaveCookieTokenAndHeader( - [NotNull] HttpContext httpContext, - AntiForgeryToken cookieToken) - { - if (cookieToken != null) - { - // Persist the new cookie if it is not null. - _tokenStore.SaveCookieToken(httpContext, cookieToken); - } - - if (!_config.SuppressXFrameOptionsHeader) - { - // Adding X-Frame-Options header to prevent ClickJacking. See - // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10 - // for more information. - httpContext.Response.Headers.Set("X-Frame-Options", "SAMEORIGIN"); - } - } - - private class AntiForgeryTokenSetInternal - { - public AntiForgeryToken FormToken { get; set; } - - public AntiForgeryToken CookieToken { get; set; } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/BinaryBlob.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/BinaryBlob.cs deleted file mode 100644 index 01a48d409d..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/BinaryBlob.cs +++ /dev/null @@ -1,117 +0,0 @@ -// 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.Diagnostics; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; - -namespace Microsoft.AspNet.Mvc -{ - // Represents a binary blob (token) that contains random data. - // Useful for binary data inside a serialized stream. - [DebuggerDisplay("{DebuggerString}")] - internal sealed class BinaryBlob : IEquatable - { - private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create(); - private readonly byte[] _data; - - // Generates a new token using a specified bit length. - public BinaryBlob(int bitLength) - : this(bitLength, GenerateNewToken(bitLength)) - { - } - - // Generates a token using an existing binary value. - public BinaryBlob(int bitLength, byte[] data) - { - if (bitLength < 32 || bitLength % 8 != 0) - { - throw new ArgumentOutOfRangeException(nameof(bitLength)); - } - if (data == null || data.Length != bitLength / 8) - { - throw new ArgumentOutOfRangeException(nameof(data)); - } - - _data = data; - } - - public int BitLength - { - get - { - return checked(_data.Length * 8); - } - } - - private string DebuggerString - { - get - { - var sb = new StringBuilder("0x", 2 + (_data.Length * 2)); - for (var i = 0; i < _data.Length; i++) - { - sb.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", _data[i]); - } - return sb.ToString(); - } - } - - public override bool Equals(object obj) - { - return Equals(obj as BinaryBlob); - } - - public bool Equals(BinaryBlob other) - { - if (other == null) - { - return false; - } - - Debug.Assert(this._data.Length == other._data.Length); - return AreByteArraysEqual(this._data, other._data); - } - - public byte[] GetData() - { - return _data; - } - - public override int GetHashCode() - { - // Since data should contain uniformly-distributed entropy, the - // first 32 bits can serve as the hash code. - Debug.Assert(_data != null && _data.Length >= (32 / 8)); - return BitConverter.ToInt32(_data, 0); - } - - private static byte[] GenerateNewToken(int bitLength) - { - var data = new byte[bitLength / 8]; - _randomNumberGenerator.GetBytes(data); - return data; - } - - // Need to mark it with NoInlining and NoOptimization attributes to ensure that the - // operation runs in constant time. - [MethodImplAttribute(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] - private static bool AreByteArraysEqual(byte[] a, byte[] b) - { - if (a == null || b == null || a.Length != b.Length) - { - return false; - } - - var areEqual = true; - for (var i = 0; i < a.Length; i++) - { - areEqual &= (a[i] == b[i]); - } - return areEqual; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultAntiForgeryAdditionalDataProvider.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultAntiForgeryAdditionalDataProvider.cs deleted file mode 100644 index 0ad599ccfc..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultAntiForgeryAdditionalDataProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -// 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.AspNet.Http; - -namespace Microsoft.AspNet.Mvc -{ - /// - /// A default implementation. - /// - public class DefaultAntiForgeryAdditionalDataProvider : IAntiForgeryAdditionalDataProvider - { - /// - public virtual string GetAdditionalData(HttpContext context) - { - return string.Empty; - } - - /// - public virtual bool ValidateAdditionalData(HttpContext context, string additionalData) - { - // Default implementation does not understand anything but empty data. - return string.IsNullOrEmpty(additionalData); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultClaimUidExtractor.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultClaimUidExtractor.cs deleted file mode 100644 index 9f748560d1..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/DefaultClaimUidExtractor.cs +++ /dev/null @@ -1,80 +0,0 @@ -// 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.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security.Claims; -using System.Security.Cryptography; - -namespace Microsoft.AspNet.Mvc -{ - /// - /// Default implementation of . - /// - public class DefaultClaimUidExtractor : IClaimUidExtractor - { - /// - public string ExtractClaimUid(ClaimsIdentity claimsIdentity) - { - if (claimsIdentity == null || !claimsIdentity.IsAuthenticated) - { - // Skip anonymous users - return null; - } - - var uniqueIdentifierParameters = GetUniqueIdentifierParameters(claimsIdentity); - var claimUidBytes = ComputeSHA256(uniqueIdentifierParameters); - return Convert.ToBase64String(claimUidBytes); - } - - internal static IEnumerable GetUniqueIdentifierParameters(ClaimsIdentity claimsIdentity) - { - var nameIdentifierClaim = claimsIdentity.FindFirst( - claim => string.Equals(ClaimTypes.NameIdentifier, claim.Type, StringComparison.Ordinal)); - if (nameIdentifierClaim != null && !string.IsNullOrEmpty(nameIdentifierClaim.Value)) - { - return new string[] - { - ClaimTypes.NameIdentifier, - nameIdentifierClaim.Value - }; - } - - // We Do not understand this claimsIdentity, fallback on serializing the entire claims Identity. - var claims = claimsIdentity.Claims.ToList(); - claims.Sort((a, b) => string.Compare(a.Type, b.Type, StringComparison.Ordinal)); - var identifierParameters = new List(); - foreach (var claim in claims) - { - identifierParameters.Add(claim.Type); - identifierParameters.Add(claim.Value); - } - - return identifierParameters; - } - - private static byte[] ComputeSHA256(IEnumerable parameters) - { - using (var ms = new MemoryStream()) - { - using (var bw = new BinaryWriter(ms)) - { - foreach (string parameter in parameters) - { - bw.Write(parameter); // also writes the length as a prefix; unambiguous - } - - bw.Flush(); - - using (var sha256 = SHA256.Create()) - { - var retVal = sha256.ComputeHash(ms.ToArray(), 0, checked((int)ms.Length)); - return retVal; - } - } - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryAdditionalDataProvider.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryAdditionalDataProvider.cs deleted file mode 100644 index f4ea1c9ed4..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryAdditionalDataProvider.cs +++ /dev/null @@ -1,39 +0,0 @@ -// 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.AspNet.Http; - -namespace Microsoft.AspNet.Mvc -{ - /// - /// Allows providing or validating additional custom data for anti-forgery tokens. - /// For example, the developer could use this to supply a nonce when the token is - /// generated, then he could validate the nonce when the token is validated. - /// - /// - /// The anti-forgery system already embeds the client's username within the - /// generated tokens. This interface provides and consumes supplemental - /// data. If an incoming anti-forgery token contains supplemental data but no - /// additional data provider is configured, the supplemental data will not be - /// validated. - /// - public interface IAntiForgeryAdditionalDataProvider - { - /// - /// Provides additional data to be stored for the anti-forgery tokens generated - /// during this request. - /// - /// Information about the current request. - /// Supplemental data to embed within the anti-forgery token. - string GetAdditionalData(HttpContext context); - - /// - /// Validates additional data that was embedded inside an incoming anti-forgery - /// token. - /// - /// Information about the current request. - /// Supplemental data that was embedded within the token. - /// True if the data is valid; false if the data is invalid. - bool ValidateAdditionalData(HttpContext context, string additionalData); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenGenerator.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenGenerator.cs deleted file mode 100644 index 4cb93a1c71..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenGenerator.cs +++ /dev/null @@ -1,22 +0,0 @@ -// 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.Security.Claims; -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Mvc -{ - // Provides configuration information about the anti-forgery system. - internal interface IAntiForgeryTokenGenerator - { - // Generates a new random cookie token. - AntiForgeryToken GenerateCookieToken(); - - // Given a cookie token, generates a corresponding form token. - // The incoming cookie token must be valid. - AntiForgeryToken GenerateFormToken( - HttpContext httpContext, - ClaimsIdentity identity, - AntiForgeryToken cookieToken); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenSerializer.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenSerializer.cs deleted file mode 100644 index 07e6501fe1..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenSerializer.cs +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -namespace Microsoft.AspNet.Mvc -{ - // Abstracts out the serialization process for an anti-forgery token - internal interface IAntiForgeryTokenSerializer - { - AntiForgeryToken Deserialize(string serializedToken); - string Serialize(AntiForgeryToken token); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenStore.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenStore.cs deleted file mode 100644 index 6c5d9bf596..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenStore.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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.Threading.Tasks; -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Mvc -{ - // Provides an abstraction around how tokens are persisted and retrieved for a request - internal interface IAntiForgeryTokenStore - { - AntiForgeryToken GetCookieToken(HttpContext httpContext); - Task GetFormTokenAsync(HttpContext httpContext); - void SaveCookieToken(HttpContext httpContext, AntiForgeryToken token); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenValidator.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenValidator.cs deleted file mode 100644 index caea47d0ae..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IAntiForgeryTokenValidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -// 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.Security.Claims; -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Mvc -{ - // Provides an abstraction around something that can validate anti-XSRF tokens - internal interface IAntiForgeryTokenValidator - { - // Determines whether an existing cookie token is valid (well-formed). - // If it is not, the caller must call GenerateCookieToken() before calling GenerateFormToken(). - bool IsCookieTokenValid(AntiForgeryToken cookieToken); - - // Validates a (cookie, form) token pair. - void ValidateTokens( - HttpContext httpContext, - ClaimsIdentity identity, - AntiForgeryToken cookieToken, - AntiForgeryToken formToken); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IClaimUidExtractor.cs b/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IClaimUidExtractor.cs deleted file mode 100644 index 2ff15b5dc5..0000000000 --- a/src/Microsoft.AspNet.Mvc.Extensions/AntiForgery/IClaimUidExtractor.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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.Security.Claims; - -namespace Microsoft.AspNet.Mvc -{ - /// - /// This interface can extract unique identifers for a claims-based identity. - /// - public interface IClaimUidExtractor - { - /// - /// Extracts claims identifier. - /// - /// The . - /// The claims identifier. - string ExtractClaimUid(ClaimsIdentity identity); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAttribute.cs b/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAttribute.cs index def4017067..7cb49b4947 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAttribute.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAttribute.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNet.Antiforgery; using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Mvc @@ -13,8 +14,8 @@ namespace Microsoft.AspNet.Mvc public IFilter CreateInstance(IServiceProvider serviceProvider) { - var antiForgery = serviceProvider.GetRequiredService(); - return new ValidateAntiForgeryTokenAuthorizationFilter(antiForgery); + var antiforgery = serviceProvider.GetRequiredService(); + return new ValidateAntiforgeryTokenAuthorizationFilter(antiforgery); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAuthorizationFilter.cs b/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiforgeryTokenAuthorizationFilter.cs similarity index 54% rename from src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAuthorizationFilter.cs rename to src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiforgeryTokenAuthorizationFilter.cs index fbe3bced94..7a15d74d9a 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiForgeryTokenAuthorizationFilter.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Filters/ValidateAntiforgeryTokenAuthorizationFilter.cs @@ -2,22 +2,23 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNet.Antiforgery; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc { - public class ValidateAntiForgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter + public class ValidateAntiforgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter { - private readonly AntiForgery _antiForgery; + private readonly IAntiforgery _antiforgery; - public ValidateAntiForgeryTokenAuthorizationFilter([NotNull] AntiForgery antiForgery) + public ValidateAntiforgeryTokenAuthorizationFilter([NotNull] IAntiforgery antiforgery) { - _antiForgery = antiForgery; + _antiforgery = antiforgery; } public async Task OnAuthorizationAsync([NotNull] AuthorizationContext context) { - await _antiForgery.ValidateAsync(context.HttpContext); + await _antiforgery.ValidateRequestAsync(context.HttpContext); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Extensions/Properties/Resources.Designer.cs index f3d168ad1b..790ddba09b 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Properties/Resources.Designer.cs @@ -42,150 +42,6 @@ namespace Microsoft.AspNet.Mvc.Extensions return string.Format(CultureInfo.CurrentCulture, GetString("ObjectResult_MatchAllContentType"), p0, p1); } - /// - /// The provided anti-forgery token failed a custom data check. - /// - internal static string AntiForgeryToken_AdditionalDataCheckFailed - { - get { return GetString("AntiForgeryToken_AdditionalDataCheckFailed"); } - } - - /// - /// The provided anti-forgery token failed a custom data check. - /// - internal static string FormatAntiForgeryToken_AdditionalDataCheckFailed() - { - return GetString("AntiForgeryToken_AdditionalDataCheckFailed"); - } - - /// - /// The provided anti-forgery token was meant for a different claims-based user than the current user. - /// - internal static string AntiForgeryToken_ClaimUidMismatch - { - get { return GetString("AntiForgeryToken_ClaimUidMismatch"); } - } - - /// - /// The provided anti-forgery token was meant for a different claims-based user than the current user. - /// - internal static string FormatAntiForgeryToken_ClaimUidMismatch() - { - return GetString("AntiForgeryToken_ClaimUidMismatch"); - } - - /// - /// The required anti-forgery cookie "{0}" is not present. - /// - internal static string AntiForgeryToken_CookieMissing - { - get { return GetString("AntiForgeryToken_CookieMissing"); } - } - - /// - /// The required anti-forgery cookie "{0}" is not present. - /// - internal static string FormatAntiForgeryToken_CookieMissing(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("AntiForgeryToken_CookieMissing"), p0); - } - - /// - /// The anti-forgery token could not be decrypted. - /// - internal static string AntiForgeryToken_DeserializationFailed - { - get { return GetString("AntiForgeryToken_DeserializationFailed"); } - } - - /// - /// The anti-forgery token could not be decrypted. - /// - internal static string FormatAntiForgeryToken_DeserializationFailed() - { - return GetString("AntiForgeryToken_DeserializationFailed"); - } - - /// - /// The required anti-forgery form field "{0}" is not present. - /// - internal static string AntiForgeryToken_FormFieldMissing - { - get { return GetString("AntiForgeryToken_FormFieldMissing"); } - } - - /// - /// The required anti-forgery form field "{0}" is not present. - /// - internal static string FormatAntiForgeryToken_FormFieldMissing(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("AntiForgeryToken_FormFieldMissing"), p0); - } - - /// - /// The anti-forgery cookie token and form field token do not match. - /// - internal static string AntiForgeryToken_SecurityTokenMismatch - { - get { return GetString("AntiForgeryToken_SecurityTokenMismatch"); } - } - - /// - /// The anti-forgery cookie token and form field token do not match. - /// - internal static string FormatAntiForgeryToken_SecurityTokenMismatch() - { - return GetString("AntiForgeryToken_SecurityTokenMismatch"); - } - - /// - /// Validation of the provided anti-forgery token failed. The cookie "{0}" and the form field "{1}" were swapped. - /// - internal static string AntiForgeryToken_TokensSwapped - { - get { return GetString("AntiForgeryToken_TokensSwapped"); } - } - - /// - /// Validation of the provided anti-forgery token failed. The cookie "{0}" and the form field "{1}" were swapped. - /// - internal static string FormatAntiForgeryToken_TokensSwapped(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("AntiForgeryToken_TokensSwapped"), p0, p1); - } - - /// - /// The provided anti-forgery token was meant for user "{0}", but the current user is "{1}". - /// - internal static string AntiForgeryToken_UsernameMismatch - { - get { return GetString("AntiForgeryToken_UsernameMismatch"); } - } - - /// - /// The provided anti-forgery token was meant for user "{0}", but the current user is "{1}". - /// - internal static string FormatAntiForgeryToken_UsernameMismatch(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("AntiForgeryToken_UsernameMismatch"), p0, p1); - } - - /// - /// The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, but the current request is not an SSL request. - /// - internal static string AntiForgeryWorker_RequireSSL - { - get { return GetString("AntiForgeryWorker_RequireSSL"); } - } - - /// - /// The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, but the current request is not an SSL request. - /// - internal static string FormatAntiForgeryWorker_RequireSSL() - { - return GetString("AntiForgeryWorker_RequireSSL"); - } - /// /// The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task. /// @@ -234,22 +90,6 @@ namespace Microsoft.AspNet.Mvc.Extensions return string.Format(CultureInfo.CurrentCulture, GetString("ClaimUidExtractor_ClaimNotPresent"), p0); } - /// - /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user. - /// - internal static string TokenValidator_AuthenticatedUserWithoutUsername - { - get { return GetString("TokenValidator_AuthenticatedUserWithoutUsername"); } - } - - /// - /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user. - /// - internal static string FormatTokenValidator_AuthenticatedUserWithoutUsername(object p0) - { - return string.Format(CultureInfo.CurrentCulture, GetString("TokenValidator_AuthenticatedUserWithoutUsername"), p0); - } - /// /// The class ReflectedActionFilterEndPoint only supports ReflectedActionDescriptors. /// diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/DefaultHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/DefaultHtmlGenerator.cs index 19c35ec303..9306902a24 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/DefaultHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/DefaultHtmlGenerator.cs @@ -9,6 +9,7 @@ using System.Globalization; using System.Linq; using System.Reflection; using System.Text; +using Microsoft.AspNet.Antiforgery; using Microsoft.AspNet.Mvc.Extensions; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Validation; @@ -25,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.Rendering private static readonly MethodInfo ConvertEnumFromStringMethod = typeof(DefaultHtmlGenerator).GetTypeInfo().GetDeclaredMethod(nameof(ConvertEnumFromString)); - private readonly AntiForgery _antiForgery; + private readonly IAntiforgery _antiforgery; private readonly IClientModelValidatorProvider _clientModelValidatorProvider; private readonly IModelMetadataProvider _metadataProvider; private readonly IUrlHelper _urlHelper; @@ -34,20 +35,20 @@ namespace Microsoft.AspNet.Mvc.Rendering /// /// Initializes a new instance of the class. /// - /// The instance which is used to generate anti-forgery + /// The instance which is used to generate antiforgery /// tokens. /// The accessor for . /// The . /// The . /// The . public DefaultHtmlGenerator( - [NotNull] AntiForgery antiForgery, + [NotNull] IAntiforgery antiforgery, [NotNull] IOptions optionsAccessor, [NotNull] IModelMetadataProvider metadataProvider, [NotNull] IUrlHelper urlHelper, [NotNull] IHtmlEncoder htmlEncoder) { - _antiForgery = antiForgery; + _antiforgery = antiforgery; var clientValidatorProviders = optionsAccessor.Options.ClientModelValidatorProviders; _clientModelValidatorProvider = new CompositeClientModelValidatorProvider(clientValidatorProviders); _metadataProvider = metadataProvider; @@ -95,10 +96,10 @@ namespace Microsoft.AspNet.Mvc.Rendering } /// - public virtual TagBuilder GenerateAntiForgery([NotNull] ViewContext viewContext) + public virtual HtmlString GenerateAntiforgery([NotNull] ViewContext viewContext) { - var tagBuilder = _antiForgery.GetHtml(viewContext.HttpContext); - return tagBuilder; + var tag = _antiforgery.GetHtml(viewContext.HttpContext); + return new HtmlString(tag); } /// diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/HtmlHelper.cs index d4256e17bf..cd4590ac44 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/HtmlHelper.cs @@ -221,13 +221,8 @@ namespace Microsoft.AspNet.Mvc.Rendering /// public HtmlString AntiForgeryToken() { - var tagBuilder = _htmlGenerator.GenerateAntiForgery(ViewContext); - if (tagBuilder == null) - { - return HtmlString.Empty; - } - - return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing); + var html = _htmlGenerator.GenerateAntiforgery(ViewContext); + return html ?? HtmlString.Empty; } /// diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/IHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/IHtmlGenerator.cs index 545ac3d4a7..4993163f01 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/IHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/Html/IHtmlGenerator.cs @@ -31,7 +31,12 @@ namespace Microsoft.AspNet.Mvc.Rendering object routeValues, object htmlAttributes); - TagBuilder GenerateAntiForgery([NotNull] ViewContext viewContext); + /// + /// Genrate an <input type="hidden".../> element containing an antiforgery token. + /// + /// The instance for the current scope. + /// An instance for the <input type="hidden".../> element. + HtmlString GenerateAntiforgery([NotNull] ViewContext viewContext); /// /// Generate a <input type="checkbox".../> element. diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/IHtmlHelper.cs index 47f484c262..c999491aad 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Rendering/IHtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/Rendering/IHtmlHelper.cs @@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Mvc.Rendering object htmlAttributes); /// - /// Returns a <hidden> element (anti-forgery token) that will be validated when the containing + /// Returns a <hidden> element (antiforgery token) that will be validated when the containing /// <form> is submitted. /// /// A new containing the <hidden> element. diff --git a/src/Microsoft.AspNet.Mvc.Extensions/Resources.resx b/src/Microsoft.AspNet.Mvc.Extensions/Resources.resx index 6f2c43bcec..796f9aba62 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.Extensions/Resources.resx @@ -1,17 +1,17 @@  - @@ -123,33 +123,6 @@ The content-type '{0}' added in the '{1}' property is invalid. Media types which match all types or match all subtypes are not supported. - - The provided anti-forgery token failed a custom data check. - - - The provided anti-forgery token was meant for a different claims-based user than the current user. - - - The required anti-forgery cookie "{0}" is not present. - - - The anti-forgery token could not be decrypted. - - - The required anti-forgery form field "{0}" is not present. - - - The anti-forgery cookie token and form field token do not match. - - - Validation of the provided anti-forgery token failed. The cookie "{0}" and the form field "{1}" were swapped. - - - The provided anti-forgery token was meant for user "{0}", but the current user is "{1}". - - - The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, but the current request is not an SSL request. - The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task. @@ -159,9 +132,6 @@ A claim of type '{0}' was not present on the provided ClaimsIdentity. - - The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user. - The class ReflectedActionFilterEndPoint only supports ReflectedActionDescriptors. diff --git a/src/Microsoft.AspNet.Mvc.Extensions/project.json b/src/Microsoft.AspNet.Mvc.Extensions/project.json index 09fd6e9014..a18f0c2253 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/project.json +++ b/src/Microsoft.AspNet.Mvc.Extensions/project.json @@ -5,6 +5,7 @@ "warningsAsErrors": true }, "dependencies": { + "Microsoft.AspNet.Antiforgery": "1.0.0-*", "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.AspNet.Authorization": "1.0.0-*", "Microsoft.AspNet.Cors.Core": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs index 9fab07d41e..5d4f46e78e 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.AspNet.Antiforgery; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Razor.Internal; using Microsoft.AspNet.Mvc.Rendering; @@ -781,8 +782,8 @@ namespace Microsoft.AspNet.Mvc.Razor /// The value returned is a token value that allows FlushAsync to work directly in an HTML /// section. However the value does not represent the rendered content. /// This method also writes out headers, so any modifications to headers must be done before - /// is called. For example, call to send - /// anti-forgery cookie token and X-Frame-Options header to client before this method flushes headers out. + /// is called. For example, call to send + /// antiforgery cookie token and X-Frame-Options header to client before this method flushes headers out. /// public async Task FlushAsync() { @@ -843,15 +844,15 @@ namespace Microsoft.AspNet.Mvc.Razor } /// - /// Sets anti-forgery cookie and X-Frame-Options header on the response. + /// Sets antiforgery cookie and X-Frame-Options header on the response. /// /// A that returns a . - /// Call this method to send anti-forgery cookie token and X-Frame-Options header to client + /// Call this method to send antiforgery cookie token and X-Frame-Options header to client /// before flushes the headers. - public virtual HtmlString SetAntiForgeryCookieAndHeader() + public virtual HtmlString SetAntiforgeryCookieAndHeader() { - var antiForgery = Context.RequestServices.GetRequiredService(); - antiForgery.SetCookieTokenAndHeader(Context); + var antiforgery = Context.RequestServices.GetRequiredService(); + antiforgery.SetCookieTokenAndHeader(Context); return HtmlString.Empty; } diff --git a/src/Microsoft.AspNet.Mvc.TagHelpers/FormTagHelper.cs b/src/Microsoft.AspNet.Mvc.TagHelpers/FormTagHelper.cs index 87fd6f7b40..44f87cbcf3 100644 --- a/src/Microsoft.AspNet.Mvc.TagHelpers/FormTagHelper.cs +++ b/src/Microsoft.AspNet.Mvc.TagHelpers/FormTagHelper.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers /// implementation targeting <form> elements. /// [TargetElement("form", Attributes = ActionAttributeName)] - [TargetElement("form", Attributes = AntiForgeryAttributeName)] + [TargetElement("form", Attributes = AntiforgeryAttributeName)] [TargetElement("form", Attributes = ControllerAttributeName)] [TargetElement("form", Attributes = RouteAttributeName)] [TargetElement("form", Attributes = RouteValuesDictionaryName)] @@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers public class FormTagHelper : TagHelper { private const string ActionAttributeName = "asp-action"; - private const string AntiForgeryAttributeName = "asp-anti-forgery"; + private const string AntiforgeryAttributeName = "asp-antiforgery"; private const string ControllerAttributeName = "asp-controller"; private const string RouteAttributeName = "asp-route"; private const string RouteValuesDictionaryName = "asp-all-route-data"; @@ -56,11 +56,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers public string Controller { get; set; } /// - /// Whether the anti-forgery token should be generated. + /// Whether the antiforgery token should be generated. /// /// Defaults to false if user provides an action attribute; true otherwise. - [HtmlAttributeName(AntiForgeryAttributeName)] - public bool? AntiForgery { get; set; } + [HtmlAttributeName(AntiforgeryAttributeName)] + public bool? Antiforgery { get; set; } /// /// Name of the route. @@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers /// /// - /// Does nothing if user provides an action attribute and is null or + /// Does nothing if user provides an action attribute and is null or /// false. /// /// @@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers /// public override void Process(TagHelperContext context, TagHelperOutput output) { - var antiForgeryDefault = true; + var antiforgeryDefault = true; // If "action" is already set, it means the user is attempting to use a normal . if (output.Attributes.ContainsName(HtmlActionAttributeName)) @@ -107,9 +107,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers RouteValuesPrefix)); } - // User is using the FormTagHelper like a normal tag. Anti-forgery default should be false to - // not force the anti-forgery token on the user. - antiForgeryDefault = false; + // User is using the FormTagHelper like a normal tag. Antiforgery default should be false to + // not force the antiforgery token on the user. + antiforgeryDefault = false; } else { @@ -158,12 +158,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers } } - if (AntiForgery ?? antiForgeryDefault) + if (Antiforgery ?? antiforgeryDefault) { - var antiForgeryTagBuilder = Generator.GenerateAntiForgery(ViewContext); - if (antiForgeryTagBuilder != null) + var antiforgeryTag = Generator.GenerateAntiforgery(ViewContext); + if (antiforgeryTag != null) { - output.PostContent.Append(antiForgeryTagBuilder.ToString(TagRenderMode.SelfClosing)); + output.PostContent.Append(antiforgeryTag.ToString()); } } } diff --git a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs index b5deb66160..96c45cac3e 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs @@ -33,18 +33,6 @@ namespace Microsoft.Framework.DependencyInjection return services; } - /// - /// Configures a set of for the application. - /// - /// The services available in the application. - /// The which need to be configured. - public static void ConfigureAntiforgery( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - services.Configure(setupAction); - } - /// /// Configures a set of for the application. /// @@ -245,11 +233,6 @@ namespace Microsoft.Framework.DependencyInjection services.TryAddSingleton(); services.TryAddTransient(); - // Security and Authorization - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(); - // Api Description services.TryAddSingleton(); services.TryAddEnumerable( @@ -287,6 +270,7 @@ namespace Microsoft.Framework.DependencyInjection private static void ConfigureDefaultServices(IServiceCollection services) { services.AddDataProtection(); + services.AddAntiforgery(); services.AddCors(); services.AddAuthorization(); services.AddWebEncoders(); diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryOptionsTests.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryOptionsTests.cs deleted file mode 100644 index 9d05a35d10..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryOptionsTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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 Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class AntiForgeryOptionsTests - { - [Fact] - public void CookieName_SettingNullValue_Throws() - { - // Arrange - var options = new AntiForgeryOptions(); - - // Act & Assert - var ex = Assert.Throws(() => options.CookieName = null); - Assert.Equal("The 'CookieName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." + - Environment.NewLine + "Parameter name: value", ex.Message); - } - - [Fact] - public void FormFieldName_SettingNullValue_Throws() - { - // Arrange - var options = new AntiForgeryOptions(); - - // Act & Assert - var ex = Assert.Throws(() => options.FormFieldName = null); - Assert.Equal("The 'FormFieldName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." + - Environment.NewLine + "Parameter name: value", ex.Message); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenSerializerTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenSerializerTest.cs deleted file mode 100644 index 7923f5b091..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenSerializerTest.cs +++ /dev/null @@ -1,181 +0,0 @@ -// 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.Collections.Generic; -using System.Linq; -using Microsoft.AspNet.DataProtection; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class AntiForgeryTokenSerializerTest - { - private static readonly Mock _dataProtector = GetDataProtector(); - private static readonly BinaryBlob _claimUid = new BinaryBlob(256, new byte[] { 0x6F, 0x16, 0x48, 0xE9, 0x72, 0x49, 0xAA, 0x58, 0x75, 0x40, 0x36, 0xA6, 0x7E, 0x24, 0x8C, 0xF0, 0x44, 0xF0, 0x7E, 0xCF, 0xB0, 0xED, 0x38, 0x75, 0x56, 0xCE, 0x02, 0x9A, 0x4F, 0x9A, 0x40, 0xE0 }); - private static readonly BinaryBlob _securityToken = new BinaryBlob(128, new byte[] { 0x70, 0x5E, 0xED, 0xCC, 0x7D, 0x42, 0xF1, 0xD6, 0xB3, 0xB9, 0x8A, 0x59, 0x36, 0x25, 0xBB, 0x4C }); - private const byte _salt = 0x05; - - [Theory] - [InlineData( - "01" // Version - + "705EEDCC7D42F1D6B3B9" // SecurityToken - // (WRONG!) Stream ends too early - )] - [InlineData( - "01" // Version - + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - + "01" // IsSessionToken - + "00" // (WRONG!) Too much data in stream - )] - [InlineData( - "02" // (WRONG! - must be 0x01) Version - + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - + "01" // IsSessionToken - )] - [InlineData( - "01" // Version - + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - + "00" // IsSessionToken - + "00" // IsClaimsBased - + "05" // Username length header - + "0000" // (WRONG!) Too little data in stream - )] - public void Deserialize_BadToken_Throws(string serializedToken) - { - // Arrange - var testSerializer = new AntiForgeryTokenSerializer(_dataProtector.Object); - - // Act & assert - var ex = Assert.Throws(() => testSerializer.Deserialize(serializedToken)); - Assert.Equal(@"The anti-forgery token could not be decrypted.", ex.Message); - } - - [Fact] - public void Serialize_FieldToken_WithClaimUid_TokenRoundTripSuccessful() - { - // Arrange - var testSerializer = new AntiForgeryTokenSerializer(_dataProtector.Object); - - //"01" // Version - //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - //+ "00" // IsSessionToken - //+ "01" // IsClaimsBased - //+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid - //+ "05" // AdditionalData length header - //+ "E282AC3437"; // AdditionalData ("€47") as UTF8 - var token = new AntiForgeryToken() - { - SecurityToken = _securityToken, - IsSessionToken = false, - ClaimUid = _claimUid, - AdditionalData = "€47" - }; - - // Act - var actualSerializedData = testSerializer.Serialize(token); - var deserializedToken = testSerializer.Deserialize(actualSerializedData); - - // Assert - AssertTokensEqual(token, deserializedToken); - _dataProtector.Verify(); - } - - [Fact] - public void Serialize_FieldToken_WithUsername_TokenRoundTripSuccessful() - { - // Arrange - var testSerializer = new AntiForgeryTokenSerializer(_dataProtector.Object); - - //"01" // Version - //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - //+ "00" // IsSessionToken - //+ "00" // IsClaimsBased - //+ "08" // Username length header - //+ "4AC3A972C3B46D65" // Username ("Jérôme") as UTF8 - //+ "05" // AdditionalData length header - //+ "E282AC3437"; // AdditionalData ("€47") as UTF8 - var token = new AntiForgeryToken() - { - SecurityToken = _securityToken, - IsSessionToken = false, - Username = "Jérôme", - AdditionalData = "€47" - }; - - // Act - var actualSerializedData = testSerializer.Serialize(token); - var deserializedToken = testSerializer.Deserialize(actualSerializedData); - - // Assert - AssertTokensEqual(token, deserializedToken); - _dataProtector.Verify(); - } - - [Fact] - public void Serialize_SessionToken_TokenRoundTripSuccessful() - { - // Arrange - var testSerializer = new AntiForgeryTokenSerializer(_dataProtector.Object); - - //"01" // Version - //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken - //+ "01"; // IsSessionToken - var token = new AntiForgeryToken() - { - SecurityToken = _securityToken, - IsSessionToken = true - }; - - // Act - string actualSerializedData = testSerializer.Serialize(token); - var deserializedToken = testSerializer.Deserialize(actualSerializedData); - - // Assert - AssertTokensEqual(token, deserializedToken); - _dataProtector.Verify(); - } - - private static Mock GetDataProtector() - { - var mockCryptoSystem = new Mock(); - mockCryptoSystem.Setup(o => o.Protect(It.IsAny())) - .Returns(Protect) - .Verifiable(); - mockCryptoSystem.Setup(o => o.Unprotect(It.IsAny())) - .Returns(UnProtect) - .Verifiable(); - return mockCryptoSystem; - } - - private static byte[] Protect(byte[] data) - { - var input = new List(data); - input.Add(_salt); - return input.ToArray(); - } - - private static byte[] UnProtect(byte[] data) - { - var salt = data[data.Length - 1]; - if (salt != _salt) - { - throw new ArgumentException("Invalid salt value in data"); - } - - return data.Take(data.Length - 1).ToArray(); - } - - private static void AssertTokensEqual(AntiForgeryToken expected, AntiForgeryToken actual) - { - Assert.NotNull(expected); - Assert.NotNull(actual); - Assert.Equal(expected.AdditionalData, actual.AdditionalData); - Assert.Equal(expected.ClaimUid, actual.ClaimUid); - Assert.Equal(expected.IsSessionToken, actual.IsSessionToken); - Assert.Equal(expected.SecurityToken, actual.SecurityToken); - Assert.Equal(expected.Username, actual.Username); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenStoreTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenStoreTest.cs deleted file mode 100644 index 30200b427a..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenStoreTest.cs +++ /dev/null @@ -1,425 +0,0 @@ -// 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.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNet.Http; -using Microsoft.Framework.DependencyInjection; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class AntiForgeryTokenStoreTest - { - private readonly string _cookieName = "cookie-name"; - - [Fact] - public void GetCookieToken_CookieDoesNotExist_ReturnsNull() - { - // Arrange - var requestCookies = new Mock(); - requestCookies - .Setup(o => o.Get(It.IsAny())) - .Returns(string.Empty); - var mockHttpContext = new Mock(); - mockHttpContext - .Setup(o => o.Request.Cookies) - .Returns(requestCookies.Object); - var contextAccessor = new ScopedInstance(); - mockHttpContext.SetupGet(o => o.RequestServices) - .Returns(GetServiceProvider(contextAccessor)); - var config = new AntiForgeryOptions() - { - CookieName = _cookieName - }; - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: null); - - // Act - var token = tokenStore.GetCookieToken(mockHttpContext.Object); - - // Assert - Assert.Null(token); - } - - [Fact] - public void GetCookieToken_CookieIsMissingInRequest_LooksUpCookieInAntiForgeryContext() - { - // Arrange - var requestCookies = new Mock(); - requestCookies - .Setup(o => o.Get(It.IsAny())) - .Returns(string.Empty); - var mockHttpContext = new Mock(); - mockHttpContext - .Setup(o => o.Request.Cookies) - .Returns(requestCookies.Object); - var contextAccessor = new ScopedInstance(); - mockHttpContext.SetupGet(o => o.RequestServices) - .Returns(GetServiceProvider(contextAccessor)); - - // add a cookie explicitly. - var cookie = new AntiForgeryToken(); - contextAccessor.Value = new AntiForgeryContext() { CookieToken = cookie }; - var config = new AntiForgeryOptions() - { - CookieName = _cookieName - }; - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: null); - - // Act - var token = tokenStore.GetCookieToken(mockHttpContext.Object); - - // Assert - Assert.Equal(cookie, token); - } - - [Fact] - public void GetCookieToken_CookieIsEmpty_ReturnsNull() - { - // Arrange - var mockHttpContext = GetMockHttpContext(_cookieName, string.Empty); - - var config = new AntiForgeryOptions() - { - CookieName = _cookieName - }; - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: null); - - // Act - var token = tokenStore.GetCookieToken(mockHttpContext); - - // Assert - Assert.Null(token); - } - - [Fact] - public void GetCookieToken_CookieIsInvalid_PropagatesException() - { - // Arrange - var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value"); - var config = new AntiForgeryOptions() - { - CookieName = _cookieName - }; - - var expectedException = new InvalidOperationException("some exception"); - var mockSerializer = new Mock(); - mockSerializer - .Setup(o => o.Deserialize("invalid-value")) - .Throws(expectedException); - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: mockSerializer.Object); - - // Act & assert - var ex = Assert.Throws(() => tokenStore.GetCookieToken(mockHttpContext)); - Assert.Same(expectedException, ex); - } - - [Fact] - public void GetCookieToken_CookieIsValid_ReturnsToken() - { - // Arrange - var expectedToken = new AntiForgeryToken(); - var mockHttpContext = GetMockHttpContext(_cookieName, "valid-value"); - - var config = new AntiForgeryOptions() - { - CookieName = _cookieName - }; - - var mockSerializer = new Mock(); - mockSerializer - .Setup(o => o.Deserialize("valid-value")) - .Returns(expectedToken); - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: mockSerializer.Object); - - // Act - AntiForgeryToken retVal = tokenStore.GetCookieToken(mockHttpContext); - - // Assert - Assert.Same(expectedToken, retVal); - } - - [Fact] - public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull() - { - // Arrange - var mockHttpContext = new Mock(); - var requestContext = new Mock(); - var formCollection = new Mock(); - formCollection.Setup(f => f["form-field-name"]).Returns(string.Empty); - requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None)) - .Returns(Task.FromResult(formCollection.Object)); - mockHttpContext.Setup(o => o.Request) - .Returns(requestContext.Object); - var config = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: null); - - // Act - var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object); - - // Assert - Assert.Null(token); - } - - [Fact] - public async Task GetFormToken_FormFieldIsInvalid_PropagatesException() - { - // Arrange - var formCollection = new Mock(); - formCollection.Setup(f => f["form-field-name"]).Returns("invalid-value"); - - var requestContext = new Mock(); - requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None)) - .Returns(Task.FromResult(formCollection.Object)); - - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request) - .Returns(requestContext.Object); - - var config = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - var expectedException = new InvalidOperationException("some exception"); - var mockSerializer = new Mock(); - mockSerializer.Setup(o => o.Deserialize("invalid-value")) - .Throws(expectedException); - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: mockSerializer.Object); - - // Act & assert - var ex = - await - Assert.ThrowsAsync( - async () => await tokenStore.GetFormTokenAsync(mockHttpContext.Object)); - Assert.Same(expectedException, ex); - } - - [Fact] - public async Task GetFormToken_FormFieldIsValid_ReturnsToken() - { - // Arrange - var expectedToken = new AntiForgeryToken(); - - // Arrange - var mockHttpContext = new Mock(); - var requestContext = new Mock(); - var formCollection = new Mock(); - formCollection.Setup(f => f["form-field-name"]).Returns("valid-value"); - requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None)) - .Returns(Task.FromResult(formCollection.Object)); - mockHttpContext.Setup(o => o.Request) - .Returns(requestContext.Object); - - var config = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - var mockSerializer = new Mock(); - mockSerializer.Setup(o => o.Deserialize("valid-value")) - .Returns(expectedToken); - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: mockSerializer.Object); - - // Act - var retVal = await tokenStore.GetFormTokenAsync(mockHttpContext.Object); - - // Assert - Assert.Same(expectedToken, retVal); - } - - [Theory] - [InlineData(true, true)] - [InlineData(false, null)] - public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag) - { - // Arrange - var token = new AntiForgeryToken(); - var mockCookies = new Mock(); - - bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor - var cookies = new MockResponseCookieCollection(); - - cookies.Count = 0; - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Response.Cookies) - .Returns(cookies); - var contextAccessor = new ScopedInstance(); - mockHttpContext.SetupGet(o => o.RequestServices) - .Returns(GetServiceProvider(contextAccessor)); - - var mockSerializer = new Mock(); - mockSerializer.Setup(o => o.Serialize(token)) - .Returns("serialized-value"); - - var config = new AntiForgeryOptions() - { - CookieName = _cookieName, - RequireSSL = requireSsl - }; - - var tokenStore = new AntiForgeryTokenStore( - config: config, - serializer: mockSerializer.Object); - - // Act - tokenStore.SaveCookieToken(mockHttpContext.Object, token); - - // Assert - Assert.Equal(1, cookies.Count); - Assert.NotNull(contextAccessor.Value.CookieToken); - Assert.NotNull(cookies); - Assert.Equal(_cookieName, cookies.Key); - Assert.Equal("serialized-value", cookies.Value); - Assert.True(cookies.Options.HttpOnly); - Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure); - } - - private HttpContext GetMockHttpContext(string cookieName, string cookieValue) - { - var requestCookies = new MockCookieCollection(new Dictionary() { { cookieName, cookieValue } }); - - var request = new Mock(); - request.Setup(o => o.Cookies) - .Returns(requestCookies); - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request) - .Returns(request.Object); - - var contextAccessor = new ScopedInstance(); - mockHttpContext.SetupGet(o => o.RequestServices) - .Returns(GetServiceProvider(contextAccessor)); - - return mockHttpContext.Object; - } - - private static IServiceProvider GetServiceProvider(IScopedInstance contextAccessor) - { - var serviceCollection = new ServiceCollection(); - serviceCollection.AddInstance>(contextAccessor); - return serviceCollection.BuildServiceProvider(); - } - - private class MockResponseCookieCollection : IResponseCookies - { - public string Key { get; set; } - public string Value { get; set; } - public CookieOptions Options { get; set; } - public int Count { get; set; } - - public void Append(string key, string value, CookieOptions options) - { - this.Key = key; - this.Value = value; - this.Options = options; - this.Count++; - } - - public void Append(string key, string value) - { - throw new NotImplementedException(); - } - - public void Delete(string key, CookieOptions options) - { - throw new NotImplementedException(); - } - - public void Delete(string key) - { - throw new NotImplementedException(); - } - } - - private class MockCookieCollection : IReadableStringCollection - { - private Dictionary _dictionary; - - public int Count - { - get - { - return _dictionary.Count; - } - } - - public ICollection Keys - { - get - { - return _dictionary.Keys; - } - } - - public MockCookieCollection(Dictionary dictionary) - { - _dictionary = dictionary; - } - - public static MockCookieCollection GetDummyInstance(string key, string value) - { - return new MockCookieCollection(new Dictionary() { { key, value } }); - } - - public string Get(string key) - { - return this[key]; - } - - public IList GetValues(string key) - { - throw new NotImplementedException(); - } - - public bool ContainsKey(string key) - { - return _dictionary.ContainsKey(key); - } - - public string this[string key] - { - get { return _dictionary[key]; } - } - - public IEnumerator> GetEnumerator() - { - throw new NotImplementedException(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenTest.cs deleted file mode 100644 index 40024f4680..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryTokenTest.cs +++ /dev/null @@ -1,132 +0,0 @@ -// 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 Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class AntiForgeryTokenTest - { - [Fact] - public void AdditionalDataProperty() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act & assert - 1 - Assert.Equal("", token.AdditionalData); - - // Act & assert - 2 - token.AdditionalData = "additional data"; - Assert.Equal("additional data", token.AdditionalData); - - // Act & assert - 3 - token.AdditionalData = null; - Assert.Equal("", token.AdditionalData); - } - - [Fact] - public void ClaimUidProperty() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act & assert - 1 - Assert.Null(token.ClaimUid); - - // Act & assert - 2 - BinaryBlob blob = new BinaryBlob(32); - token.ClaimUid = blob; - Assert.Equal(blob, token.ClaimUid); - - // Act & assert - 3 - token.ClaimUid = null; - Assert.Null(token.ClaimUid); - } - - [Fact] - public void IsSessionTokenProperty() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act & assert - 1 - Assert.False(token.IsSessionToken); - - // Act & assert - 2 - token.IsSessionToken = true; - Assert.True(token.IsSessionToken); - - // Act & assert - 3 - token.IsSessionToken = false; - Assert.False(token.IsSessionToken); - } - - [Fact] - public void UsernameProperty() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act & assert - 1 - Assert.Equal("", token.Username); - - // Act & assert - 2 - token.Username = "my username"; - Assert.Equal("my username", token.Username); - - // Act & assert - 3 - token.Username = null; - Assert.Equal("", token.Username); - } - - [Fact] - public void SecurityTokenProperty_GetsAutopopulated() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act - var securityToken = token.SecurityToken; - - // Assert - Assert.NotNull(securityToken); - Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); - - // check that we're not making a new one each property call - Assert.Equal(securityToken, token.SecurityToken); - } - - [Fact] - public void SecurityTokenProperty_PropertySetter_DoesNotUseDefaults() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act - var securityToken = new BinaryBlob(64); - token.SecurityToken = securityToken; - - // Assert - Assert.Equal(securityToken, token.SecurityToken); - } - - [Fact] - public void SecurityTokenProperty_PropertySetter_DoesNotAllowNulls() - { - // Arrange - var token = new AntiForgeryToken(); - - // Act - token.SecurityToken = null; - var securityToken = token.SecurityToken; - - // Assert - Assert.NotNull(securityToken); - Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); - - // check that we're not making a new one each property call - Assert.Equal(securityToken, token.SecurityToken); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryWorkerTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryWorkerTest.cs deleted file mode 100644 index c3169d55ef..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/AntiForgeryWorkerTest.cs +++ /dev/null @@ -1,584 +0,0 @@ -// 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.Collections.Generic; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Internal; -using Microsoft.AspNet.Mvc.Rendering; -using Microsoft.Framework.WebEncoders.Testing; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class AntiForgeryWorkerTest - { - - [Fact] - public async Task ChecksSSL_ValidateAsync_Throws() - { - // Arrange - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request.IsHttps) - .Returns(false); - - var config = new AntiForgeryOptions() - { - RequireSSL = true - }; - - var worker = new AntiForgeryWorker( - config: config, - serializer: null, - tokenStore: null, - generator: null, - validator: null, - htmlEncoder: new CommonTestEncoder()); - - // Act & assert - var ex = - await - Assert.ThrowsAsync( - async () => await worker.ValidateAsync(mockHttpContext.Object)); - Assert.Equal( - @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - ex.Message); - } - - [Fact] - public void ChecksSSL_Validate_Throws() - { - // Arrange - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request.IsHttps) - .Returns(false); - - var config = new AntiForgeryOptions() - { - RequireSSL = true - }; - - var worker = new AntiForgeryWorker( - config: config, - serializer: null, - tokenStore: null, - generator: null, - validator: null, - htmlEncoder: new CommonTestEncoder()); - - // Act & assert - var ex = Assert.Throws( - () => worker.Validate(mockHttpContext.Object, cookieToken: null, formToken: null)); - Assert.Equal( - @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - ex.Message); - } - - [Fact] - public void ChecksSSL_GetFormInputElement_Throws() - { - // Arrange - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request.IsHttps) - .Returns(false); - - var config = new AntiForgeryOptions() - { - RequireSSL = true - }; - - var worker = new AntiForgeryWorker( - config: config, - serializer: null, - tokenStore: null, - generator: null, - validator: null, - htmlEncoder: new CommonTestEncoder()); - - // Act & assert - var ex = Assert.Throws(() => worker.GetFormInputElement(mockHttpContext.Object)); - Assert.Equal( - @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - ex.Message); - } - - [Fact] - public void ChecksSSL_GetTokens_Throws() - { - // Arrange - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.Request.IsHttps) - .Returns(false); - - var config = new AntiForgeryOptions() - { - RequireSSL = true - }; - - var worker = new AntiForgeryWorker( - config: config, - serializer: null, - tokenStore: null, - generator: null, - validator: null, - htmlEncoder: new CommonTestEncoder()); - - // Act & assert - var ex = Assert.Throws(() => - worker.GetTokens(mockHttpContext.Object, "cookie-token")); - Assert.Equal( - @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - ex.Message); - } - - [Fact] - public void GetFormInputElement_ExistingInvalidCookieToken_GeneratesANewCookieAndAnAntiForgeryToken() - { - // Arrange - var config = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - // Make sure the existing cookie is invalid. - var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false); - var worker = GetAntiForgeryWorker(context); - - // Act - var inputElement = worker.GetFormInputElement(context.HttpContext.Object); - - // Assert - Assert.Equal(@"", - inputElement.ToString(TagRenderMode.SelfClosing)); - context.TokenStore.Verify(); - } - - [Fact] - public void GetFormInputElement_ExistingInvalidCookieToken_SwallowsExceptions() - { - // Arrange - var config = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - // Make sure the existing cookie is invalid. - var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false); - var worker = GetAntiForgeryWorker(context); - - // This will cause the cookieToken to be null. - context.TokenStore.Setup(o => o.GetCookieToken(context.HttpContext.Object)) - .Throws(new Exception("should be swallowed")); - - // Setup so that the null cookie token returned is treated as invalid. - context.TokenProvider.Setup(o => o.IsCookieTokenValid(null)) - .Returns(false); - - // Act - var inputElement = worker.GetFormInputElement(context.HttpContext.Object); - - // Assert - Assert.Equal(@"", - inputElement.ToString(TagRenderMode.SelfClosing)); - context.TokenStore.Verify(); - } - - [Fact] - public void GetFormInputElement_ExistingValidCookieToken_GeneratesAnAntiForgeryToken() - { - // Arrange - var options = new AntiForgeryOptions() - { - FormFieldName = "form-field-name" - }; - - // Make sure the existing cookie is valid and use the same cookie for the mock Token Provider. - var context = GetAntiForgeryWorkerContext(options, useOldCookie: true, isOldCookieValid: true); - var worker = GetAntiForgeryWorker(context); - - // Act - var inputElement = worker.GetFormInputElement(context.HttpContext.Object); - - // Assert - Assert.Equal(@"", - inputElement.ToString(TagRenderMode.SelfClosing)); - } - - [Theory] - [InlineData(false, "SAMEORIGIN")] - [InlineData(true, null)] - public void GetFormInputElement_AddsXFrameOptionsHeader(bool suppressXFrameOptions, string expectedHeaderValue) - { - // Arrange - var options = new AntiForgeryOptions() - { - SuppressXFrameOptionsHeader = suppressXFrameOptions - }; - - // Genreate a new cookie. - var context = GetAntiForgeryWorkerContext(options, useOldCookie: false, isOldCookieValid: false); - var worker = GetAntiForgeryWorker(context); - - // Act - var inputElement = worker.GetFormInputElement(context.HttpContext.Object); - - // Assert - string xFrameOptions = context.HttpContext.Object.Response.Headers["X-Frame-Options"]; - Assert.Equal(expectedHeaderValue, xFrameOptions); - } - - [Fact] - public void GetTokens_ExistingInvalidCookieToken_GeneratesANewCookieTokenAndANewFormToken() - { - // Arrange - // Genreate a new cookie. - var context = GetAntiForgeryWorkerContext( - new AntiForgeryOptions(), - useOldCookie: false, - isOldCookieValid: false); - var worker = GetAntiForgeryWorker(context); - - // Act - var tokenset = worker.GetTokens(context.HttpContext.Object, "serialized-old-cookie-token"); - - // Assert - Assert.Equal("serialized-new-cookie-token", tokenset.CookieToken); - Assert.Equal("serialized-form-token", tokenset.FormToken); - } - - [Fact] - public void GetTokens_ExistingInvalidCookieToken_SwallowsExceptions() - { - // Arrange - // Make sure the existing cookie is invalid. - var context = GetAntiForgeryWorkerContext( - new AntiForgeryOptions(), - useOldCookie: false, - isOldCookieValid: false); - - // This will cause the cookieToken to be null. - context.TokenSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")) - .Throws(new Exception("should be swallowed")); - - // Setup so that the null cookie token returned is treated as invalid. - context.TokenProvider.Setup(o => o.IsCookieTokenValid(null)) - .Returns(false); - var worker = GetAntiForgeryWorker(context); - - // Act - var tokenset = worker.GetTokens(context.HttpContext.Object, "serialized-old-cookie-token"); - - // Assert - Assert.Equal("serialized-new-cookie-token", tokenset.CookieToken); - Assert.Equal("serialized-form-token", tokenset.FormToken); - } - - [Fact] - public void GetTokens_ExistingValidCookieToken_GeneratesANewFormToken() - { - // Arrange - var context = GetAntiForgeryWorkerContext( - new AntiForgeryOptions(), - useOldCookie: true, - isOldCookieValid: true); - context.TokenStore = null; - var worker = GetAntiForgeryWorker(context); - - // Act - var tokenset = worker.GetTokens(context.HttpContext.Object, "serialized-old-cookie-token"); - - // Assert - Assert.Null(tokenset.CookieToken); - Assert.Equal("serialized-form-token", tokenset.FormToken); - } - - [Fact] - public void Validate_FromInvalidStrings_Throws() - { - // Arrange - var context = GetAntiForgeryWorkerContext(new AntiForgeryOptions()); - - context.TokenSerializer.Setup(o => o.Deserialize("cookie-token")) - .Returns(context.TestTokenSet.OldCookieToken); - context.TokenSerializer.Setup(o => o.Deserialize("form-token")) - .Returns(context.TestTokenSet.FormToken); - - context.TokenProvider.Setup(o => o.ValidateTokens( - context.HttpContext.Object, - context.HttpContext.Object.User.Identity as ClaimsIdentity, - context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken)) - .Throws(new InvalidOperationException("my-message")); - context.TokenStore = null; - var worker = GetAntiForgeryWorker(context); - - // Act & assert - var ex = - Assert.Throws( - () => worker.Validate(context.HttpContext.Object, "cookie-token", "form-token")); - Assert.Equal("my-message", ex.Message); - } - - [Fact] - public void Validate_FromValidStrings_TokensValidatedSuccessfully() - { - // Arrange - var context = GetAntiForgeryWorkerContext(new AntiForgeryOptions()); - - context.TokenSerializer.Setup(o => o.Deserialize("cookie-token")) - .Returns(context.TestTokenSet.OldCookieToken); - context.TokenSerializer.Setup(o => o.Deserialize("form-token")) - .Returns(context.TestTokenSet.FormToken); - - context.TokenProvider.Setup(o => o.ValidateTokens( - context.HttpContext.Object, - context.HttpContext.Object.User.Identity as ClaimsIdentity, - context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken)) - .Verifiable(); - context.TokenStore = null; - var worker = GetAntiForgeryWorker(context); - - // Act - worker.Validate(context.HttpContext.Object, "cookie-token", "form-token"); - - // Assert - context.TokenProvider.Verify(); - } - - [Fact] - public async Task Validate_FromStore_Failure() - { - // Arrange - var context = GetAntiForgeryWorkerContext(new AntiForgeryOptions()); - - context.TokenProvider.Setup(o => o.ValidateTokens( - context.HttpContext.Object, - context.HttpContext.Object.User.Identity as ClaimsIdentity, - context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken)) - .Throws(new InvalidOperationException("my-message")); - context.TokenSerializer = null; - var worker = GetAntiForgeryWorker(context); - - // Act & assert - var ex = - await - Assert.ThrowsAsync( - async () => await worker.ValidateAsync(context.HttpContext.Object)); - Assert.Equal("my-message", ex.Message); - } - - [Fact] - public async Task Validate_FromStore_Success() - { - // Arrange - var context = GetAntiForgeryWorkerContext(new AntiForgeryOptions()); - - context.TokenProvider.Setup(o => o.ValidateTokens( - context.HttpContext.Object, - context.HttpContext.Object.User.Identity as ClaimsIdentity, - context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken)) - .Verifiable(); - context.TokenSerializer = null; - var worker = GetAntiForgeryWorker(context); - - // Act - await worker.ValidateAsync(context.HttpContext.Object); - - // Assert - context.TokenProvider.Verify(); - } - - [Theory] - [InlineData(false, "SAMEORIGIN")] - [InlineData(true, null)] - public void SetCookieTokenAndHeader_AddsXFrameOptionsHeader( - bool suppressXFrameOptions, - string expectedHeaderValue) - { - // Arrange - var options = new AntiForgeryOptions() - { - SuppressXFrameOptionsHeader = suppressXFrameOptions - }; - - // Genreate a new cookie. - var context = GetAntiForgeryWorkerContext(options, useOldCookie: false, isOldCookieValid: false); - var worker = GetAntiForgeryWorker(context); - - // Act - worker.SetCookieTokenAndHeader(context.HttpContext.Object); - - // Assert - var xFrameOptions = context.HttpContext.Object.Response.Headers["X-Frame-Options"]; - Assert.Equal(expectedHeaderValue, xFrameOptions); - } - - private AntiForgeryWorker GetAntiForgeryWorker(AntiForgeryWorkerContext context) - { - return new AntiForgeryWorker( - config: context.Options, - serializer: context.TokenSerializer != null ? context.TokenSerializer.Object : null, - tokenStore: context.TokenStore != null ? context.TokenStore.Object : null, - generator: context.TokenProvider != null ? context.TokenProvider.Object : null, - validator: context.TokenProvider != null ? context.TokenProvider.Object : null, - htmlEncoder: new CommonTestEncoder()); - } - - private Mock GetHttpContext(bool setupResponse = true) - { - var identity = new ClaimsIdentity("some-auth"); - var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.User) - .Returns(new ClaimsPrincipal(identity)); - - if (setupResponse) - { - var mockResponse = new Mock(); - mockResponse.Setup(r => r.Headers) - .Returns(new HeaderDictionary(new Dictionary())); - mockHttpContext.Setup(o => o.Response) - .Returns(mockResponse.Object); - } - - return mockHttpContext; - } - - private Mock GetTokenProvider( - HttpContext context, - TestTokenSet testTokenSet, - bool useOldCookie, - bool isOldCookieValid = true, - bool isNewCookieValid = true) - { - var oldCookieToken = testTokenSet.OldCookieToken; - var newCookieToken = testTokenSet.NewCookieToken; - var formToken = testTokenSet.FormToken; - var mockValidator = new Mock(MockBehavior.Strict); - mockValidator.Setup(o => o.GenerateFormToken( - context, - context.User.Identity as ClaimsIdentity, - useOldCookie ? oldCookieToken : newCookieToken)) - .Returns(formToken); - mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)) - .Returns(isOldCookieValid); - mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)) - .Returns(isNewCookieValid); - - mockValidator.Setup(o => o.GenerateCookieToken()) - .Returns(useOldCookie ? oldCookieToken : newCookieToken); - - return mockValidator; - } - - private Mock GetTokenStore( - HttpContext context, - TestTokenSet testTokenSet, - bool saveNewCookie = true) - { - var oldCookieToken = testTokenSet.OldCookieToken; - var formToken = testTokenSet.FormToken; - var mockTokenStore = new Mock(MockBehavior.Strict); - mockTokenStore.Setup(o => o.GetCookieToken(context)) - .Returns(oldCookieToken); - mockTokenStore.Setup(o => o.GetFormTokenAsync(context)) - .Returns(Task.FromResult(formToken)); - - if (saveNewCookie) - { - var newCookieToken = testTokenSet.NewCookieToken; - mockTokenStore.Setup(o => o.SaveCookieToken(context, newCookieToken)) - .Verifiable(); - } - - return mockTokenStore; - } - - private Mock GetTokenSerializer(TestTokenSet testTokenSet) - { - var oldCookieToken = testTokenSet.OldCookieToken; - var newCookieToken = testTokenSet.NewCookieToken; - var formToken = testTokenSet.FormToken; - var mockSerializer = new Mock(MockBehavior.Strict); - mockSerializer.Setup(o => o.Serialize(formToken)) - .Returns("serialized-form-token"); - mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")) - .Returns(oldCookieToken); - mockSerializer.Setup(o => o.Serialize(newCookieToken)) - .Returns("serialized-new-cookie-token"); - return mockSerializer; - } - - private TestTokenSet GetTokenSet(bool isOldCookieTokenSessionToken = true, bool isNewCookieSessionToken = true) - { - return new TestTokenSet() - { - FormToken = new AntiForgeryToken() { IsSessionToken = false }, - OldCookieToken = new AntiForgeryToken() { IsSessionToken = isOldCookieTokenSessionToken }, - NewCookieToken = new AntiForgeryToken() { IsSessionToken = isNewCookieSessionToken }, - }; - } - - private AntiForgeryWorkerContext GetAntiForgeryWorkerContext( - AntiForgeryOptions config, - bool useOldCookie = false, - bool isOldCookieValid = true) - { - // Arrange - var mockHttpContext = GetHttpContext(); - var testTokenSet = GetTokenSet(isOldCookieTokenSessionToken: true, isNewCookieSessionToken: true); - - var mockSerializer = GetTokenSerializer(testTokenSet); - - var mockTokenStore = GetTokenStore(mockHttpContext.Object, testTokenSet); - var mockTokenProvider = GetTokenProvider( - mockHttpContext.Object, - testTokenSet, - useOldCookie: useOldCookie, - isOldCookieValid: isOldCookieValid); - - return new AntiForgeryWorkerContext() - { - Options = config, - HttpContext = mockHttpContext, - TokenProvider = mockTokenProvider, - TokenSerializer = mockSerializer, - TokenStore = mockTokenStore, - TestTokenSet = testTokenSet - }; - } - - private class TestTokenSet - { - public AntiForgeryToken FormToken { get; set; } - public string FormTokenString { get; set; } - public AntiForgeryToken OldCookieToken { get; set; } - public string OldCookieTokenString { get; set; } - public AntiForgeryToken NewCookieToken { get; set; } - public string NewCookieTokenString { get; set; } - } - - private class AntiForgeryWorkerContext - { - public AntiForgeryOptions Options { get; set; } - - public TestTokenSet TestTokenSet { get; set; } - - public Mock HttpContext { get; set; } - - public Mock TokenProvider { get; set; } - - public Mock TokenStore { get; set; } - - public Mock TokenSerializer { get; set; } - } - } -} diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/BinaryBlobTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/BinaryBlobTest.cs deleted file mode 100644 index 8681ac6a64..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/BinaryBlobTest.cs +++ /dev/null @@ -1,129 +0,0 @@ -// 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 Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class BinaryBlobTest - { - [Fact] - public void Ctor_BitLength() - { - // Act - var blob = new BinaryBlob(bitLength: 64); - var data = blob.GetData(); - - // Assert - Assert.Equal(64, blob.BitLength); - Assert.Equal(64 / 8, data.Length); - Assert.NotEqual(new byte[64 / 8], data); // should not be a zero-filled array - } - - [Theory] - [InlineData(24)] - [InlineData(33)] - public void Ctor_BitLength_Bad(int bitLength) - { - // Act & assert - var ex = Assert.Throws(() => new BinaryBlob(bitLength)); - Assert.Equal("bitLength", ex.ParamName); - } - - [Fact] - public void Ctor_BitLength_ProducesDifferentValues() - { - // Act - var blobA = new BinaryBlob(bitLength: 64); - var blobB = new BinaryBlob(bitLength: 64); - - // Assert - Assert.NotEqual(blobA.GetData(), blobB.GetData()); - } - - [Fact] - public void Ctor_Data() - { - // Arrange - var expectedData = new byte[] { 0x01, 0x02, 0x03, 0x04 }; - - // Act - var blob = new BinaryBlob(32, expectedData); - - // Assert - Assert.Equal(32, blob.BitLength); - Assert.Equal(expectedData, blob.GetData()); - } - - [Theory] - [InlineData((object[])null)] - [InlineData(new byte[] { 0x01, 0x02, 0x03 })] - public void Ctor_Data_Bad(byte[] data) - { - // Act & assert - var ex = Assert.Throws(() => new BinaryBlob(32, data)); - Assert.Equal("data", ex.ParamName); - } - - [Fact] - public void Equals_DifferentData_ReturnsFalse() - { - // Arrange - object blobA = new BinaryBlob(32, new byte[] { 0x01, 0x02, 0x03, 0x04 }); - object blobB = new BinaryBlob(32, new byte[] { 0x04, 0x03, 0x02, 0x01 }); - - // Act & assert - Assert.NotEqual(blobA, blobB); - } - - [Fact] - public void Equals_NotABlob_ReturnsFalse() - { - // Arrange - object blobA = new BinaryBlob(32); - object blobB = "hello"; - - // Act & assert - Assert.NotEqual(blobA, blobB); - } - - [Fact] - public void Equals_Null_ReturnsFalse() - { - // Arrange - object blobA = new BinaryBlob(32); - object blobB = null; - - // Act & assert - Assert.NotEqual(blobA, blobB); - } - - [Fact] - public void Equals_SameData_ReturnsTrue() - { - // Arrange - object blobA = new BinaryBlob(32, new byte[] { 0x01, 0x02, 0x03, 0x04 }); - object blobB = new BinaryBlob(32, new byte[] { 0x01, 0x02, 0x03, 0x04 }); - - // Act & assert - Assert.Equal(blobA, blobB); - } - - [Fact] - public void GetHashCodeTest() - { - // Arrange - var blobData = new byte[] { 0x01, 0x02, 0x03, 0x04 }; - var expectedHashCode = BitConverter.ToInt32(blobData, 0); - - var blob = new BinaryBlob(32, blobData); - - // Act - var actualHashCode = blob.GetHashCode(); - - // Assert - Assert.Equal(expectedHashCode, actualHashCode); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ClaimUidExtractorTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ClaimUidExtractorTest.cs deleted file mode 100644 index d100a246e5..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ClaimUidExtractorTest.cs +++ /dev/null @@ -1,108 +0,0 @@ -// 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.Linq; -using System.Security.Claims; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class ClaimUidExtractorTest - { - [Fact] - public void ExtractClaimUid_NullIdentity() - { - // Arrange - IClaimUidExtractor extractor = new DefaultClaimUidExtractor(); - - // Act - var claimUid = extractor.ExtractClaimUid(null); - - // Assert - Assert.Null(claimUid); - } - - [Fact] - public void ExtractClaimUid_Unauthenticated() - { - // Arrange - IClaimUidExtractor extractor = new DefaultClaimUidExtractor(); - - var mockIdentity = new Mock(); - mockIdentity.Setup(o => o.IsAuthenticated) - .Returns(false); - - // Act - var claimUid = extractor.ExtractClaimUid(mockIdentity.Object); - - // Assert - Assert.Null(claimUid); - } - - [Fact] - public void ExtractClaimUid_ClaimsIdentity() - { - // Arrange - var mockIdentity = new Mock(); - mockIdentity.Setup(o => o.IsAuthenticated) - .Returns(true); - - IClaimUidExtractor extractor = new DefaultClaimUidExtractor(); - - // Act - var claimUid = extractor.ExtractClaimUid(mockIdentity.Object); - - // Assert - Assert.NotNull(claimUid); - Assert.Equal("47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", claimUid); - } - - [Fact] - public void DefaultUniqueClaimTypes_NotPresent_SerializesAllClaimTypes() - { - var identity = new ClaimsIdentity(); - identity.AddClaim(new Claim(ClaimTypes.Email, "someone@antifrogery.com")); - identity.AddClaim(new Claim(ClaimTypes.GivenName, "some")); - identity.AddClaim(new Claim(ClaimTypes.Surname, "one")); - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, String.Empty)); - - // Arrange - var claimsIdentity = (ClaimsIdentity)identity; - - // Act - var identiferParameters = DefaultClaimUidExtractor.GetUniqueIdentifierParameters(claimsIdentity) - .ToArray(); - var claims = claimsIdentity.Claims.ToList(); - claims.Sort((a, b) => string.Compare(a.Type, b.Type, StringComparison.Ordinal)); - - // Assert - int index = 0; - foreach (var claim in claims) - { - Assert.True(String.Equals(identiferParameters[index++], claim.Type, StringComparison.Ordinal)); - Assert.True(String.Equals(identiferParameters[index++], claim.Value, StringComparison.Ordinal)); - } - } - - [Fact] - public void DefaultUniqueClaimTypes_Present() - { - // Arrange - var identity = new ClaimsIdentity(); - identity.AddClaim(new Claim("fooClaim", "fooClaimValue")); - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "nameIdentifierValue")); - - // Act - var uniqueIdentifierParameters = DefaultClaimUidExtractor.GetUniqueIdentifierParameters(identity); - - // Assert - Assert.Equal(new string[] - { - ClaimTypes.NameIdentifier, - "nameIdentifierValue", - }, uniqueIdentifierParameters); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/IAntiForgeryTokenProvider.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/IAntiForgeryTokenProvider.cs deleted file mode 100644 index a3584337b5..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/IAntiForgeryTokenProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - // A TokenProvider that can be passed to MoQ - internal interface IAntiForgeryTokenProvider : IAntiForgeryTokenValidator, IAntiForgeryTokenGenerator - { - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/TokenProviderTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/TokenProviderTest.cs deleted file mode 100644 index 6f430ba06e..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/TokenProviderTest.cs +++ /dev/null @@ -1,582 +0,0 @@ -// 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.Security.Claims; -using System.Security.Cryptography; -using Microsoft.AspNet.Http; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class TokenProviderTest - { - [Fact] - public void GenerateCookieToken() - { - // Arrange - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act - var retVal = tokenProvider.GenerateCookieToken(); - - // Assert - Assert.NotNull(retVal); - } - - [Fact] - public void GenerateFormToken_AnonymousUser() - { - // Arrange - var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; - var httpContext = new Mock().Object; - var mockIdentity = new Mock(); - mockIdentity.Setup(o => o.IsAuthenticated) - .Returns(false); - - var config = new AntiForgeryOptions(); - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act - var fieldToken = tokenProvider.GenerateFormToken(httpContext, mockIdentity.Object, cookieToken); - - // Assert - Assert.NotNull(fieldToken); - Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); - Assert.False(fieldToken.IsSessionToken); - Assert.Empty(fieldToken.Username); - Assert.Null(fieldToken.ClaimUid); - Assert.Empty(fieldToken.AdditionalData); - } - - [Fact] - public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData() - { - // Arrange - var cookieToken = new AntiForgeryToken() - { - IsSessionToken = true - }; - - var httpContext = new Mock().Object; - ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername(); - var config = new AntiForgeryOptions(); - IClaimUidExtractor claimUidExtractor = new Mock().Object; - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: claimUidExtractor, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.GenerateFormToken(httpContext, identity, cookieToken)); - Assert.Equal( - "The provided identity of type " + - "'Microsoft.AspNet.Mvc.Core.Test.TokenProviderTest+MyAuthenticatedIdentityWithoutUsername' " + - "is marked IsAuthenticated = true but does not have a value for Name. " + - "By default, the anti-forgery system requires that all authenticated identities have a unique Name. " + - "If it is not possible to provide a unique Name for this identity, " + - "consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider " + - "or a custom type that can provide some form of unique identifier for the current user.", - ex.Message); - } - - [Fact] - public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData() - { - // Arrange - var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; - var httpContext = new Mock().Object; - ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername(); - - var mockAdditionalDataProvider = new Mock(); - mockAdditionalDataProvider.Setup(o => o.GetAdditionalData(httpContext)) - .Returns("additional-data"); - - var config = new AntiForgeryOptions(); - IClaimUidExtractor claimUidExtractor = new Mock().Object; - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: claimUidExtractor, - additionalDataProvider: mockAdditionalDataProvider.Object); - - // Act - var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken); - - // Assert - Assert.NotNull(fieldToken); - Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); - Assert.False(fieldToken.IsSessionToken); - Assert.Empty(fieldToken.Username); - Assert.Null(fieldToken.ClaimUid); - Assert.Equal("additional-data", fieldToken.AdditionalData); - } - - [Fact] - public void GenerateFormToken_ClaimsBasedIdentity() - { - // Arrange - var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; - var httpContext = new Mock().Object; - var identity = GetAuthenticatedIdentity("some-identity"); - - var config = new AntiForgeryOptions(); - - byte[] data = new byte[256 / 8]; - using (var rng = RandomNumberGenerator.Create()) - { - rng.GetBytes(data); - } - var base64ClaimUId = Convert.ToBase64String(data); - var expectedClaimUid = new BinaryBlob(256, data); - - var mockClaimUidExtractor = new Mock(); - mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) - .Returns(base64ClaimUId); - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: mockClaimUidExtractor.Object, - additionalDataProvider: null); - - // Act - var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken); - - // Assert - Assert.NotNull(fieldToken); - Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); - Assert.False(fieldToken.IsSessionToken); - Assert.Equal("", fieldToken.Username); - Assert.Equal(expectedClaimUid, fieldToken.ClaimUid); - Assert.Equal("", fieldToken.AdditionalData); - } - - [Fact] - public void GenerateFormToken_RegularUserWithUsername() - { - // Arrange - var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; - - var httpContext = new Mock().Object; - var mockIdentity = new Mock(); - mockIdentity.Setup(o => o.IsAuthenticated) - .Returns(true); - mockIdentity.Setup(o => o.Name) - .Returns("my-username"); - - var config = new AntiForgeryOptions(); - IClaimUidExtractor claimUidExtractor = new Mock().Object; - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: claimUidExtractor, - additionalDataProvider: null); - - // Act - var fieldToken = tokenProvider.GenerateFormToken(httpContext, mockIdentity.Object, cookieToken); - - // Assert - Assert.NotNull(fieldToken); - Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); - Assert.False(fieldToken.IsSessionToken); - Assert.Equal("my-username", fieldToken.Username); - Assert.Null(fieldToken.ClaimUid); - Assert.Empty(fieldToken.AdditionalData); - } - - [Fact] - public void IsCookieTokenValid_FieldToken_ReturnsFalse() - { - // Arrange - var cookieToken = new AntiForgeryToken() - { - IsSessionToken = false - }; - - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act - bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); - - // Assert - Assert.False(retVal); - } - - [Fact] - public void IsCookieTokenValid_NullToken_ReturnsFalse() - { - // Arrange - AntiForgeryToken cookieToken = null; - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act - bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); - - // Assert - Assert.False(retVal); - } - - [Fact] - public void IsCookieTokenValid_ValidToken_ReturnsTrue() - { - // Arrange - var cookieToken = new AntiForgeryToken() - { - IsSessionToken = true - }; - - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act - bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); - - // Assert - Assert.True(retVal); - } - - [Fact] - public void ValidateTokens_SessionTokenMissing() - { - // Arrange - var httpContext = new Mock().Object; - ClaimsIdentity identity = new Mock().Object; - AntiForgeryToken sessionToken = null; - var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; - - var config = new AntiForgeryOptions() - { - CookieName = "my-cookie-name" - }; - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal(@"The required anti-forgery cookie ""my-cookie-name"" is not present.", ex.Message); - } - - [Fact] - public void ValidateTokens_FieldTokenMissing() - { - // Arrange - var httpContext = new Mock().Object; - ClaimsIdentity identity = new Mock().Object; - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - AntiForgeryToken fieldtoken = null; - - var config = new AntiForgeryOptions() - { - FormFieldName = "my-form-field-name" - }; - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal(@"The required anti-forgery form field ""my-form-field-name"" is not present.", ex.Message); - } - - [Fact] - public void ValidateTokens_FieldAndSessionTokensSwapped() - { - // Arrange - var httpContext = new Mock().Object; - ClaimsIdentity identity = new Mock().Object; - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; - - var config = new AntiForgeryOptions() - { - CookieName = "my-cookie-name", - FormFieldName = "my-form-field-name" - }; - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act & assert - var ex1 = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, fieldtoken, fieldtoken)); - Assert.Equal( - "Validation of the provided anti-forgery token failed. " + - @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", - ex1.Message); - - var ex2 = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, sessionToken)); - Assert.Equal( - "Validation of the provided anti-forgery token failed. " + - @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", - ex2.Message); - } - - [Fact] - public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys() - { - // Arrange - var httpContext = new Mock().Object; - ClaimsIdentity identity = new Mock().Object; - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; - - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: null, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal(@"The anti-forgery cookie token and form field token do not match.", ex.Message); - } - - [Theory] - [InlineData("the-user", "the-other-user")] - [InlineData("http://example.com/uri-casing", "http://example.com/URI-casing")] - [InlineData("https://example.com/secure-uri-casing", "https://example.com/secure-URI-casing")] - public void ValidateTokens_UsernameMismatch(string identityUsername, string embeddedUsername) - { - // Arrange - var httpContext = new Mock().Object; - var identity = GetAuthenticatedIdentity(identityUsername); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - Username = embeddedUsername, - IsSessionToken = false - }; - - var mockClaimUidExtractor = new Mock(); - mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) - .Returns((string)null); - - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: mockClaimUidExtractor.Object, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal( - @"The provided anti-forgery token was meant for user """ + embeddedUsername + - @""", but the current user is """ + identityUsername + @""".", ex.Message); - } - - [Fact] - public void ValidateTokens_ClaimUidMismatch() - { - // Arrange - var httpContext = new Mock().Object; - var identity = GetAuthenticatedIdentity("the-user"); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - IsSessionToken = false, - ClaimUid = new BinaryBlob(256) - }; - - var differentToken = new BinaryBlob(256); - var mockClaimUidExtractor = new Mock(); - mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) - .Returns(Convert.ToBase64String(differentToken.GetData())); - - var tokenProvider = new AntiForgeryTokenProvider( - config: null, - claimUidExtractor: mockClaimUidExtractor.Object, - additionalDataProvider: null); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal( - @"The provided anti-forgery token was meant for a different claims-based user than the current user.", - ex.Message); - } - - [Fact] - public void ValidateTokens_AdditionalDataRejected() - { - // Arrange - var httpContext = new Mock().Object; - var identity = new ClaimsIdentity(); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - Username = String.Empty, - IsSessionToken = false, - AdditionalData = "some-additional-data" - }; - - var mockAdditionalDataProvider = new Mock(); - mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data")) - .Returns(false); - - var config = new AntiForgeryOptions(); - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: mockAdditionalDataProvider.Object); - - // Act & assert - var ex = - Assert.Throws( - () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); - Assert.Equal(@"The provided anti-forgery token failed a custom data check.", ex.Message); - } - - [Fact] - public void ValidateTokens_Success_AnonymousUser() - { - // Arrange - var httpContext = new Mock().Object; - var identity = new ClaimsIdentity(); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - Username = String.Empty, - IsSessionToken = false, - AdditionalData = "some-additional-data" - }; - - var mockAdditionalDataProvider = new Mock(); - mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data")) - .Returns(true); - - var config = new AntiForgeryOptions(); - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: null, - additionalDataProvider: mockAdditionalDataProvider.Object); - - // Act - tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken); - - // Assert - // Nothing to assert - if we got this far, success! - } - - [Fact] - public void ValidateTokens_Success_AuthenticatedUserWithUsername() - { - // Arrange - var httpContext = new Mock().Object; - var identity = GetAuthenticatedIdentity("the-user"); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - Username = "THE-USER", - IsSessionToken = false, - AdditionalData = "some-additional-data" - }; - - var mockAdditionalDataProvider = new Mock(); - mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data")) - .Returns(true); - - var config = new AntiForgeryOptions(); - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: new Mock().Object, - additionalDataProvider: mockAdditionalDataProvider.Object); - - // Act - tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken); - - // Assert - // Nothing to assert - if we got this far, success! - } - - [Fact] - public void ValidateTokens_Success_ClaimsBasedUser() - { - // Arrange - var httpContext = new Mock().Object; - var identity = GetAuthenticatedIdentity("the-user"); - var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; - var fieldtoken = new AntiForgeryToken() - { - SecurityToken = sessionToken.SecurityToken, - IsSessionToken = false, - ClaimUid = new BinaryBlob(256) - }; - - var mockClaimUidExtractor = new Mock(); - mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) - .Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData())); - - var config = new AntiForgeryOptions(); - - var tokenProvider = new AntiForgeryTokenProvider( - config: config, - claimUidExtractor: mockClaimUidExtractor.Object, - additionalDataProvider: null); - - // Act - tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken); - - // Assert - // Nothing to assert - if we got this far, success! - } - - private static ClaimsIdentity GetAuthenticatedIdentity(string identityUsername) - { - var claim = new Claim(ClaimsIdentity.DefaultNameClaimType, identityUsername); - return new ClaimsIdentity(new[] { claim }, "Some-Authentication"); - } - - private sealed class MyAuthenticatedIdentityWithoutUsername : ClaimsIdentity - { - public override bool IsAuthenticated - { - get { return true; } - } - - public override string Name - { - get { return String.Empty; } - } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ValidateAntiForgeryTokenAttributeTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ValidateAntiForgeryTokenAttributeTest.cs deleted file mode 100644 index e6295bb812..0000000000 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/AntiXsrf/ValidateAntiForgeryTokenAttributeTest.cs +++ /dev/null @@ -1,51 +0,0 @@ -// 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.AspNet.DataProtection; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; -using Microsoft.Framework.WebEncoders.Testing; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - public class ValidateAntiForgeryTokenAttributeTest - { - [Fact] - public void ValidationAttribute_ForwardsCallToValidateAntiForgeryTokenAuthorizationFilter() - { - // Arrange - var serviceCollection = new ServiceCollection(); - serviceCollection.AddInstance(GetAntiForgeryInstance()); - var serviceProvider = serviceCollection.BuildServiceProvider(); - var attribute = new ValidateAntiForgeryTokenAttribute(); - - // Act - var filter = attribute.CreateInstance(serviceProvider); - - // Assert - var validationFilter = filter as ValidateAntiForgeryTokenAuthorizationFilter; - Assert.NotNull(validationFilter); - } - - private AntiForgery GetAntiForgeryInstance() - { - var claimExtractor = new Mock(); - var dataProtectionProvider = new Mock(); - var additionalDataProvider = new Mock(); - var optionsAccessor = new Mock>(); - var mockDataProtectionOptions = new Mock>(); - mockDataProtectionOptions - .SetupGet(options => options.Options) - .Returns(Mock.Of()); - optionsAccessor.SetupGet(o => o.Options).Returns(new AntiForgeryOptions()); - return new AntiForgery(claimExtractor.Object, - dataProtectionProvider.Object, - additionalDataProvider.Object, - optionsAccessor.Object, - new CommonTestEncoder(), - mockDataProtectionOptions.Object); - } - } -} diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultHtmlGeneratorTest.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultHtmlGeneratorTest.cs index 06f70bb54a..78f594f828 100644 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultHtmlGeneratorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultHtmlGeneratorTest.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using Microsoft.AspNet.Antiforgery; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.Framework.OptionsModel; @@ -544,20 +545,10 @@ namespace Microsoft.AspNet.Mvc.Rendering // GetCurrentValues uses only the IModelMetadataProvider passed to the DefaultHtmlGenerator constructor. private static IHtmlGenerator GetGenerator(IModelMetadataProvider metadataProvider) { - var antiforgeryOptionsAccessor = new Mock>(); - antiforgeryOptionsAccessor.SetupGet(accessor => accessor.Options).Returns(new AntiForgeryOptions()); var mvcViewOptionsAccessor = new Mock>(); mvcViewOptionsAccessor.SetupGet(accessor => accessor.Options).Returns(new MvcViewOptions()); var htmlEncoder = Mock.Of(); - var dataOptionsAccessor = new Mock>(); - dataOptionsAccessor.SetupGet(accessor => accessor.Options).Returns(new DataProtectionOptions()); - var antiForgery = new AntiForgery( - Mock.Of(), - Mock.Of(), - Mock.Of(), - antiforgeryOptionsAccessor.Object, - htmlEncoder, - dataOptionsAccessor.Object); + var antiforgery = Mock.Of(); var optionsAccessor = new Mock>(); optionsAccessor @@ -565,7 +556,7 @@ namespace Microsoft.AspNet.Mvc.Rendering .Returns(new MvcOptions()); return new DefaultHtmlGenerator( - antiForgery, + antiforgery, mvcViewOptionsAccessor.Object, metadataProvider, Mock.Of(), diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultTemplatesUtilities.cs index abefe9b8d5..847894f8a1 100644 --- a/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.Extensions.Test/Rendering/DefaultTemplatesUtilities.cs @@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations; using System.Globalization; using System.IO; using System.Threading.Tasks; +using Microsoft.AspNet.Antiforgery; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.ModelBinding; @@ -236,7 +237,7 @@ namespace Microsoft.AspNet.Mvc.Rendering if (htmlGenerator == null) { htmlGenerator = new DefaultHtmlGenerator( - GetAntiForgeryInstance(), + Mock.Of(), optionsAccessor.Object, provider, urlHelper, @@ -307,26 +308,6 @@ namespace Microsoft.AspNet.Mvc.Rendering return viewEngine.Object; } - private static AntiForgery GetAntiForgeryInstance() - { - var claimExtractor = new Mock(); - var dataProtectionProvider = new Mock(); - var additionalDataProvider = new Mock(); - var optionsAccessor = new Mock>(); - var mockDataProtectionOptions = new Mock>(); - mockDataProtectionOptions - .SetupGet(options => options.Options) - .Returns(Mock.Of()); - optionsAccessor.SetupGet(o => o.Options).Returns(new AntiForgeryOptions()); - return new AntiForgery( - claimExtractor.Object, - dataProtectionProvider.Object, - additionalDataProvider.Object, - optionsAccessor.Object, - new CommonTestEncoder(), - mockDataProtectionOptions.Object); - } - private static string FormatOutput(ModelExplorer modelExplorer) { var metadata = modelExplorer.Metadata; diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTestHelper.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTestHelper.cs similarity index 90% rename from test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTestHelper.cs rename to test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTestHelper.cs index fe1a868b7d..1e50ef4514 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTestHelper.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTestHelper.cs @@ -10,18 +10,18 @@ using System.Xml.Linq; namespace Microsoft.AspNet.Mvc.FunctionalTests { - public static class AntiForgeryTestHelper + public static class AntiforgeryTestHelper { - public static string RetrieveAntiForgeryToken(string htmlContent, string actionUrl) + public static string RetrieveAntiforgeryToken(string htmlContent, string actionUrl) { - return RetrieveAntiForgeryTokens( + return RetrieveAntiforgeryTokens( htmlContent, attribute => attribute.Value.EndsWith(actionUrl, StringComparison.OrdinalIgnoreCase) || attribute.Value.EndsWith($"HtmlEncode[[{ actionUrl }]]", StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); } - public static IEnumerable RetrieveAntiForgeryTokens( + public static IEnumerable RetrieveAntiforgeryTokens( string htmlContent, Func predicate = null) { @@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests } } - public static CookieMetadata RetrieveAntiForgeryCookie(HttpResponseMessage response) + public static CookieMetadata RetrieveAntiforgeryCookie(HttpResponseMessage response) { var setCookieArray = response.Headers.GetValues("Set-Cookie").ToArray(); var cookie = setCookieArray[0].Split(';').First().Split('='); diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTests.cs similarity index 81% rename from test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTests.cs rename to test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTests.cs index 382c9cdd58..e3bad7b019 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiForgeryTests.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/AntiforgeryTests.cs @@ -13,11 +13,11 @@ using Xunit; namespace Microsoft.AspNet.Mvc.FunctionalTests { - public class AntiForgeryTests + public class AntiforgeryTests { - private const string SiteName = nameof(AntiForgeryWebSite); - private readonly Action _app = new AntiForgeryWebSite.Startup().Configure; - private readonly Action _configureServices = new AntiForgeryWebSite.Startup().ConfigureServices; + private const string SiteName = nameof(AntiforgeryTokenWebSite); + private readonly Action _app = new AntiforgeryTokenWebSite.Startup().Configure; + private readonly Action _configureServices = new AntiforgeryTokenWebSite.Startup().ConfigureServices; [Fact] public async Task MultipleAFTokensWithinTheSamePage_GeneratesASingleCookieToken() @@ -50,12 +50,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // do a get response. var getResponse = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); + var responseBody = await getResponse.Content.ReadAsStringAsync(); // Get the AF token for the second login. If the cookies are generated twice(i.e are different), // this AF token will not work with the first cookie. - var formToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(resposneBody, "Account/UseFacebookLogin"); - var cookieToken = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse); + var formToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseBody, "Account/UseFacebookLogin"); + var cookieToken = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); request.Headers.Add("Cookie", cookieToken.Key + "=" + cookieToken.Value); @@ -84,10 +84,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var client = server.CreateClient(); var getResponse = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); - var formToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(resposneBody, "Account/Login"); + var responseBody = await getResponse.Content.ReadAsStringAsync(); + var formToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseBody, "Account/Login"); - var cookieToken = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse); + var cookieToken = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); request.Headers.Add("Cookie", cookieToken.Key + "=invalidCookie"); @@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // Assert var exception = response.GetServerException(); - Assert.Equal("The anti-forgery token could not be decrypted.", exception.ExceptionMessage); + Assert.Equal("The antiforgery token could not be decrypted.", exception.ExceptionMessage); } [Fact] @@ -116,8 +116,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var client = server.CreateClient(); var getResponse = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); - var cookieToken = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse); + var responseBody = await getResponse.Content.ReadAsStringAsync(); + var cookieToken = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); var formToken = "adsad"; request.Headers.Add("Cookie", cookieToken.Key + "=" + cookieToken.Value); @@ -135,7 +135,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // Assert var exception = response.GetServerException(); - Assert.Equal("The anti-forgery token could not be decrypted.", exception.ExceptionMessage); + Assert.Equal("The antiforgery token could not be decrypted.", exception.ExceptionMessage); } [Fact] @@ -146,14 +146,14 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var client = server.CreateClient(); // do a get response. - // We do two requests to get two different sets of anti forgery cookie and token values. + // We do two requests to get two different sets of antiforgery cookie and token values. var getResponse1 = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody1 = await getResponse1.Content.ReadAsStringAsync(); - var formToken1 = AntiForgeryTestHelper.RetrieveAntiForgeryToken(resposneBody1, "Account/Login"); + var responseBody1 = await getResponse1.Content.ReadAsStringAsync(); + var formToken1 = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseBody1, "Account/Login"); var getResponse2 = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody2 = await getResponse2.Content.ReadAsStringAsync(); - var cookieToken2 = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse2); + var responseBody2 = await getResponse2.Content.ReadAsStringAsync(); + var cookieToken2 = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse2); var cookieToken = cookieToken2.Value; var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); @@ -173,7 +173,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // Assert var exception = response.GetServerException(); - Assert.Equal("The anti-forgery cookie token and form field token do not match.", exception.ExceptionMessage); + Assert.Equal("The antiforgery cookie token and form field token do not match.", exception.ExceptionMessage); } [Fact] @@ -185,9 +185,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // do a get response. var getResponse = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); - var formToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(resposneBody, "Account/Login"); - var cookieTokenKey = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse).Key; + var responseBody = await getResponse.Content.ReadAsStringAsync(); + var formToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseBody, "Account/Login"); + var cookieTokenKey = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse).Key; var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); var nameValueCollection = new List> @@ -205,7 +205,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // Assert var exception = response.GetServerException(); Assert.Equal( - "The required anti-forgery cookie \"" + cookieTokenKey + "\" is not present.", + "The required antiforgery cookie \"" + cookieTokenKey + "\" is not present.", exception.ExceptionMessage); } @@ -216,8 +216,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var server = TestHelper.CreateServer(_app, SiteName, _configureServices); var client = server.CreateClient(); var getResponse = await client.GetAsync("http://localhost/Account/Login"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); - var cookieToken = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse); + var responseBody = await getResponse.Content.ReadAsStringAsync(); + var cookieToken = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/Login"); request.Headers.Add("Cookie", cookieToken.Key + "=" + cookieToken.Value); @@ -234,7 +234,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // Assert var exception = response.GetServerException(); - Assert.Equal("The required anti-forgery form field \"__RequestVerificationToken\" is not present.", + Assert.Equal("The required antiforgery form field \"__RequestVerificationToken\" is not present.", exception.ExceptionMessage); } @@ -265,10 +265,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests // do a get response. var getResponse = await client.GetAsync("http://localhost/Account/FlushAsyncLogin"); - var resposneBody = await getResponse.Content.ReadAsStringAsync(); + var responseBody = await getResponse.Content.ReadAsStringAsync(); - var formToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(resposneBody, "Account/FlushAsyncLogin"); - var cookieToken = AntiForgeryTestHelper.RetrieveAntiForgeryCookie(getResponse); + var formToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseBody, "Account/FlushAsyncLogin"); + var cookieToken = AntiforgeryTestHelper.RetrieveAntiforgeryCookie(getResponse); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Account/FlushAsyncLogin"); request.Headers.Add("Cookie", cookieToken.Key + "=" + cookieToken.Value); diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs index 04dd5ee271..a27f4c0573 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests [InlineData("Image", null)] // Testing InputTagHelper with File [InlineData("Input", null)] - public async Task HtmlGenerationWebSite_GeneratesExpectedResults(string action, string antiForgeryPath) + public async Task HtmlGenerationWebSite_GeneratesExpectedResults(string action, string antiforgeryPath) { // Arrange var server = TestHelper.CreateServer(_app, SiteName, _configureServices); @@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal(expectedMediaType, response.Content.Headers.ContentType); responseContent = responseContent.Trim(); - if (antiForgeryPath == null) + if (antiforgeryPath == null) { #if GENERATE_BASELINES ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent); @@ -82,7 +82,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests } else { - var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath); + var forgeryToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, antiforgeryPath); #if GENERATE_BASELINES // Reverse usual substitution and insert a format item into the new file content. responseContent = responseContent.Replace(forgeryToken, "{0}"); @@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests [InlineData("OrderUsingHtmlHelpers", "/HtmlGeneration_Order/Submit")] [InlineData("Product", null)] [InlineData("Script", null)] - public async Task HtmlGenerationWebSite_GenerateEncodedResults(string action, string antiForgeryPath) + public async Task HtmlGenerationWebSite_GenerateEncodedResults(string action, string antiforgeryPath) { // Arrange var server = TestHelper.CreateServer(_app, SiteName, services => @@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal(expectedMediaType, response.Content.Headers.ContentType); responseContent = responseContent.Trim(); - if (antiForgeryPath == null) + if (antiforgeryPath == null) { #if GENERATE_BASELINES ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent); @@ -138,7 +138,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests } else { - var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath); + var forgeryToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, antiforgeryPath); #if GENERATE_BASELINES // Reverse usual substitution and insert a format item into the new file content. responseContent = responseContent.Replace(forgeryToken, "{0}"); @@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests responseContent = responseContent.Trim(); var forgeryToken = - AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, "Customer/HtmlGeneration_Customer"); + AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, "Customer/HtmlGeneration_Customer"); #if GENERATE_BASELINES // Reverse usual substitution and insert a format item into the new file content. @@ -461,11 +461,11 @@ Products: Laptops (3)"; [InlineData(null)] [InlineData(true)] [InlineData(false)] - public async Task FormTagHelper_GeneratesExpectedContent(bool? optionsAntiForgery) + public async Task FormTagHelper_GeneratesExpectedContent(bool? optionsAntiforgery) { // Arrange var newServices = new ServiceCollection(); - newServices.InitializeTagHelper((helper, _) => helper.AntiForgery = optionsAntiForgery); + newServices.InitializeTagHelper((helper, _) => helper.Antiforgery = optionsAntiforgery); var server = TestHelper.CreateServer(_app, SiteName, services => { @@ -476,8 +476,8 @@ Products: Laptops (3)"; var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8"); var outputFile = string.Format( - "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.{0}.html", - optionsAntiForgery?.ToString() ?? "null"); + "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.{0}.html", + optionsAntiforgery?.ToString() ?? "null"); var expectedContent = await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false); @@ -491,7 +491,7 @@ Products: Laptops (3)"; Assert.Equal(expectedMediaType, response.Content.Headers.ContentType); responseContent = responseContent.Trim(); - var forgeryTokens = AntiForgeryTestHelper.RetrieveAntiForgeryTokens(responseContent).ToArray(); + var forgeryTokens = AntiforgeryTestHelper.RetrieveAntiforgeryTokens(responseContent).ToArray(); #if GENERATE_BASELINES // Reverse usual substitutions and insert format items into the new file content. diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.False.html b/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.False.html similarity index 100% rename from test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.False.html rename to test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.False.html diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.True.html b/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.True.html similarity index 100% rename from test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.True.html rename to test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.True.html diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.null.html b/test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.null.html similarity index 100% rename from test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.AntiForgery.null.html rename to test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Form.Options.Antiforgery.null.html diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json index f618d2ffd3..4c96a7a628 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json @@ -11,7 +11,7 @@ "ActionResultsWebSite": "1.0.0", "ActivatorWebSite": "1.0.0", "AddServicesWebSite": "1.0.0", - "AntiForgeryWebSite": "1.0.0", + "AntiforgeryTokenWebSite": "1.0.0", "ApiExplorerWebSite": "1.0.0", "ApplicationModelWebSite": "1.0.0", "BasicWebSite": "1.0.0", diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs index 6d90cf2f0b..7e5ea5823a 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers { "asp-action", "index" }, { "asp-controller", "home" }, { "method", "post" }, - { "asp-anti-forgery", true } + { "asp-antiforgery", true } }, items: new Dictionary(), uniqueId: "test", @@ -58,12 +58,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers var viewContext = TestableHtmlGenerator.GetViewContext(model: null, htmlGenerator: htmlGenerator, metadataProvider: metadataProvider); - var expectedPostContent = "Something" + htmlGenerator.GenerateAntiForgery(viewContext) - .ToString(TagRenderMode.SelfClosing); + var expectedPostContent = "Something" + htmlGenerator.GenerateAntiforgery(viewContext); var formTagHelper = new FormTagHelper(htmlGenerator) { Action = "index", - AntiForgery = true, + Antiforgery = true, Controller = "home", ViewContext = viewContext, RouteValues = @@ -93,8 +92,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers [InlineData(null, "")] [InlineData(true, "")] [InlineData(false, "")] - public async Task ProcessAsync_GeneratesAntiForgeryCorrectly( - bool? antiForgery, + public async Task ProcessAsync_GeneratesAntiforgeryCorrectly( + bool? antiforgery, string expectedPostContent) { // Arrange @@ -124,12 +123,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers It.IsAny())) .Returns(new TagBuilder("form", new CommonTestEncoder())); - generator.Setup(mock => mock.GenerateAntiForgery(viewContext)) - .Returns(new TagBuilder("input", new CommonTestEncoder())); + generator.Setup(mock => mock.GenerateAntiforgery(viewContext)) + .Returns(new HtmlString("")); var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", - AntiForgery = antiForgery, + Antiforgery = antiforgery, ViewContext = viewContext, }; @@ -195,7 +194,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", - AntiForgery = false, + Antiforgery = false, ViewContext = testViewContext, RouteValues = { @@ -250,7 +249,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", - AntiForgery = false, + Antiforgery = false, Controller = "Home", ViewContext = viewContext, }; @@ -299,7 +298,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { - AntiForgery = false, + Antiforgery = false, Route = "Default", ViewContext = viewContext, RouteValues = @@ -326,19 +325,19 @@ namespace Microsoft.AspNet.Mvc.TagHelpers [InlineData(true, "")] [InlineData(false, "")] [InlineData(null, "")] - public async Task ProcessAsync_SupportsAntiForgeryIfActionIsSpecified( - bool? antiForgery, + public async Task ProcessAsync_SupportsAntiforgeryIfActionIsSpecified( + bool? antiforgery, string expectedPostContent) { // Arrange var viewContext = CreateViewContext(); var generator = new Mock(); - generator.Setup(mock => mock.GenerateAntiForgery(It.IsAny())) - .Returns(new TagBuilder("input", new CommonTestEncoder())); + generator.Setup(mock => mock.GenerateAntiforgery(It.IsAny())) + .Returns(new HtmlString("")); var formTagHelper = new FormTagHelper(generator.Object) { - AntiForgery = antiForgery, + Antiforgery = antiforgery, ViewContext = viewContext, }; diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs index d00c5f7cae..9cc7177b5b 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using Microsoft.AspNet.Antiforgery; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.ModelBinding; @@ -38,7 +39,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers IOptions options, IUrlHelper urlHelper, IDictionary validationAttributes) - : base(GetAntiForgery(), options, metadataProvider, urlHelper, new CommonTestEncoder()) + : base(Mock.Of(), options, metadataProvider, urlHelper, new CommonTestEncoder()) { _validationAttributes = validationAttributes; } @@ -69,9 +70,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers return viewContext; } - public override TagBuilder GenerateAntiForgery(ViewContext viewContext) + public override HtmlString GenerateAntiforgery(ViewContext viewContext) { - return new TagBuilder("input", new CommonTestEncoder()) + var tagBuilder = new TagBuilder("input", new CommonTestEncoder()) { Attributes = { @@ -80,6 +81,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers { "value", "olJlUDjrouRNWLen4tQJhauj1Z1rrvnb3QD65cmQU1Ykqi6S4" }, // 50 chars of a token. }, }; + + return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing); } protected override IDictionary GetValidationAttributes( @@ -99,26 +102,5 @@ namespace Microsoft.AspNet.Mvc.TagHelpers return mockOptions.Object; } - private static AntiForgery GetAntiForgery() - { - // AntiForgery must be passed to TestableHtmlGenerator constructor but will never be called. - var optionsAccessor = new Mock>(); - var mockDataProtectionOptions = new Mock>(); - mockDataProtectionOptions - .SetupGet(options => options.Options) - .Returns(Mock.Of()); - optionsAccessor - .SetupGet(o => o.Options) - .Returns(new AntiForgeryOptions()); - var antiForgery = new AntiForgery( - Mock.Of(), - Mock.Of(), - Mock.Of(), - optionsAccessor.Object, - new CommonTestEncoder(), - mockDataProtectionOptions.Object); - - return antiForgery; - } } } \ No newline at end of file diff --git a/test/WebSites/AntiForgeryWebSite/readme.md b/test/WebSites/AntiForgeryWebSite/readme.md deleted file mode 100644 index f7f9e69dbf..0000000000 --- a/test/WebSites/AntiForgeryWebSite/readme.md +++ /dev/null @@ -1,5 +0,0 @@ -AntiForgeryWebSite -=== - -This web site illustrates how to use anti forgery system to prevent CSRF attacks. The web site has an -`AccountsController` which uses an anti forgery token to validate incoming form posts. diff --git a/test/WebSites/AntiForgeryWebSite/AntiForgeryWebSite.xproj b/test/WebSites/AntiforgeryTokenWebSite/AntiforgeryTokenWebSite.xproj similarity index 89% rename from test/WebSites/AntiForgeryWebSite/AntiForgeryWebSite.xproj rename to test/WebSites/AntiforgeryTokenWebSite/AntiforgeryTokenWebSite.xproj index f4778bec48..84d4a0b9af 100644 --- a/test/WebSites/AntiForgeryWebSite/AntiForgeryWebSite.xproj +++ b/test/WebSites/AntiforgeryTokenWebSite/AntiforgeryTokenWebSite.xproj @@ -10,6 +10,9 @@ ..\..\..\artifacts\obj\$(MSBuildProjectName) ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + + AntiforgeryTokenWebSite + 2.0 49637 diff --git a/test/WebSites/AntiForgeryWebSite/Controllers/AccountController.cs b/test/WebSites/AntiforgeryTokenWebSite/Controllers/AccountController.cs similarity index 97% rename from test/WebSites/AntiForgeryWebSite/Controllers/AccountController.cs rename to test/WebSites/AntiforgeryTokenWebSite/Controllers/AccountController.cs index 90ca19ea30..14402b8030 100644 --- a/test/WebSites/AntiForgeryWebSite/Controllers/AccountController.cs +++ b/test/WebSites/AntiforgeryTokenWebSite/Controllers/AccountController.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Mvc; -namespace AntiForgeryWebSite +namespace AntiforgeryTokenWebSite { // This controller is reachable via traditional routing. public class AccountController : Controller diff --git a/test/WebSites/AntiForgeryWebSite/Controllers/HomeController.cs b/test/WebSites/AntiforgeryTokenWebSite/Controllers/HomeController.cs similarity index 92% rename from test/WebSites/AntiForgeryWebSite/Controllers/HomeController.cs rename to test/WebSites/AntiforgeryTokenWebSite/Controllers/HomeController.cs index cbd57e3320..0aebd9f32c 100644 --- a/test/WebSites/AntiForgeryWebSite/Controllers/HomeController.cs +++ b/test/WebSites/AntiforgeryTokenWebSite/Controllers/HomeController.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Mvc; -namespace AntiForgeryWebSite +namespace AntiforgeryTokenWebSite { // This controller is reachable via traditional routing. public class HomeController : Controller diff --git a/test/WebSites/AntiForgeryWebSite/Models/LoginViewModels.cs b/test/WebSites/AntiforgeryTokenWebSite/Models/LoginViewModels.cs similarity index 94% rename from test/WebSites/AntiForgeryWebSite/Models/LoginViewModels.cs rename to test/WebSites/AntiforgeryTokenWebSite/Models/LoginViewModels.cs index 0819c11721..442568d8fb 100644 --- a/test/WebSites/AntiForgeryWebSite/Models/LoginViewModels.cs +++ b/test/WebSites/AntiforgeryTokenWebSite/Models/LoginViewModels.cs @@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations; -namespace AntiForgeryWebSite +namespace AntiforgeryTokenWebSite { public class LoginViewModel { diff --git a/test/WebSites/AntiForgeryWebSite/Startup.cs b/test/WebSites/AntiforgeryTokenWebSite/Startup.cs similarity index 95% rename from test/WebSites/AntiForgeryWebSite/Startup.cs rename to test/WebSites/AntiforgeryTokenWebSite/Startup.cs index 07c771e2f7..543e9cf9a8 100644 --- a/test/WebSites/AntiForgeryWebSite/Startup.cs +++ b/test/WebSites/AntiforgeryTokenWebSite/Startup.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Builder; using Microsoft.Framework.DependencyInjection; -namespace AntiForgeryWebSite +namespace AntiforgeryTokenWebSite { public class Startup { diff --git a/test/WebSites/AntiForgeryWebSite/Views/Account/FlushAsyncLogin.cshtml b/test/WebSites/AntiforgeryTokenWebSite/Views/Account/FlushAsyncLogin.cshtml similarity index 97% rename from test/WebSites/AntiForgeryWebSite/Views/Account/FlushAsyncLogin.cshtml rename to test/WebSites/AntiforgeryTokenWebSite/Views/Account/FlushAsyncLogin.cshtml index 65ee7aedd1..aa92c14783 100644 --- a/test/WebSites/AntiForgeryWebSite/Views/Account/FlushAsyncLogin.cshtml +++ b/test/WebSites/AntiforgeryTokenWebSite/Views/Account/FlushAsyncLogin.cshtml @@ -1,4 +1,4 @@ -@model AntiForgeryWebSite.LoginViewModel +@model AntiforgeryTokenWebSite.LoginViewModel @{ ViewBag.Title = "Log in"; diff --git a/test/WebSites/AntiForgeryWebSite/Views/Account/Login.cshtml b/test/WebSites/AntiforgeryTokenWebSite/Views/Account/Login.cshtml similarity index 98% rename from test/WebSites/AntiForgeryWebSite/Views/Account/Login.cshtml rename to test/WebSites/AntiforgeryTokenWebSite/Views/Account/Login.cshtml index 8c7e3ac09b..6d449c7c49 100644 --- a/test/WebSites/AntiForgeryWebSite/Views/Account/Login.cshtml +++ b/test/WebSites/AntiforgeryTokenWebSite/Views/Account/Login.cshtml @@ -1,4 +1,4 @@ -@model AntiForgeryWebSite.LoginViewModel +@model AntiforgeryTokenWebSite.LoginViewModel @{ ViewBag.Title = "Log in"; diff --git a/test/WebSites/AntiForgeryWebSite/Views/Home/MyView.cshtml b/test/WebSites/AntiforgeryTokenWebSite/Views/Home/MyView.cshtml similarity index 100% rename from test/WebSites/AntiForgeryWebSite/Views/Home/MyView.cshtml rename to test/WebSites/AntiforgeryTokenWebSite/Views/Home/MyView.cshtml diff --git a/test/WebSites/AntiForgeryWebSite/Views/Shared/_FlushAsyncLayout.cshtml b/test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_FlushAsyncLayout.cshtml similarity index 74% rename from test/WebSites/AntiForgeryWebSite/Views/Shared/_FlushAsyncLayout.cshtml rename to test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_FlushAsyncLayout.cshtml index 08c9240c47..838fd4996b 100644 --- a/test/WebSites/AntiForgeryWebSite/Views/Shared/_FlushAsyncLayout.cshtml +++ b/test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_FlushAsyncLayout.cshtml @@ -1,8 +1,8 @@  - @ViewBag.Title – AntiForgery Functional Tests + @ViewBag.Title – Antiforgery Functional Tests -@SetAntiForgeryCookieAndHeader() +@SetAntiforgeryCookieAndHeader() @await FlushAsync() diff --git a/test/WebSites/AntiForgeryWebSite/Views/Shared/_Layout.cshtml b/test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_Layout.cshtml similarity index 78% rename from test/WebSites/AntiForgeryWebSite/Views/Shared/_Layout.cshtml rename to test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_Layout.cshtml index ede382285b..a37fecfbab 100644 --- a/test/WebSites/AntiForgeryWebSite/Views/Shared/_Layout.cshtml +++ b/test/WebSites/AntiforgeryTokenWebSite/Views/Shared/_Layout.cshtml @@ -3,7 +3,7 @@ - @ViewBag.Title –AntiForgery Functional Tests + @ViewBag.Title –Antiforgery Functional Tests