Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,178 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using Moq;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class AntiForgeryTokenSerializerTest
{
private static readonly AntiForgeryTokenSerializer _testSerializer = new AntiForgeryTokenSerializer(cryptoSystem: CreateIdentityTransformCryptoSystem());
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 });
[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(string serializedToken)
{
// Act & assert
var ex = Assert.Throws<HttpAntiForgeryException>(() => _testSerializer.Deserialize(serializedToken));
Assert.Equal(@"The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the <machineKey> configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.", ex.Message);
}
[Fact]
public void Serialize_FieldToken_WithClaimUid()
{
// Arrange
const string expectedSerializedData =
"01" // Version
+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
+ "00" // IsSessionToken
+ "01" // IsClaimsBased
+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid
+ "05" // AdditionalData length header
+ "E282AC3437"; // AdditionalData ("€47") as UTF8
AntiForgeryToken token = new AntiForgeryToken()
{
SecurityToken = _securityToken,
IsSessionToken = false,
ClaimUid = _claimUid,
AdditionalData = "€47"
};
// Act & assert - serialization
string actualSerializedData = _testSerializer.Serialize(token);
Assert.Equal(expectedSerializedData, actualSerializedData);
// Act & assert - deserialization
AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
AssertTokensEqual(token, deserializedToken);
}
[Fact]
public void Serialize_FieldToken_WithUsername()
{
// Arrange
const string expectedSerializedData =
"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
AntiForgeryToken token = new AntiForgeryToken()
{
SecurityToken = _securityToken,
IsSessionToken = false,
Username = "Jérôme",
AdditionalData = "€47"
};
// Act & assert - serialization
string actualSerializedData = _testSerializer.Serialize(token);
Assert.Equal(expectedSerializedData, actualSerializedData);
// Act & assert - deserialization
AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
AssertTokensEqual(token, deserializedToken);
}
[Fact]
public void Serialize_SessionToken()
{
// Arrange
const string expectedSerializedData =
"01" // Version
+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
+ "01"; // IsSessionToken
AntiForgeryToken token = new AntiForgeryToken()
{
SecurityToken = _securityToken,
IsSessionToken = true
};
// Act & assert - serialization
string actualSerializedData = _testSerializer.Serialize(token);
Assert.Equal(expectedSerializedData, actualSerializedData);
// Act & assert - deserialization
AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
AssertTokensEqual(token, deserializedToken);
}
private static string BytesToHex(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", b);
}
return sb.ToString();
}
private static byte[] HexToBytes(string hex)
{
List<byte> bytes = new List<byte>();
for (int i = 0; i < hex.Length; i += 2)
{
byte b = Byte.Parse(hex.Substring(i, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
bytes.Add(b);
}
return bytes.ToArray();
}
private static ICryptoSystem CreateIdentityTransformCryptoSystem()
{
Mock<MockableCryptoSystem> mockCryptoSystem = new Mock<MockableCryptoSystem>();
mockCryptoSystem.Setup(o => o.Protect(It.IsAny<byte[]>())).Returns<byte[]>(HexUtil.HexEncode);
mockCryptoSystem.Setup(o => o.Unprotect(It.IsAny<string>())).Returns<string>(HexUtil.HexDecode);
return mockCryptoSystem.Object;
}
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);
}
}
}

View File

@@ -0,0 +1,236 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Mvc;
using Moq;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class AntiForgeryTokenStoreTest
{
[Fact]
public void GetCookieToken_CookieDoesNotExist_ReturnsNull()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Cookies).Returns(new HttpCookieCollection());
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
CookieName = "cookie-name"
};
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: null);
// Act
AntiForgeryToken token = tokenStore.GetCookieToken(mockHttpContext.Object);
// Assert
Assert.Null(token);
}
[Fact]
public void GetCookieToken_CookieIsEmpty_ReturnsNull()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Cookies).Returns(new HttpCookieCollection()
{
new HttpCookie("cookie-name", "")
});
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
CookieName = "cookie-name"
};
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: null);
// Act
AntiForgeryToken token = tokenStore.GetCookieToken(mockHttpContext.Object);
// Assert
Assert.Null(token);
}
[Fact]
public void GetCookieToken_CookieIsInvalid_PropagatesException()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Cookies).Returns(new HttpCookieCollection()
{
new HttpCookie("cookie-name", "invalid-value")
});
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
CookieName = "cookie-name"
};
HttpAntiForgeryException expectedException = new HttpAntiForgeryException("some exception");
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("invalid-value")).Throws(expectedException);
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: mockSerializer.Object);
// Act & assert
var ex = Assert.Throws<HttpAntiForgeryException>(() => tokenStore.GetCookieToken(mockHttpContext.Object));
Assert.Equal(expectedException, ex);
}
[Fact]
public void GetCookieToken_CookieIsValid_ReturnsToken()
{
// Arrange
AntiForgeryToken expectedToken = new AntiForgeryToken();
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Cookies).Returns(new HttpCookieCollection()
{
new HttpCookie("cookie-name", "valid-value")
});
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
CookieName = "cookie-name"
};
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("valid-value")).Returns((object)expectedToken);
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: mockSerializer.Object);
// Act
AntiForgeryToken retVal = tokenStore.GetCookieToken(mockHttpContext.Object);
// Assert
Assert.Same(expectedToken, retVal);
}
[Fact]
public void GetFormToken_FormFieldIsEmpty_ReturnsNull()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Form.Get("form-field-name")).Returns("");
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: null);
// Act
AntiForgeryToken token = tokenStore.GetFormToken(mockHttpContext.Object);
// Assert
Assert.Null(token);
}
[Fact]
public void GetFormToken_FormFieldIsInvalid_PropagatesException()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Form.Get("form-field-name")).Returns("invalid-value");
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
HttpAntiForgeryException expectedException = new HttpAntiForgeryException("some exception");
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("invalid-value")).Throws(expectedException);
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: mockSerializer.Object);
// Act & assert
var ex = Assert.Throws<HttpAntiForgeryException>(() => tokenStore.GetFormToken(mockHttpContext.Object));
Assert.Same(expectedException, ex);
}
[Fact]
public void GetFormToken_FormFieldIsValid_ReturnsToken()
{
// Arrange
AntiForgeryToken expectedToken = new AntiForgeryToken();
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.Form.Get("form-field-name")).Returns("valid-value");
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("valid-value")).Returns((object)expectedToken);
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: mockSerializer.Object);
// Act
AntiForgeryToken retVal = tokenStore.GetFormToken(mockHttpContext.Object);
// Assert
Assert.Same(expectedToken, retVal);
}
[Theory]
[InlineData(true, true)]
[InlineData(false, null)]
public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag)
{
// Arrange
AntiForgeryToken token = new AntiForgeryToken();
HttpCookieCollection cookies = new HttpCookieCollection();
bool defaultCookieSecureValue = expectedCookieSecureFlag ?? new HttpCookie("name", "value").Secure; // pulled from config; set by ctor
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Response.Cookies).Returns(cookies);
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Serialize(token)).Returns("serialized-value");
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
CookieName = "cookie-name",
RequireSSL = requireSsl
};
AntiForgeryTokenStore tokenStore = new AntiForgeryTokenStore(
config: config,
serializer: mockSerializer.Object);
// Act
tokenStore.SaveCookieToken(mockHttpContext.Object, token);
// Assert
Assert.Equal(1, cookies.Count);
HttpCookie cookie = cookies["cookie-name"];
Assert.NotNull(cookie);
Assert.Equal("serialized-value", cookie.Value);
Assert.True(cookie.HttpOnly);
Assert.Equal(defaultCookieSecureValue, cookie.Secure);
}
}
}

View File

@@ -0,0 +1,108 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class AntiForgeryTokenTest
{
[Fact]
public void AdditionalDataProperty()
{
// Arrange
AntiForgeryToken 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
AntiForgeryToken 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
AntiForgeryToken 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 SecurityTokenProperty()
{
// Arrange
AntiForgeryToken token = new AntiForgeryToken();
// Act & assert - 1
BinaryBlob securityToken = token.SecurityToken;
Assert.NotNull(securityToken);
Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength);
Assert.Equal(securityToken, token.SecurityToken); // check that we're not making a new one each property call
// Act & assert - 2
securityToken = new BinaryBlob(64);
token.SecurityToken = securityToken;
Assert.Equal(securityToken, token.SecurityToken);
// Act & assert - 3
token.SecurityToken = null;
securityToken = token.SecurityToken;
Assert.NotNull(securityToken);
Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength);
Assert.Equal(securityToken, token.SecurityToken); // check that we're not making a new one each property call
}
[Fact]
public void UsernameProperty()
{
// Arrange
AntiForgeryToken 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);
}
}
}

View File

@@ -0,0 +1,403 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Security.Principal;
using System.Web.Helpers.Test;
using System.Web.Mvc;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class AntiForgeryWorkerTest
{
[Fact]
public void ChecksSSL()
{
// Arrange
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.Request.IsSecureConnection).Returns(false);
IAntiForgeryConfig config = new MockAntiForgeryConfig()
{
RequireSSL = true
};
AntiForgeryWorker worker = new AntiForgeryWorker(
config: config,
serializer: null,
tokenStore: null,
validator: null);
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => worker.Validate(mockHttpContext.Object, "session-token", "field-token"));
Assert.Equal(@"The anti-forgery system has the configuration value AntiForgeryConfig.RequireSsl = true, but the current request is not an SSL request.", ex.Message);
ex = Assert.Throws<InvalidOperationException>(() => worker.Validate(mockHttpContext.Object));
Assert.Equal(@"The anti-forgery system has the configuration value AntiForgeryConfig.RequireSsl = true, but the current request is not an SSL request.", ex.Message);
ex = Assert.Throws<InvalidOperationException>(() => worker.GetFormInputElement(mockHttpContext.Object));
Assert.Equal(@"The anti-forgery system has the configuration value AntiForgeryConfig.RequireSsl = true, but the current request is not an SSL request.", ex.Message);
ex = Assert.Throws<InvalidOperationException>(() => { string dummy1, dummy2; worker.GetTokens(mockHttpContext.Object, "cookie-token", out dummy1, out dummy2); });
Assert.Equal(@"The anti-forgery system has the configuration value AntiForgeryConfig.RequireSsl = true, but the current request is not an SSL request.", ex.Message);
}
[Fact]
public void GetFormInputElement_ExistingInvalidCookieToken()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>(MockBehavior.Strict);
mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(oldCookieToken);
mockTokenStore.Setup(o => o.SaveCookieToken(mockHttpContext.Object, newCookieToken)).Verifiable();
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)).Returns(false);
mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: config,
serializer: mockSerializer.Object,
tokenStore: mockTokenStore.Object,
validator: mockValidator.Object);
// Act
TagBuilder retVal = worker.GetFormInputElement(mockHttpContext.Object);
// Assert
Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />", retVal.ToString(TagRenderMode.SelfClosing));
mockTokenStore.Verify();
}
[Fact]
public void GetFormInputElement_ExistingInvalidCookieToken_SwallowsExceptions()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>(MockBehavior.Strict);
mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Throws(new Exception("should be swallowed"));
mockTokenStore.Setup(o => o.SaveCookieToken(mockHttpContext.Object, newCookieToken)).Verifiable();
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(null)).Returns(false);
mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: config,
serializer: mockSerializer.Object,
tokenStore: mockTokenStore.Object,
validator: mockValidator.Object);
// Act
TagBuilder retVal = worker.GetFormInputElement(mockHttpContext.Object);
// Assert
Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />", retVal.ToString(TagRenderMode.SelfClosing));
mockTokenStore.Verify();
}
[Fact]
public void GetFormInputElement_ExistingValidCookieToken()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
FormFieldName = "form-field-name"
};
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>(MockBehavior.Strict);
mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(cookieToken);
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, cookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(cookieToken)).Returns(true);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: config,
serializer: mockSerializer.Object,
tokenStore: mockTokenStore.Object,
validator: mockValidator.Object);
// Act
TagBuilder retVal = worker.GetFormInputElement(mockHttpContext.Object);
// Assert
Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />", retVal.ToString(TagRenderMode.SelfClosing));
}
[Fact]
public void GetTokens_ExistingInvalidCookieToken()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")).Returns(oldCookieToken);
mockSerializer.Setup(o => o.Serialize(newCookieToken)).Returns("serialized-new-cookie-token");
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)).Returns(false);
mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: mockSerializer.Object,
tokenStore: null,
validator: mockValidator.Object);
// Act
string serializedNewCookieToken, serializedFormToken;
worker.GetTokens(mockHttpContext.Object, "serialized-old-cookie-token", out serializedNewCookieToken, out serializedFormToken);
// Assert
Assert.Equal("serialized-new-cookie-token", serializedNewCookieToken);
Assert.Equal("serialized-form-token", serializedFormToken);
}
[Fact]
public void GetTokens_ExistingInvalidCookieToken_SwallowsExceptions()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")).Throws(new Exception("should be swallowed"));
mockSerializer.Setup(o => o.Serialize(newCookieToken)).Returns("serialized-new-cookie-token");
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(null)).Returns(false);
mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: mockSerializer.Object,
tokenStore: null,
validator: mockValidator.Object);
// Act
string serializedNewCookieToken, serializedFormToken;
worker.GetTokens(mockHttpContext.Object, "serialized-old-cookie-token", out serializedNewCookieToken, out serializedFormToken);
// Assert
Assert.Equal("serialized-new-cookie-token", serializedNewCookieToken);
Assert.Equal("serialized-form-token", serializedFormToken);
}
[Fact]
public void GetTokens_ExistingValidCookieToken()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")).Returns(cookieToken);
mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, cookieToken)).Returns(formToken);
mockValidator.Setup(o => o.IsCookieTokenValid(cookieToken)).Returns(true);
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: mockSerializer.Object,
tokenStore: null,
validator: mockValidator.Object);
// Act
string serializedNewCookieToken, serializedFormToken;
worker.GetTokens(mockHttpContext.Object, "serialized-old-cookie-token", out serializedNewCookieToken, out serializedFormToken);
// Assert
Assert.Null(serializedNewCookieToken);
Assert.Equal("serialized-form-token", serializedFormToken);
}
[Fact]
public void Validate_FromStrings_Failure()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken();
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("cookie-token")).Returns(cookieToken);
mockSerializer.Setup(o => o.Deserialize("form-token")).Returns(formToken);
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Throws(new HttpAntiForgeryException("my-message"));
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: mockSerializer.Object,
tokenStore: null,
validator: mockValidator.Object);
// Act & assert
var ex = Assert.Throws<HttpAntiForgeryException>(() => worker.Validate(mockHttpContext.Object, "cookie-token", "form-token"));
Assert.Equal("my-message", ex.Message);
}
[Fact]
public void Validate_FromStrings_Success()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken();
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>();
mockSerializer.Setup(o => o.Deserialize("cookie-token")).Returns(cookieToken);
mockSerializer.Setup(o => o.Deserialize("form-token")).Returns(formToken);
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Verifiable();
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: mockSerializer.Object,
tokenStore: null,
validator: mockValidator.Object);
// Act
worker.Validate(mockHttpContext.Object, "cookie-token", "form-token");
// Assert
mockValidator.Verify();
}
[Fact]
public void Validate_FromStore_Failure()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken();
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>();
mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(cookieToken);
mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken);
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Throws(new HttpAntiForgeryException("my-message"));
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: null,
tokenStore: mockTokenStore.Object,
validator: mockValidator.Object);
// Act & assert
var ex = Assert.Throws<HttpAntiForgeryException>(() => worker.Validate(mockHttpContext.Object));
Assert.Equal("my-message", ex.Message);
}
[Fact]
public void Validate_FromStore_Success()
{
// Arrange
GenericIdentity identity = new GenericIdentity("some-user");
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));
AntiForgeryToken cookieToken = new AntiForgeryToken();
AntiForgeryToken formToken = new AntiForgeryToken();
Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>();
mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(cookieToken);
mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken);
Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Verifiable();
AntiForgeryWorker worker = new AntiForgeryWorker(
config: new MockAntiForgeryConfig(),
serializer: null,
tokenStore: mockTokenStore.Object,
validator: mockValidator.Object);
// Act
worker.Validate(mockHttpContext.Object);
// Assert
mockValidator.Verify();
}
}
}

View File

@@ -0,0 +1,129 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class BinaryBlobTest
{
[Fact]
public void Ctor_BitLength()
{
// Act
BinaryBlob blob = new BinaryBlob(bitLength: 64);
byte[] 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<ArgumentOutOfRangeException>(() => new BinaryBlob(bitLength));
Assert.Equal("bitLength", ex.ParamName);
}
[Fact]
public void Ctor_BitLength_ProducesDifferentValues()
{
// Act
BinaryBlob blobA = new BinaryBlob(bitLength: 64);
BinaryBlob blobB = new BinaryBlob(bitLength: 64);
// Assert
Assert.NotEqual(blobA.GetData(), blobB.GetData());
}
[Fact]
public void Ctor_Data()
{
// Arrange
byte[] expectedData = new byte[] { 0x01, 0x02, 0x03, 0x04 };
// Act
BinaryBlob 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<ArgumentOutOfRangeException>(() => 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
byte[] blobData = new byte[] { 0x01, 0x02, 0x03, 0x04 };
int expectedHashCode = BitConverter.ToInt32(blobData, 0);
BinaryBlob blob = new BinaryBlob(32, blobData);
// Act
int actualHashCode = blob.GetHashCode();
// Assert
Assert.Equal(expectedHashCode, actualHashCode);
}
}
}

View File

@@ -0,0 +1,239 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reflection;
using System.Security.Principal;
using System.Web.Helpers.Claims;
using System.Web.Helpers.Claims.Test;
using System.Web.Helpers.Test;
using Moq;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class ClaimUidExtractorTest
{
[Fact]
public void ExtractClaimUid_NullIdentity()
{
// Arrange
ClaimUidExtractor extractor = new ClaimUidExtractor(
config: null,
claimsIdentityConverter: null);
// Act
BinaryBlob retVal = extractor.ExtractClaimUid(null);
// Assert
Assert.Null(retVal);
}
[Fact]
public void ExtractClaimUid_Unauthenticated()
{
// Arrange
ClaimUidExtractor extractor = new ClaimUidExtractor(
config: null,
claimsIdentityConverter: null);
Mock<IIdentity> mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(o => o.IsAuthenticated).Returns(false);
// Act
BinaryBlob retVal = extractor.ExtractClaimUid(mockIdentity.Object);
// Assert
Assert.Null(retVal);
}
[Fact]
public void ExtractClaimUid_ClaimsIdentityHeuristicsSuppressed()
{
// Arrange
GenericIdentity identity = new GenericIdentity("the-user");
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
SuppressIdentityHeuristicChecks = true
};
ClaimUidExtractor extractor = new ClaimUidExtractor(
config: config,
claimsIdentityConverter: null);
// Act
BinaryBlob retVal = extractor.ExtractClaimUid(identity);
// Assert
Assert.Null(retVal);
}
[Fact]
public void ExtractClaimUid_NotAClaimsIdentity()
{
// Arrange
Mock<IIdentity> mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(o => o.IsAuthenticated).Returns(true);
MockAntiForgeryConfig config = new MockAntiForgeryConfig();
ClaimsIdentityConverter converter = new ClaimsIdentityConverter(new Func<IIdentity, ClaimsIdentity>[0]);
ClaimUidExtractor extractor = new ClaimUidExtractor(
config: config,
claimsIdentityConverter: converter);
// Act
BinaryBlob retVal = extractor.ExtractClaimUid(mockIdentity.Object);
// Assert
Assert.Null(retVal);
}
[Fact]
public void ExtractClaimUid_ClaimsIdentity()
{
// Arrange
Mock<IIdentity> mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(o => o.IsAuthenticated).Returns(true);
MockAntiForgeryConfig config = new MockAntiForgeryConfig()
{
UniqueClaimTypeIdentifier = "unique-identifier"
};
ClaimsIdentityConverter converter = new ClaimsIdentityConverter(new Func<IIdentity, ClaimsIdentity>[] {
identity =>
{
Assert.Equal(mockIdentity.Object, identity);
MockClaimsIdentity claimsIdentity = new MockClaimsIdentity();
claimsIdentity.AddClaim("unique-identifier", "some-value");
return claimsIdentity;
}
});
ClaimUidExtractor extractor = new ClaimUidExtractor(
config: config,
claimsIdentityConverter: converter);
// Act
BinaryBlob retVal = extractor.ExtractClaimUid(mockIdentity.Object);
// Assert
Assert.NotNull(retVal);
Assert.Equal("CA9CCFF86F903FBB7505BAAA9F222E49EC2A1E8FAD630AE73DE180BD679751ED", HexUtil.HexEncode(retVal.GetData()));
}
[Theory]
[DefaultUniqueClaimTypes_NotPresent_Data]
public void DefaultUniqueClaimTypes_NotPresent_Throws(object identity)
{
// Arrange
ClaimsIdentity claimsIdentity = (ClaimsIdentity)identity;
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => ClaimUidExtractor.GetUniqueIdentifierParameters(claimsIdentity, null));
Assert.Equal(@"A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was not present on the provided ClaimsIdentity. To enable anti-forgery token support with claims-based authentication, please verify that the configured claims provider is providing both of these claims on the ClaimsIdentity instances it generates. If the configured claims provider instead uses a different claim type as a unique identifier, it can be configured by setting the static property AntiForgeryConfig.UniqueClaimTypeIdentifier.", ex.Message);
}
[Fact]
public void DefaultUniqueClaimTypes_Present()
{
// Arrange
MockClaimsIdentity identity = new MockClaimsIdentity();
identity.AddClaim("fooClaim", "fooClaimValue");
identity.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, "nameIdentifierValue");
identity.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, "identityProviderValue");
// Act
var retVal = ClaimUidExtractor.GetUniqueIdentifierParameters(identity, null);
// Assert
Assert.Equal(new string[] {
ClaimUidExtractor.NameIdentifierClaimType,
"nameIdentifierValue",
ClaimUidExtractor.IdentityProviderClaimType,
"identityProviderValue"
}, retVal);
}
[Fact]
public void ExplicitUniqueClaimType_Present()
{
// Arrange
MockClaimsIdentity identity = new MockClaimsIdentity();
identity.AddClaim("fooClaim", "fooClaimValue");
identity.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, "nameIdentifierValue");
identity.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, "identityProviderValue");
// Act
var retVal = ClaimUidExtractor.GetUniqueIdentifierParameters(identity, "fooClaim");
// Assert
Assert.Equal(new string[] {
"fooClaim",
"fooClaimValue"
}, retVal);
}
[Theory]
[ExplicitUniqueClaimType_NotPresent_Data]
public void ExplicitUniqueClaimType_NotPresent_Throws(object identity)
{
// Arrange
ClaimsIdentity claimsIdentity = (ClaimsIdentity)identity;
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => ClaimUidExtractor.GetUniqueIdentifierParameters(claimsIdentity, "fooClaim"));
Assert.Equal(@"A claim of type 'fooClaim' was not present on the provided ClaimsIdentity.", ex.Message);
}
private sealed class DefaultUniqueClaimTypes_NotPresent_DataAttribute : DataAttribute
{
public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, Type[] parameterTypes)
{
MockClaimsIdentity identity1 = new MockClaimsIdentity();
identity1.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, "identityProviderValue");
yield return new object[] { identity1 };
MockClaimsIdentity identity2 = new MockClaimsIdentity();
identity2.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, String.Empty);
identity2.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, "identityProviderValue");
yield return new object[] { identity2 };
MockClaimsIdentity identity3 = new MockClaimsIdentity();
identity3.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, "nameIdentifierValue");
yield return new object[] { identity3 };
MockClaimsIdentity identity4 = new MockClaimsIdentity();
identity4.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, "nameIdentifierValue");
identity4.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, String.Empty);
yield return new object[] { identity4 };
MockClaimsIdentity identity5 = new MockClaimsIdentity();
identity5.AddClaim(ClaimUidExtractor.NameIdentifierClaimType.ToUpper(), "nameIdentifierValue");
identity5.AddClaim(ClaimUidExtractor.IdentityProviderClaimType.ToUpper(), "identityProviderValue");
yield return new object[] { identity5 };
}
}
private sealed class ExplicitUniqueClaimType_NotPresent_DataAttribute : DataAttribute
{
public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, Type[] parameterTypes)
{
MockClaimsIdentity identity1 = new MockClaimsIdentity();
yield return new object[] { identity1 };
MockClaimsIdentity identity2 = new MockClaimsIdentity();
identity2.AddClaim("fooClaim", String.Empty);
yield return new object[] { identity2 };
MockClaimsIdentity identity3 = new MockClaimsIdentity();
identity3.AddClaim("FOOCLAIM", "fooClaimValue");
yield return new object[] { identity3 };
MockClaimsIdentity identity4 = new MockClaimsIdentity();
identity4.AddClaim(ClaimUidExtractor.NameIdentifierClaimType, "nameIdentifierValue");
identity4.AddClaim(ClaimUidExtractor.IdentityProviderClaimType, "identityProviderValue");
yield return new object[] { identity4 };
}
}
}
}

View File

@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace System.Web.Helpers.AntiXsrf.Test
{
internal static class HexUtil
{
public static string HexEncode(byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * 2);
foreach (byte b in data)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", b);
}
return sb.ToString();
}
public static byte[] HexDecode(string input)
{
List<byte> bytes = new List<byte>(input.Length / 2);
for (int i = 0; i < input.Length; i += 2)
{
bytes.Add(Byte.Parse(input.Substring(i, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture));
}
return bytes.ToArray();
}
}
}

View File

@@ -0,0 +1,122 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Security;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Helpers.AntiXsrf.Test
{
public class MachineKeyCryptoSystemTest
{
private static readonly MachineKeyCryptoSystem _dummyCryptoSystem = new MachineKeyCryptoSystem(HexEncoder, HexDecoder);
[Fact]
public void Base64ToHex()
{
// Arrange
string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_0";
string hex = "00108310518720928B30D38F41149351559761969B71D79F8218A39259A7A29AABB2DBAFC31CB3D35DB7E39EBBF3DFBF";
// Act
string retVal = MachineKeyCryptoSystem.Base64ToHex(base64);
// Assert
Assert.Equal(hex, retVal);
}
[Fact]
public void Base64ToHex_HexToBase64_RoundTrips()
{
for (int i = 0; i <= Byte.MaxValue; i++)
{
// Arrange
string hex = String.Format("{0:X2}", i);
// Act
string retVal = MachineKeyCryptoSystem.Base64ToHex(MachineKeyCryptoSystem.HexToBase64(hex));
// Assert
Assert.Equal(hex, retVal);
}
}
[Fact]
public void HexToBase64()
{
// Arrange
string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_0";
string hex = "00108310518720928B30D38F41149351559761969B71D79F8218A39259A7A29AABB2DBAFC31CB3D35DB7E39EBBF3DFBF";
// Act
string retVal = MachineKeyCryptoSystem.HexToBase64(hex);
// Assert
Assert.Equal(base64, retVal);
}
[Fact]
public void Protect()
{
// Arrange
byte[] data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 };
// Act
string retVal = _dummyCryptoSystem.Protect(data);
// Assert
Assert.Equal("hYfyZgECAwQF0", retVal);
}
[Theory]
[InlineData("hYfyZwECAwQF0")] // bad MagicHeader
[InlineData("hYfy0")] // too short to contain MagicHeader
public void Unprotect_Failure(string protectedData)
{
// Act
byte[] retVal = _dummyCryptoSystem.Unprotect(protectedData);
// Assert
Assert.Null(retVal);
}
[Fact]
public void Unprotect_Success()
{
// Arrange
byte[] expected = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 };
// Act
byte[] retVal = _dummyCryptoSystem.Unprotect("hYfyZgECAwQF0");
// Assert
Assert.Equal(expected, retVal);
}
[Fact]
public void Protect_Unprotect_RoundTrips()
{
// Arrange
byte[] data = new byte[1024];
new Random().NextBytes(data);
// Act
byte[] roundTripped = _dummyCryptoSystem.Unprotect(_dummyCryptoSystem.Protect(data));
// Assert
Assert.Equal(data, roundTripped);
}
private static string HexEncoder(byte[] data, MachineKeyProtection protection)
{
Assert.Equal(MachineKeyProtection.All, protection);
return HexUtil.HexEncode(data);
}
private static byte[] HexDecoder(string input, MachineKeyProtection protection)
{
Assert.Equal(MachineKeyProtection.All, protection);
return HexUtil.HexDecode(input);
}
}
}

View File

@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Helpers.AntiXsrf.Test
{
public sealed class MockAntiForgeryConfig : IAntiForgeryConfig
{
public IAntiForgeryAdditionalDataProvider AdditionalDataProvider
{
get;
set;
}
public string CookieName
{
get;
set;
}
public string FormFieldName
{
get;
set;
}
public bool RequireSSL
{
get;
set;
}
public bool SuppressIdentityHeuristicChecks
{
get;
set;
}
public string UniqueClaimTypeIdentifier
{
get;
set;
}
}
}

View File

@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Helpers.AntiXsrf.Test
{
// An IAntiForgeryTokenSerializer that can be passed to MoQ.
public abstract class MockableAntiForgeryTokenSerializer : IAntiForgeryTokenSerializer
{
public abstract object Deserialize(string serializedToken);
public abstract string Serialize(object token);
AntiForgeryToken IAntiForgeryTokenSerializer.Deserialize(string serializedToken)
{
return (AntiForgeryToken)Deserialize(serializedToken);
}
string IAntiForgeryTokenSerializer.Serialize(AntiForgeryToken token)
{
return Serialize(token);
}
}
}

View File

@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Security.Principal;
namespace System.Web.Helpers.AntiXsrf.Test
{
// An IClaimUidExtractor that can be passed to MoQ
public abstract class MockableClaimUidExtractor : IClaimUidExtractor
{
public abstract object ExtractClaimUid(IIdentity identity);
BinaryBlob IClaimUidExtractor.ExtractClaimUid(IIdentity identity)
{
return (BinaryBlob)ExtractClaimUid(identity);
}
}
}

View File

@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Helpers.AntiXsrf.Test
{
// An ICryptoSystem that can be passed to MoQ
public abstract class MockableCryptoSystem : ICryptoSystem
{
public abstract string Protect(byte[] data);
public abstract byte[] Unprotect(string protectedData);
}
}

View File

@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Security.Principal;
namespace System.Web.Helpers.AntiXsrf.Test
{
// An ITokenStore that can be passed to MoQ
public abstract class MockableTokenStore : ITokenStore
{
public abstract object GetCookieToken(HttpContextBase httpContext);
public abstract object GetFormToken(HttpContextBase httpContext);
public abstract void SaveCookieToken(HttpContextBase httpContext, object token);
AntiForgeryToken ITokenStore.GetCookieToken(HttpContextBase httpContext)
{
return (AntiForgeryToken)GetCookieToken(httpContext);
}
AntiForgeryToken ITokenStore.GetFormToken(HttpContextBase httpContext)
{
return (AntiForgeryToken)GetFormToken(httpContext);
}
void ITokenStore.SaveCookieToken(HttpContextBase httpContext, AntiForgeryToken token)
{
SaveCookieToken(httpContext, (AntiForgeryToken)token);
}
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Security.Principal;
namespace System.Web.Helpers.AntiXsrf.Test
{
// An ITokenValidator that can be passed to MoQ
public abstract class MockableTokenValidator : ITokenValidator
{
public abstract object GenerateCookieToken();
public abstract object GenerateFormToken(HttpContextBase httpContext, IIdentity identity, object cookieToken);
public abstract bool IsCookieTokenValid(object cookieToken);
public abstract void ValidateTokens(HttpContextBase httpContext, IIdentity identity, object cookieToken, object formToken);
AntiForgeryToken ITokenValidator.GenerateCookieToken()
{
return (AntiForgeryToken)GenerateCookieToken();
}
AntiForgeryToken ITokenValidator.GenerateFormToken(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken)
{
return (AntiForgeryToken)GenerateFormToken(httpContext, identity, (AntiForgeryToken)cookieToken);
}
bool ITokenValidator.IsCookieTokenValid(AntiForgeryToken cookieToken)
{
return IsCookieTokenValid((AntiForgeryToken)cookieToken);
}
void ITokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken, AntiForgeryToken formToken)
{
ValidateTokens(httpContext, identity, (AntiForgeryToken)cookieToken, (AntiForgeryToken)formToken);
}
}
}

File diff suppressed because it is too large Load Diff