public void TryValidateTokenSet_FieldAndCookieTokensSwapped_CookieDuplicated()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();

        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            IsCookieToken = false
        };

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: null,
            additionalDataProvider: null);

        string expectedMessage =
            "Validation of the provided antiforgery token failed. " +
            "The cookie token and the request token were swapped.";

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, cookieToken, out message);

        // Assert
        Assert.False(result);
        Assert.Equal(expectedMessage, message);
    }
    public void TryValidateTokenSet_FieldAndCookieTokensHaveDifferentSecurityKeys()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();

        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            IsCookieToken = false
        };

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: null,
            additionalDataProvider: null);

        string expectedMessage = "The antiforgery cookie token and request token do not match.";

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.False(result);
        Assert.Equal(expectedMessage, message);
    }
    public void TryValidateTokenSet_ClaimUidMismatch()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var identity    = GetAuthenticatedIdentity("the-user");

        httpContext.User = new ClaimsPrincipal(identity);

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            SecurityToken = cookieToken.SecurityToken,
            IsCookieToken = false,
            ClaimUid      = new BinaryBlob(256)
        };

        var differentToken        = new BinaryBlob(256);
        var mockClaimUidExtractor = new Mock <IClaimUidExtractor>();

        mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is <ClaimsPrincipal>(c => c.Identity == identity)))
        .Returns(Convert.ToBase64String(differentToken.GetData()));

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: mockClaimUidExtractor.Object,
            additionalDataProvider: null);

        string expectedMessage =
            "The provided antiforgery token was meant for a different " +
            "claims-based user than the current user.";

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.False(result);
        Assert.Equal(expectedMessage, message);
    }
    public void TryValidateTokenSet_AdditionalDataRejected()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var identity    = new ClaimsIdentity();

        httpContext.User = new ClaimsPrincipal(identity);

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            SecurityToken  = cookieToken.SecurityToken,
            Username       = String.Empty,
            IsCookieToken  = false,
            AdditionalData = "some-additional-data"
        };

        var mockAdditionalDataProvider = new Mock <IAntiforgeryAdditionalDataProvider>();

        mockAdditionalDataProvider
        .Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data"))
        .Returns(false);

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: null,
            additionalDataProvider: mockAdditionalDataProvider.Object);

        string expectedMessage = "The provided antiforgery token failed a custom data check.";

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.False(result);
        Assert.Equal(expectedMessage, message);
    }
    public void TryValidateTokenSet_UsernameMismatch(string identityUsername, string embeddedUsername)
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var identity    = GetAuthenticatedIdentity(identityUsername);

        httpContext.User = new ClaimsPrincipal(identity);

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            SecurityToken = cookieToken.SecurityToken,
            Username      = embeddedUsername,
            IsCookieToken = false
        };

        var mockClaimUidExtractor = new Mock <IClaimUidExtractor>();

        mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is <ClaimsPrincipal>(c => c.Identity == identity)))
        .Returns((string)null);

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: mockClaimUidExtractor.Object,
            additionalDataProvider: null);

        string expectedMessage =
            $"The provided antiforgery token was meant for user \"{embeddedUsername}\", " +
            $"but the current user is \"{identityUsername}\".";

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.False(result);
        Assert.Equal(expectedMessage, message);
    }
    public void TryValidateTokenSet_CookieTokenMissing()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();

        httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

        var fieldtoken = new AntiforgeryToken()
        {
            IsCookieToken = false
        };

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: null,
            additionalDataProvider: null);

        // Act & Assert
        string message;
        var    ex = Assert.Throws <ArgumentNullException>(
            () => tokenProvider.TryValidateTokenSet(httpContext, null, fieldtoken, out message));

        Assert.StartsWith(@"The required antiforgery cookie token must be provided.", ex.Message);
    }
    public void TryValidateTokenSet_Success_AuthenticatedUserWithUsername()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var identity    = GetAuthenticatedIdentity("the-user");

        httpContext.User = new ClaimsPrincipal(identity);

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            SecurityToken  = cookieToken.SecurityToken,
            Username       = "******",
            IsCookieToken  = false,
            AdditionalData = "some-additional-data"
        };

        var mockAdditionalDataProvider = new Mock <IAntiforgeryAdditionalDataProvider>();

        mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data"))
        .Returns(true);

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: new Mock <IClaimUidExtractor>().Object,
            additionalDataProvider: mockAdditionalDataProvider.Object);

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.True(result);
        Assert.Null(message);
    }
    public void TryValidateTokenSet_Success_ClaimsBasedUser()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var identity    = GetAuthenticatedIdentity("the-user");

        httpContext.User = new ClaimsPrincipal(identity);

        var cookieToken = new AntiforgeryToken()
        {
            IsCookieToken = true
        };
        var fieldtoken = new AntiforgeryToken()
        {
            SecurityToken = cookieToken.SecurityToken,
            IsCookieToken = false,
            ClaimUid      = new BinaryBlob(256)
        };

        var mockClaimUidExtractor = new Mock <IClaimUidExtractor>();

        mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is <ClaimsPrincipal>(c => c.Identity == identity)))
        .Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData()));

        var tokenProvider = new DefaultAntiforgeryTokenGenerator(
            claimUidExtractor: mockClaimUidExtractor.Object,
            additionalDataProvider: null);

        // Act
        string message;
        var    result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

        // Assert
        Assert.True(result);
        Assert.Null(message);
    }
        public void TryValidateTokenSet_UsernameMismatch(string identityUsername, string embeddedUsername)
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity(identityUsername);
            httpContext.User = new ClaimsPrincipal(identity);

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                Username = embeddedUsername,
                IsCookieToken = false
            };

            var mockClaimUidExtractor = new Mock<IClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is<ClaimsPrincipal>(c => c.Identity == identity)))
                                 .Returns((string)null);

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

            string expectedMessage =
                $"The provided antiforgery token was meant for user \"{embeddedUsername}\", " +
                $"but the current user is \"{identityUsername}\".";

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.False(result);
            Assert.Equal(expectedMessage, message);
        }
        public void TryValidateTokenSet_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                Username = "******",
                IsCookieToken = false,
                AdditionalData = "some-additional-data"
            };

            var mockAdditionalDataProvider = new Mock<IAntiforgeryAdditionalDataProvider>();
            mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data"))
                                      .Returns(true);

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: new Mock<IClaimUidExtractor>().Object,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.True(result);
            Assert.Null(message);
        }
        public void TryValidateTokenSet_Success_ClaimsBasedUser()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                IsCookieToken = false,
                ClaimUid = new BinaryBlob(256)
            };

            var mockClaimUidExtractor = new Mock<IClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is<ClaimsPrincipal>(c => c.Identity == identity)))
                                 .Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData()));

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.True(result);
            Assert.Null(message);
        }
        public void TryValidateTokenSet_FieldTokenMissing()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: null);

            // Act & Assert
            string message;
            var ex = Assert.Throws<ArgumentNullException>(
                () => tokenProvider.TryValidateTokenSet(httpContext, cookieToken, null, out message));

            var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine));
            Assert.Equal("The required antiforgery request token must be provided.", trimmed);
        }
        public void TryValidateTokenSet_FieldAndCookieTokensSwapped_FieldTokenDuplicated()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken() { IsCookieToken = false };

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: null);

            string expectedMessage =
                "Validation of the provided antiforgery token failed. " +
                "The cookie token and the request token were swapped.";

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, fieldtoken, fieldtoken, out message);

            // Assert
            Assert.False(result);
            Assert.Equal(expectedMessage, message);
        }
        public void TryValidateTokenSet_FieldAndCookieTokensHaveDifferentSecurityKeys()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken() { IsCookieToken = false };

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: null);

            string expectedMessage = "The antiforgery cookie token and request token do not match.";

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.False(result);
            Assert.Equal(expectedMessage, message);
        }
        public void TryValidateTokenSet_ClaimUidMismatch()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                IsCookieToken = false,
                ClaimUid = new BinaryBlob(256)
            };

            var differentToken = new BinaryBlob(256);
            var mockClaimUidExtractor = new Mock<IClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(It.Is<ClaimsPrincipal>(c => c.Identity == identity)))
                                 .Returns(Convert.ToBase64String(differentToken.GetData()));

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

            string expectedMessage =
                "The provided antiforgery token was meant for a different " +
                "claims-based user than the current user.";

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.False(result);
            Assert.Equal(expectedMessage, message);
        }
        public void TryValidateTokenSet_AdditionalDataRejected()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = new ClaimsIdentity();
            httpContext.User = new ClaimsPrincipal(identity);

            var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
            var fieldtoken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                Username = String.Empty,
                IsCookieToken = false,
                AdditionalData = "some-additional-data"
            };

            var mockAdditionalDataProvider = new Mock<IAntiforgeryAdditionalDataProvider>();
            mockAdditionalDataProvider
                .Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data"))
                .Returns(false);

            var tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            string expectedMessage = "The provided antiforgery token failed a custom data check.";

            // Act
            string message;
            var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message);

            // Assert
            Assert.False(result);
            Assert.Equal(expectedMessage, message);
        }