public void SetCookieTokenAndHeader_PreserveXFrameOptionsHeader()
        {
            // Arrange
            var options             = new AntiforgeryOptions();
            var antiforgeryFeature  = new AntiforgeryFeature();
            var expectedHeaderValue = "DIFFERENTORIGIN";

            // Generate a new cookie.
            var context = CreateMockContext(
                options,
                useOldCookie: false,
                isOldCookieValid: false,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            context.HttpContext.Response.Headers["X-Frame-Options"] = expectedHeaderValue;

            // Act
            antiforgery.SetCookieTokenAndHeader(context.HttpContext);

            // Assert
            var xFrameOptions = context.HttpContext.Response.Headers["X-Frame-Options"];

            Assert.Equal(expectedHeaderValue, xFrameOptions);
        }
        public void SetCookieTokenAndHeader_NullCookieToken()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature
            {
                HaveDeserializedCookieToken = false,
                HaveGeneratedNewCookieToken = false,
                HaveStoredNewCookieToken    = true,
                NewCookieToken        = new AntiforgeryToken(),
                NewCookieTokenString  = "serialized-cookie-token-from-context",
                NewRequestToken       = new AntiforgeryToken(),
                NewRequestTokenString = "serialized-form-token-from-context",
            };
            var context = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: false,
                isOldCookieValid: false,
                antiforgeryFeature: antiforgeryFeature);
            var testTokenSet = new TestTokenSet
            {
                OldCookieTokenString = null
            };

            var nullTokenStore = GetTokenStore(context.HttpContext, testTokenSet, false);
            var antiforgery    = GetAntiforgery(
                context.HttpContext,
                tokenGenerator: context.TokenGenerator.Object,
                tokenStore: nullTokenStore.Object);

            // Act
            antiforgery.SetCookieTokenAndHeader(context.HttpContext);

            // Assert
            context.TokenSerializer.Verify(s => s.Deserialize(null), Times.Never);
        }
        public void SetCookieTokenAndHeader_AddsXFrameOptionsHeader(
            bool suppressXFrameOptions,
            string expectedHeaderValue)
        {
            // Arrange
            var options = new AntiforgeryOptions()
            {
                SuppressXFrameOptionsHeader = suppressXFrameOptions
            };
            var antiforgeryFeature = new AntiforgeryFeature();

            // Generate a new cookie.
            var context = CreateMockContext(
                options,
                useOldCookie: false,
                isOldCookieValid: false,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            // Act
            antiforgery.SetCookieTokenAndHeader(context.HttpContext);

            // Assert
            var xFrameOptions = context.HttpContext.Response.Headers["X-Frame-Options"];

            Assert.Equal(expectedHeaderValue, xFrameOptions);

            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken);
            Assert.Equal(context.TestTokenSet.NewCookieToken, antiforgeryFeature.NewCookieToken);
            Assert.Equal(context.TestTokenSet.NewCookieTokenString, antiforgeryFeature.NewCookieTokenString);
            Assert.True(antiforgeryFeature.HaveStoredNewCookieToken);
        }
        public async Task ValidateRequestAsync_FromStore_Failure()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);

            var message = "my-message";

            context.TokenGenerator
            .Setup(o => o.TryValidateTokenSet(
                       context.HttpContext,
                       context.TestTokenSet.OldCookieToken,
                       context.TestTokenSet.RequestToken,
                       out message))
            .Returns(false)
            .Verifiable();
            var antiforgery = GetAntiforgery(context);

            // Act & assert
            var exception = await Assert.ThrowsAsync <AntiforgeryValidationException>(
                () => antiforgery.ValidateRequestAsync(context.HttpContext));

            Assert.Equal("my-message", exception.Message);
            context.TokenGenerator.Verify();

            // Failed _after_ updating the AntiforgeryContext.
            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveDeserializedRequestToken);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken);
        }
        public async Task ValidateRequestAsync_FromStore_Success()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);

            string message;

            context.TokenGenerator
            .Setup(o => o.TryValidateTokenSet(
                       context.HttpContext,
                       context.TestTokenSet.OldCookieToken,
                       context.TestTokenSet.RequestToken,
                       out message))
            .Returns(true)
            .Verifiable();

            var antiforgery = GetAntiforgery(context);

            // Act
            await antiforgery.ValidateRequestAsync(context.HttpContext);

            // Assert
            context.TokenGenerator.Verify();

            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveDeserializedRequestToken);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken);
        }
        public async Task IsRequestValidAsync_FromStore_Failure()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);

            string message;

            context.TokenGenerator
            .Setup(o => o.TryValidateTokenSet(
                       context.HttpContext,
                       context.TestTokenSet.OldCookieToken,
                       context.TestTokenSet.RequestToken,
                       out message))
            .Returns(false);

            var antiforgery = GetAntiforgery(context);

            // Act
            var result = await antiforgery.IsRequestValidAsync(context.HttpContext);

            // Assert
            Assert.False(result);
            context.TokenGenerator.Verify();

            // Failed _after_ updating the AntiforgeryContext.
            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveDeserializedRequestToken);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken);
        }
        public void GetAndStoreTokens_NoExistingCookieToken_Saved()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: false,
                isOldCookieValid: false,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            // Act
            var tokenSet = antiforgery.GetAndStoreTokens(context.HttpContext);

            // Assert
            context.TokenStore.Verify(
                t => t.SaveCookieToken(It.IsAny <HttpContext>(), context.TestTokenSet.NewCookieTokenString),
                Times.Once);

            Assert.Equal(context.TestTokenSet.NewCookieTokenString, tokenSet.CookieToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, tokenSet.RequestToken);

            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken);
            Assert.Equal(context.TestTokenSet.NewCookieToken, antiforgeryFeature.NewCookieToken);
            Assert.Equal(context.TestTokenSet.NewCookieTokenString, antiforgeryFeature.NewCookieTokenString);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString);
            Assert.True(antiforgeryFeature.HaveStoredNewCookieToken);
        }
        public void GetAndStoreTokens_ExistingValidCookieToken_NotOverriden()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: true,
                isOldCookieValid: true,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            // Act
            var tokenSet = antiforgery.GetAndStoreTokens(context.HttpContext);

            // Assert
            // We shouldn't have saved the cookie because it already existed.
            context.TokenStore.Verify(
                t => t.SaveCookieToken(It.IsAny <HttpContext>(), It.IsAny <string>()),
                Times.Never);

            Assert.Null(tokenSet.CookieToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, tokenSet.RequestToken);

            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken);
            Assert.Null(antiforgeryFeature.NewCookieToken);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString);
        }
        public void GetTokens_DoesNotSerializeTwice()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature
            {
                HaveDeserializedCookieToken = true,
                HaveGeneratedNewCookieToken = true,
                NewRequestToken             = new AntiforgeryToken(),
                NewRequestTokenString       = "serialized-form-token-from-context",
            };
            var context = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: true,
                isOldCookieValid: true,
                antiforgeryFeature: antiforgeryFeature);

            var antiforgery = GetAntiforgery(context);

            // Act
            var tokenset = antiforgery.GetTokens(context.HttpContext);

            // Assert
            Assert.Null(tokenset.CookieToken);
            Assert.Equal("serialized-form-token-from-context", tokenset.RequestToken);

            Assert.Null(antiforgeryFeature.NewCookieToken);

            // Token serializer not used.
            context.TokenSerializer.Verify(
                o => o.Deserialize(It.IsAny <string>()),
                Times.Never);
            context.TokenSerializer.Verify(
                o => o.Serialize(It.IsAny <AntiforgeryToken>()),
                Times.Never);
        }
        public void GetTokens_ExistingValidCookieToken_GeneratesANewFormToken()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature();
            var context            = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: true,
                isOldCookieValid: true,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            // Act
            var tokenset = antiforgery.GetTokens(context.HttpContext);

            // Assert
            Assert.Null(tokenset.CookieToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, tokenset.RequestToken);

            Assert.NotNull(antiforgeryFeature);
            Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
            Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
            Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken);
            Assert.Null(antiforgeryFeature.NewCookieToken);
            Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken);
            Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString);
        }
        private static IAntiforgeryFeature GetAntiforgeryFeature(HttpContext httpContext)
        {
            var antiforgeryFeature = httpContext.Features.Get <IAntiforgeryFeature>();

            if (antiforgeryFeature == null)
            {
                antiforgeryFeature = new AntiforgeryFeature();
                httpContext.Features.Set(antiforgeryFeature);
            }

            return(antiforgeryFeature);
        }
        public void GetAndStoreTokens_DoesNotSerializeTwice()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature
            {
                HaveDeserializedCookieToken = true,
                HaveGeneratedNewCookieToken = true,
                NewCookieToken        = new AntiforgeryToken(),
                NewCookieTokenString  = "serialized-cookie-token-from-context",
                NewRequestToken       = new AntiforgeryToken(),
                NewRequestTokenString = "serialized-form-token-from-context",
            };
            var context = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: true,
                isOldCookieValid: true,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            context.TokenStore
            .Setup(t => t.SaveCookieToken(context.HttpContext, "serialized-cookie-token-from-context"))
            .Verifiable();

            // Act
            var tokenset = antiforgery.GetAndStoreTokens(context.HttpContext);

            // Assert
            // Token store used once, with expected arguments.
            // Passed context's cookie token though request's cookie token was valid.
            context.TokenStore.Verify(
                t => t.SaveCookieToken(context.HttpContext, "serialized-cookie-token-from-context"),
                Times.Once);

            // Token serializer not used.
            context.TokenSerializer.Verify(
                o => o.Deserialize(It.IsAny <string>()),
                Times.Never);
            context.TokenSerializer.Verify(
                o => o.Serialize(It.IsAny <AntiforgeryToken>()),
                Times.Never);

            Assert.Equal("serialized-cookie-token-from-context", tokenset.CookieToken);
            Assert.Equal("serialized-form-token-from-context", tokenset.RequestToken);

            Assert.True(antiforgeryFeature.HaveStoredNewCookieToken);
        }
        public async Task IsRequestValidAsync_DoesNotDeserializeTwice()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature
            {
                HaveDeserializedCookieToken = true,
                CookieToken = new AntiforgeryToken(),
                HaveDeserializedRequestToken = true,
                RequestToken = new AntiforgeryToken(),
            };
            var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);

            context.HttpContext.Request.Method = "POST";

            string message;

            context.TokenGenerator
            .Setup(o => o.TryValidateTokenSet(
                       context.HttpContext,
                       antiforgeryFeature.CookieToken,
                       antiforgeryFeature.RequestToken,
                       out message))
            .Returns(true)
            .Verifiable();

            var antiforgery = GetAntiforgery(context);

            // Act
            var result = await antiforgery.IsRequestValidAsync(context.HttpContext);

            // Assert
            Assert.True(result);
            context.TokenGenerator.Verify();

            // Token serializer not used.
            context.TokenSerializer.Verify(
                o => o.Deserialize(It.IsAny <string>()),
                Times.Never);
            context.TokenSerializer.Verify(
                o => o.Serialize(It.IsAny <AntiforgeryToken>()),
                Times.Never);
        }
        public void SetCookieTokenAndHeader_DoesNotStoreTwice()
        {
            // Arrange
            var antiforgeryFeature = new AntiforgeryFeature
            {
                HaveDeserializedCookieToken = true,
                HaveGeneratedNewCookieToken = true,
                HaveStoredNewCookieToken    = true,
                NewCookieToken        = new AntiforgeryToken(),
                NewCookieTokenString  = "serialized-cookie-token-from-context",
                NewRequestToken       = new AntiforgeryToken(),
                NewRequestTokenString = "serialized-form-token-from-context",
            };
            var context = CreateMockContext(
                new AntiforgeryOptions(),
                useOldCookie: true,
                isOldCookieValid: true,
                antiforgeryFeature: antiforgeryFeature);
            var antiforgery = GetAntiforgery(context);

            // Act
            antiforgery.SetCookieTokenAndHeader(context.HttpContext);

            // Assert
            // Token serializer not used.
            context.TokenSerializer.Verify(
                o => o.Deserialize(It.IsAny <string>()),
                Times.Never);
            context.TokenSerializer.Verify(
                o => o.Serialize(It.IsAny <AntiforgeryToken>()),
                Times.Never);

            // Token store not used.
            context.TokenStore.Verify(
                t => t.SaveCookieToken(It.IsAny <HttpContext>(), It.IsAny <string>()),
                Times.Never);
        }