240 lines
9.9 KiB
C#
Raw Normal View History

// 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 };
}
}
}
}