Example #1
1
        public void ValidateTokens_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            var identity = GetAuthenticatedIdentity("the-user");
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken = sessionToken.SecurityToken,
                Username = "******",
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

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

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

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
        public void ChecksSSL_Validate_Throws()
        {
            // Arrange
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Request.IsHttps)
                           .Returns(false);

            var config = new AntiForgeryOptions()
            {
                RequireSSL = true
            };

            var worker = new AntiForgeryWorker(
                config: config,
                serializer: null,
                tokenStore: null,
                generator: null,
                validator: null,
                htmlEncoder: new HtmlEncoder());

            // Act & assert
            var ex = Assert.Throws<InvalidOperationException>(
                         () => worker.Validate(mockHttpContext.Object, cookieToken: null, formToken: null));
            Assert.Equal(
                @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " +
                "but the current request is not an SSL request.",
                ex.Message);
        }
Example #3
0
        public void ValidateTokens_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            var            httpContext  = new Mock <HttpContext>().Object;
            ClaimsIdentity identity     = new GenericIdentity("the-user");
            var            sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken  = sessionToken.SecurityToken,
                Username       = "******",
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

            var mockAdditionalDataProvider = new Mock <IAntiForgeryAdditionalDataProvider>();

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

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

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
Example #4
0
        public void ValidateTokens_Success_ClaimsBasedUser()
        {
            // Arrange
            var            httpContext  = new Mock <HttpContext>().Object;
            ClaimsIdentity identity     = new GenericIdentity("the-user");
            var            sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken  = sessionToken.SecurityToken,
                IsSessionToken = false,
                ClaimUid       = new BinaryBlob(256)
            };

            var mockClaimUidExtractor = new Mock <IClaimUidExtractor>();

            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity))
            .Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData()));

            var config = new AntiForgeryOptions();

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

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
Example #5
0
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };

            var                httpContext       = new Mock <HttpContext>().Object;
            ClaimsIdentity     identity          = new MyAuthenticatedIdentityWithoutUsername();
            var                config            = new AntiForgeryOptions();
            IClaimUidExtractor claimUidExtractor = new Mock <IClaimUidExtractor>().Object;

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

            // Act & assert
            var ex =
                Assert.Throws <InvalidOperationException>(
                    () => tokenProvider.GenerateFormToken(httpContext, identity, cookieToken));

            Assert.Equal(
                "The provided identity of type " +
                "'Microsoft.AspNet.Mvc.Core.Test.TokenProviderTest+MyAuthenticatedIdentityWithoutUsername' " +
                "is marked IsAuthenticated = true but does not have a value for Name. " +
                "By default, the anti-forgery system requires that all authenticated identities have a unique Name. " +
                "If it is not possible to provide a unique Name for this identity, " +
                "consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider " +
                "or a custom type that can provide some form of unique identifier for the current user.",
                ex.Message);
        }
Example #6
0
        public void GenerateFormToken_AnonymousUser()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            var httpContext = new Mock<HttpContext>().Object;
            var mockIdentity = new Mock<ClaimsIdentity>();
            mockIdentity.Setup(o => o.IsAuthenticated)
                        .Returns(false);

            var config = new AntiForgeryOptions();

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, mockIdentity.Object, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Empty(fieldToken.Username);
            Assert.Null(fieldToken.ClaimUid);
            Assert.Empty(fieldToken.AdditionalData);
        }
Example #7
0
        public void ValidateTokens_Success_AnonymousUser()
        {
            // Arrange
            var httpContext  = new Mock <HttpContext>().Object;
            var identity     = new ClaimsIdentity();
            var sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken  = sessionToken.SecurityToken,
                Username       = String.Empty,
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

            var mockAdditionalDataProvider = new Mock <IAntiForgeryAdditionalDataProvider>();

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

            var config        = new AntiForgeryOptions();
            var tokenProvider = new AntiForgeryTokenProvider(
                config: config,
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
Example #8
0
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };

            var httpContext = new Mock<HttpContext>().Object;
            ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername();
            var config = new AntiForgeryOptions();
            IClaimUidExtractor claimUidExtractor = new Mock<IClaimUidExtractor>().Object;

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

            // Act & assert
            var ex =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.GenerateFormToken(httpContext, identity, cookieToken));
            Assert.Equal(
                "The provided identity of type " +
                "'Microsoft.AspNet.Mvc.Core.Test.TokenProviderTest+MyAuthenticatedIdentityWithoutUsername' " +
                "is marked IsAuthenticated = true but does not have a value for Name. " +
                "By default, the anti-forgery system requires that all authenticated identities have a unique Name. " +
                "If it is not possible to provide a unique Name for this identity, " +
                "consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider " +
                "or a custom type that can provide some form of unique identifier for the current user.",
                ex.Message);
        }
Example #9
0
        public async Task ChecksSSL_ValidateAsync_Throws()
        {
            // Arrange
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Request.IsSecure)
                           .Returns(false);

            var config = new AntiForgeryOptions()
            {
                RequireSSL = true
            };

            var worker = new AntiForgeryWorker(
                config: config,
                serializer: null,
                tokenStore: null,
                generator: null,
                validator: null);

            // Act & assert
            var ex =
                await
                    Assert.ThrowsAsync<InvalidOperationException>(
                        async () => await worker.ValidateAsync(mockHttpContext.Object));
            Assert.Equal(
             @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " +
             "but the current request is not an SSL request.",
             ex.Message);
        }
Example #10
0
        public async Task ChecksSSL_ValidateAsync_Throws()
        {
            // Arrange
            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(o => o.Request.IsHttps)
            .Returns(false);

            var config = new AntiForgeryOptions()
            {
                RequireSSL = true
            };

            var worker = new AntiForgeryWorker(
                config: config,
                serializer: null,
                tokenStore: null,
                generator: null,
                validator: null,
                htmlEncoder: new HtmlEncoder());

            // Act & assert
            var ex =
                await
                Assert.ThrowsAsync <InvalidOperationException>(
                    async() => await worker.ValidateAsync(mockHttpContext.Object));

            Assert.Equal(
                @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " +
                "but the current request is not an SSL request.",
                ex.Message);
        }
        public void GetCookieToken_CookieIsMissingInRequest_LooksUpCookieInAntiForgeryContext()
        {
            // Arrange
            var requestCookies = new Mock<IReadableStringCollection>();
            requestCookies
                .Setup(o => o.Get(It.IsAny<string>()))
                .Returns(string.Empty);
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext
                .Setup(o => o.Request.Cookies)
                .Returns(requestCookies.Object);
            var contextAccessor = new ScopedInstance<AntiForgeryContext>();
            mockHttpContext.SetupGet(o => o.RequestServices)
                           .Returns(GetServiceProvider(contextAccessor));

            // add a cookie explicitly.
            var cookie = new AntiForgeryToken();
            contextAccessor.Value = new AntiForgeryContext() { CookieToken = cookie };
            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext.Object);

            // Assert
            Assert.Equal(cookie, token);
        }
        private AntiForgeryWorkerContext GetAntiForgeryWorkerContext(
            AntiForgeryOptions config,
            bool useOldCookie     = false,
            bool isOldCookieValid = true)
        {
            // Arrange
            var mockHttpContext = GetHttpContext();
            var testTokenSet    = GetTokenSet(isOldCookieTokenSessionToken: true, isNewCookieSessionToken: true);

            var mockSerializer = GetTokenSerializer(testTokenSet);

            var mockTokenStore    = GetTokenStore(mockHttpContext.Object, testTokenSet);
            var mockTokenProvider = GetTokenProvider(
                mockHttpContext.Object,
                testTokenSet,
                useOldCookie: useOldCookie,
                isOldCookieValid: isOldCookieValid);

            return(new AntiForgeryWorkerContext()
            {
                Options = config,
                HttpContext = mockHttpContext,
                TokenProvider = mockTokenProvider,
                TokenSerializer = mockSerializer,
                TokenStore = mockTokenStore,
                TestTokenSet = testTokenSet
            });
        }
Example #13
0
        public void GetFormInputElement_ExistingInvalidCookieToken_SwallowsExceptions()
        {
            // Arrange
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is invalid.
            var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false);
            var worker  = GetAntiForgeryWorker(context);

            // This will cause the cookieToken to be null.
            context.TokenStore.Setup(o => o.GetCookieToken(context.HttpContext.Object))
            .Throws(new Exception("should be swallowed"));

            // Setup so that the null cookie token returned is treated as invalid.
            context.TokenProvider.Setup(o => o.IsCookieTokenValid(null))
            .Returns(false);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                         inputElement.ToString(TagRenderMode.SelfClosing));
            context.TokenStore.Verify();
        }
Example #14
0
        public void ValidateTokens_AdditionalDataRejected()
        {
            // Arrange
            var            httpContext  = new Mock <HttpContext>().Object;
            ClaimsIdentity identity     = new GenericIdentity(String.Empty);
            var            sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken  = sessionToken.SecurityToken,
                Username       = String.Empty,
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

            var mockAdditionalDataProvider = new Mock <IAntiForgeryAdditionalDataProvider>();

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

            var config        = new AntiForgeryOptions();
            var tokenProvider = new TokenProvider(
                config: config,
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act & assert
            var ex =
                Assert.Throws <InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));

            Assert.Equal(@"The provided anti-forgery token failed a custom data check.", ex.Message);
        }
Example #15
0
        public void GetCookieToken_CookieIsValid_ReturnsToken()
        {
            // Arrange
            var expectedToken   = new AntiForgeryToken();
            var mockHttpContext = GetMockHttpContext(_cookieName, "valid-value");

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var mockSerializer = new Mock <IAntiForgeryTokenSerializer>();

            mockSerializer
            .Setup(o => o.Deserialize("valid-value"))
            .Returns(expectedToken);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            AntiForgeryToken retVal = tokenStore.GetCookieToken(mockHttpContext);

            // Assert
            Assert.Same(expectedToken, retVal);
        }
Example #16
0
        public void GetCookieToken_CookieDoesNotExist_ReturnsNull()
        {
            // Arrange
            var requestCookies = new Mock<IReadableStringCollection>();
            requestCookies
                .Setup(o => o.Get(It.IsAny<string>()))
                .Returns(string.Empty);
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext
                .Setup(o => o.Request.Cookies)
                .Returns(requestCookies.Object);
            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #17
0
        public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var            httpContext = new Mock <HttpContext>().Object;
            ClaimsIdentity identity    = new MyAuthenticatedIdentityWithoutUsername();

            var mockAdditionalDataProvider = new Mock <IAntiForgeryAdditionalDataProvider>();

            mockAdditionalDataProvider.Setup(o => o.GetAdditionalData(httpContext))
            .Returns("additional-data");

            var config = new AntiForgeryOptions();
            IClaimUidExtractor claimUidExtractor = new Mock <IClaimUidExtractor>().Object;

            var tokenProvider = new TokenProvider(
                config: config,
                claimUidExtractor: claimUidExtractor,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("", fieldToken.Username);
            Assert.Equal(null, fieldToken.ClaimUid);
            Assert.Equal("additional-data", fieldToken.AdditionalData);
        }
Example #18
0
        public void GenerateFormToken_AnonymousUser()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var httpContext  = new Mock <HttpContext>().Object;
            var mockIdentity = new Mock <ClaimsIdentity>();

            mockIdentity.Setup(o => o.IsAuthenticated)
            .Returns(false);

            var config = new AntiForgeryOptions();

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, mockIdentity.Object, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("", fieldToken.Username);
            Assert.Equal(null, fieldToken.ClaimUid);
            Assert.Equal("", fieldToken.AdditionalData);
        }
Example #19
0
        public void ValidateTokens_FieldTokenMissing()
        {
            // Arrange
            var            httpContext  = new Mock <HttpContext>().Object;
            ClaimsIdentity identity     = new Mock <ClaimsIdentity>().Object;
            var            sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            AntiForgeryToken fieldtoken = null;

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "my-form-field-name"
            };

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

            // Act & assert
            var ex =
                Assert.Throws <InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));

            Assert.Equal(@"The required anti-forgery form field ""my-form-field-name"" is not present.", ex.Message);
        }
Example #20
0
        public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = new Mock <HttpContext>();
            var requestContext  = new Mock <HttpRequest>();
            var formCollection  = new Mock <IFormCollection>();

            formCollection.Setup(f => f["form-field-name"]).Returns(string.Empty);
            requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None))
            .Returns(Task.FromResult(formCollection.Object));
            mockHttpContext.Setup(o => o.Request)
            .Returns(requestContext.Object);
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #21
0
        public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = new Mock <HttpContext>();
            var requestContext  = new Mock <HttpRequest>();
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary <string, string>()
            {
                { "form-field-name", string.Empty }
            });

            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
            .Returns(Task.FromResult(formsCollection));
            mockHttpContext.Setup(o => o.Request)
            .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #22
0
        public void GetCookieToken_CookieDoesNotExist_ReturnsNull()
        {
            // Arrange
            var requestCookies = new Mock <IReadableStringCollection>();

            requestCookies
            .Setup(o => o.Get(It.IsAny <string>()))
            .Returns(string.Empty);
            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext
            .Setup(o => o.Request.Cookies)
            .Returns(requestCookies.Object);
            var contextAccessor = new ContextAccessor <AntiForgeryContext>();

            mockHttpContext.SetupGet(o => o.RequestServices)
            .Returns(GetServiceProvider(contextAccessor));
            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #23
0
        public void GetCookieToken_CookieIsInvalid_PropagatesException()
        {
            // Arrange
            var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value");
            var config          = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var expectedException = new InvalidOperationException("some exception");
            var mockSerializer    = new Mock <IAntiForgeryTokenSerializer>();

            mockSerializer
            .Setup(o => o.Deserialize("invalid-value"))
            .Throws(expectedException);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act & assert
            var ex = Assert.Throws <InvalidOperationException>(() => tokenStore.GetCookieToken(mockHttpContext));

            Assert.Same(expectedException, ex);
        }
Example #24
0
        public void ChecksSSL_GetFormInputElement_Throws()
        {
            // Arrange
            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(o => o.Request.IsSecure)
            .Returns(false);

            var config = new AntiForgeryOptions()
            {
                RequireSSL = true
            };

            var worker = new AntiForgeryWorker(
                config: config,
                serializer: null,
                tokenStore: null,
                generator: null,
                validator: null);

            // Act & assert
            var ex = Assert.Throws <InvalidOperationException>(() => worker.GetFormInputElement(mockHttpContext.Object));

            Assert.Equal(
                @"The anti-forgery system has the configuration value AntiForgeryOptions.RequireSsl = true, " +
                "but the current request is not an SSL request.",
                ex.Message);
        }
        public void FormFieldName_SettingNullValue_Throws()
        {
            // Arrange
            var options = new AntiForgeryOptions();

            // Act & Assert
            var ex = Assert.Throws<ArgumentNullException>(() => options.FormFieldName = null);
            Assert.Equal("The 'FormFieldName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." +
                         Environment.NewLine + "Parameter name: value", ex.Message);
        }
        public void FormFieldName_SettingNullValue_Throws()
        {
            // Arrange
            var options = new AntiForgeryOptions();

            // Act & Assert
            var ex = Assert.Throws <ArgumentNullException>(() => options.FormFieldName = null);

            Assert.Equal("The 'FormFieldName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." +
                         Environment.NewLine + "Parameter name: value", ex.Message);
        }
Example #27
0
        /// <summary>
        /// Configures the anti-forgery tokens for better security. See:
        /// http://www.asp.net/mvc/overview/security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages
        /// </summary>
        /// <param name="antiForgeryOptions">The anti-forgery token options.</param>
        private static void ConfigureAntiforgeryTokens(AntiForgeryOptions antiForgeryOptions)
        {
            // Rename the Anti-Forgery cookie from "__RequestVerificationToken" to "f". This adds a little security
            // through obscurity and also saves sending a few characters over the wire.
            antiForgeryOptions.CookieName = "f";

            // Rename the form input name from "__RequestVerificationToken" to "f" for the same reason above e.g.
            // <input name="__RequestVerificationToken" type="hidden" value="..." />
            antiForgeryOptions.FormFieldName = "f";

            // If you have enabled SSL/TLS. Uncomment this line to ensure that the Anti-Forgery cookie requires SSL/TLS
            // to be sent across the wire.
            // antiForgeryOptions.RequireSSL = true;
        }
Example #28
0
        public void SaveCookieToken(bool requireSsl, bool?expectedCookieSecureFlag)
        {
            // Arrange
            var token       = new AntiForgeryToken();
            var mockCookies = new Mock <IResponseCookies>();

            // TODO : Once we decide on where to pick this value from enable this.
            bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor
            var  cookies = new MockResponseCookieCollection();

            cookies.Count = 0;
            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(o => o.Response.Cookies)
            .Returns(cookies);
            var contextAccessor = new ContextAccessor <AntiForgeryContext>();

            mockHttpContext.SetupGet(o => o.RequestServices)
            .Returns(GetServiceProvider(contextAccessor));

            var mockSerializer = new Mock <IAntiForgeryTokenSerializer>();

            mockSerializer.Setup(o => o.Serialize(token))
            .Returns("serialized-value");

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName,
                RequireSSL = requireSsl
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            tokenStore.SaveCookieToken(mockHttpContext.Object, token);

            // Assert
            Assert.Equal(1, cookies.Count);
            Assert.NotNull(contextAccessor.Value.CookieToken);
            Assert.NotNull(cookies);
            Assert.Equal(_cookieName, cookies.Key);
            Assert.Equal("serialized-value", cookies.Value);
            Assert.True(cookies.Options.HttpOnly);
            Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
        }
Example #29
0
        public void ValidateTokens_FieldAndSessionTokensSwapped()
        {
            // Arrange
            var            httpContext  = new Mock <HttpContext>().Object;
            ClaimsIdentity identity     = new Mock <ClaimsIdentity>().Object;
            var            sessionToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiForgeryToken()
            {
                IsSessionToken = false
            };

            var config = new AntiForgeryOptions()
            {
                CookieName    = "my-cookie-name",
                FormFieldName = "my-form-field-name"
            };

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

            // Act & assert
            var ex1 =
                Assert.Throws <InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, fieldtoken, fieldtoken));

            Assert.Equal(
                "Validation of the provided anti-forgery token failed. " +
                @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
                ex1.Message);

            var ex2 =
                Assert.Throws <InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, sessionToken));

            Assert.Equal(
                "Validation of the provided anti-forgery token failed. " +
                @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
                ex2.Message);
        }
Example #30
0
        public void GetFormInputElement_ExistingValidCookieToken_GeneratesAnAntiForgeryToken()
        {
            // Arrange
            var options = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is valid and use the same cookie for the mock Token Provider.
            var context = GetAntiForgeryWorkerContext(options, useOldCookie: true, isOldCookieValid: true);
            var worker  = GetAntiForgeryWorker(context);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                         inputElement.ToString(TagRenderMode.SelfClosing));
        }
Example #31
0
        public async Task GetFormToken_FormFieldIsInvalid_PropagatesException()
        {
            // Arrange
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary <string, string>()
            {
                { "form-field-name", "invalid-value" }
            });

            var requestContext = new Mock <HttpRequest>();

            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
            .Returns(Task.FromResult(formsCollection));

            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(o => o.Request)
            .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var expectedException = new InvalidOperationException("some exception");
            var mockSerializer    = new Mock <IAntiForgeryTokenSerializer>();

            mockSerializer.Setup(o => o.Deserialize("invalid-value"))
            .Throws(expectedException);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act & assert
            var ex =
                await
                Assert.ThrowsAsync <InvalidOperationException>(
                    async() => await tokenStore.GetFormTokenAsync(mockHttpContext.Object));

            Assert.Same(expectedException, ex);
        }
Example #32
0
        public void GetFormInputElement_ExistingInvalidCookieToken_GeneratesANewCookieAndAnAntiForgeryToken()
        {
            // Arrange
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is invalid.
            var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false);
            var worker  = GetAntiForgeryWorker(context);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                         inputElement.ToString(TagRenderMode.SelfClosing));
            context.TokenStore.Verify();
        }
Example #33
0
        public void GetCookieToken_CookieIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = GetMockHttpContext(_cookieName, string.Empty);

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext);

            // Assert
            Assert.Null(token);
        }
Example #34
0
        public void GetCookieToken_CookieIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = GetMockHttpContext(_cookieName, string.Empty);

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext);

            // Assert
            Assert.Null(token);
        }
Example #35
0
        public void SetCookieTokenAndHeader_AddsXFrameOptionsHeader(bool suppressXFrameOptions, string expectedHeaderValue)
        {
            // Arrange
            var options = new AntiForgeryOptions()
            {
                SuppressXFrameOptionsHeader = suppressXFrameOptions
            };

            // Genreate a new cookie.
            var context = GetAntiForgeryWorkerContext(options, useOldCookie: false, isOldCookieValid: false);
            var worker  = GetAntiForgeryWorker(context);

            // Act
            worker.SetCookieTokenAndHeader(context.HttpContext.Object);

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

            Assert.Equal(expectedHeaderValue, xFrameOptions);
        }
Example #36
0
        public void GenerateFormToken_ClaimsBasedIdentity()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };
            var httpContext = new Mock <HttpContext>().Object;
            var identity    = GetAuthenticatedIdentity("some-identity");

            var config = new AntiForgeryOptions();

            byte[] data = new byte[256 / 8];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(data);
            }
            var base64ClaimUId   = Convert.ToBase64String(data);
            var expectedClaimUid = new BinaryBlob(256, data);

            var mockClaimUidExtractor = new Mock <IClaimUidExtractor>();

            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity))
            .Returns(base64ClaimUId);

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("", fieldToken.Username);
            Assert.Equal(expectedClaimUid, fieldToken.ClaimUid);
            Assert.Equal("", fieldToken.AdditionalData);
        }
Example #37
0
        public void GetCookieToken_CookieIsMissingInRequest_LooksUpCookieInAntiForgeryContext()
        {
            // Arrange
            var requestCookies = new Mock <IReadableStringCollection>();

            requestCookies
            .Setup(o => o.Get(It.IsAny <string>()))
            .Returns(string.Empty);
            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext
            .Setup(o => o.Request.Cookies)
            .Returns(requestCookies.Object);
            var contextAccessor = new ContextAccessor <AntiForgeryContext>();

            mockHttpContext.SetupGet(o => o.RequestServices)
            .Returns(GetServiceProvider(contextAccessor));

            // add a cookie explicitly.
            var cookie = new AntiForgeryToken();

            contextAccessor.SetValue(new AntiForgeryContext()
            {
                CookieToken = cookie
            });
            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = tokenStore.GetCookieToken(mockHttpContext.Object);

            // Assert
            Assert.Equal(cookie, token);
        }
Example #38
0
        public async Task GetFormToken_FormFieldIsValid_ReturnsToken()
        {
            // Arrange
            var expectedToken = new AntiForgeryToken();

            // Arrange
            var mockHttpContext = new Mock <HttpContext>();
            var requestContext  = new Mock <HttpRequest>();
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary <string, string>()
            {
                { "form-field-name", "valid-value" }
            });

            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
            .Returns(Task.FromResult(formsCollection));
            mockHttpContext.Setup(o => o.Request)
            .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var mockSerializer = new Mock <IAntiForgeryTokenSerializer>();

            mockSerializer.Setup(o => o.Deserialize("valid-value"))
            .Returns(expectedToken);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            var retVal = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Same(expectedToken, retVal);
        }
Example #39
0
        public void GetCookieToken_CookieIsInvalid_PropagatesException()
        {
            // Arrange
            var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value");
            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var expectedException = new InvalidOperationException("some exception");
            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer
                .Setup(o => o.Deserialize("invalid-value"))
                .Throws(expectedException);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act & assert
            var ex = Assert.Throws<InvalidOperationException>(() => tokenStore.GetCookieToken(mockHttpContext));
            Assert.Same(expectedException, ex);
        }
        public void SetCookieTokenAndHeader_AddsXFrameOptionsHeader(bool suppressXFrameOptions, string expectedHeaderValue)
        {
            // Arrange
            var options = new AntiForgeryOptions()
            {
                SuppressXFrameOptionsHeader = suppressXFrameOptions
            };

            // Genreate a new cookie.
            var context = GetAntiForgeryWorkerContext(options, useOldCookie: false, isOldCookieValid: false);
            var worker = GetAntiForgeryWorker(context);

            // Act
            worker.SetCookieTokenAndHeader(context.HttpContext.Object);

            // Assert
            var xFrameOptions = context.HttpContext.Object.Response.Headers["X-Frame-Options"];
            Assert.Equal(expectedHeaderValue, xFrameOptions);
        }
        private AntiForgeryWorkerContext GetAntiForgeryWorkerContext(AntiForgeryOptions config, bool useOldCookie = false, bool isOldCookieValid = true)
        {
            // Arrange
            var mockHttpContext = GetHttpContext();
            var testTokenSet = GetTokenSet(isOldCookieTokenSessionToken: true, isNewCookieSessionToken: true);

            var mockSerializer = GetTokenSerializer(testTokenSet);

            var mockTokenStore = GetTokenStore(mockHttpContext.Object, testTokenSet);
            var mockTokenProvider = GetTokenProvider(mockHttpContext.Object, testTokenSet, useOldCookie: useOldCookie, isOldCookieValid: isOldCookieValid);

            return new AntiForgeryWorkerContext()
            {
                Options = config,
                HttpContext = mockHttpContext,
                TokenProvider = mockTokenProvider,
                TokenSerializer = mockSerializer,
                TokenStore = mockTokenStore,
                TestTokenSet = testTokenSet
            };
        }
        public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = new Mock<HttpContext>();
            var requestContext = new Mock<HttpRequest>();
            var formCollection = new Mock<IFormCollection>();
            formCollection.Setup(f => f["form-field-name"]).Returns(string.Empty);
            requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None))
                          .Returns(Task.FromResult(formCollection.Object));
            mockHttpContext.Setup(o => o.Request)
                           .Returns(requestContext.Object);
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #43
0
        public void ValidateTokens_Success_AnonymousUser()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            var identity = new ClaimsIdentity();
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken = sessionToken.SecurityToken,
                Username = String.Empty,
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

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

            var config = new AntiForgeryOptions();
            var tokenProvider = new TokenProvider(
                config: config,
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
Example #44
0
        public void GetCookieToken_CookieIsValid_ReturnsToken()
        {
            // Arrange
            var expectedToken = new AntiForgeryToken();
            var mockHttpContext = GetMockHttpContext(_cookieName, "valid-value");

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName
            };

            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer
                .Setup(o => o.Deserialize("valid-value"))
                .Returns(expectedToken);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            AntiForgeryToken retVal = tokenStore.GetCookieToken(mockHttpContext);

            // Assert
            Assert.Same(expectedToken, retVal);
        }
        public void GetFormInputElement_ExistingInvalidCookieToken_GeneratesANewCookieAndAnAntiForgeryToken()
        {
            // Arrange
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is invalid.
            var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false);
            var worker = GetAntiForgeryWorker(context);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                inputElement.ToString(TagRenderMode.SelfClosing));
            context.TokenStore.Verify();
        }
        public void GetFormInputElement_ExistingInvalidCookieToken_SwallowsExceptions()
        {
            // Arrange
            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is invalid.
            var context = GetAntiForgeryWorkerContext(config, isOldCookieValid: false);
            var worker = GetAntiForgeryWorker(context);

            // This will cause the cookieToken to be null.
            context.TokenStore.Setup(o => o.GetCookieToken(context.HttpContext.Object))
                              .Throws(new Exception("should be swallowed"));

            // Setup so that the null cookie token returned is treated as invalid.
            context.TokenProvider.Setup(o => o.IsCookieTokenValid(null))
                                 .Returns(false);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                inputElement.ToString(TagRenderMode.SelfClosing));
            context.TokenStore.Verify();
        }
Example #47
0
        public void ValidateTokens_FieldTokenMissing()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            ClaimsIdentity identity = new Mock<ClaimsIdentity>().Object;
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = null;

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "my-form-field-name"
            };

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

            // Act & assert
            var ex =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The required anti-forgery form field ""my-form-field-name"" is not present.", ex.Message);
        }
        public void GetFormInputElement_ExistingValidCookieToken_GeneratesAnAntiForgeryToken()
        {
            // Arrange
            var options = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            // Make sure the existing cookie is valid and use the same cookie for the mock Token Provider.
            var context = GetAntiForgeryWorkerContext(options, useOldCookie: true, isOldCookieValid: true);
            var worker = GetAntiForgeryWorker(context);

            // Act
            var inputElement = worker.GetFormInputElement(context.HttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />",
                inputElement.ToString(TagRenderMode.SelfClosing));
        }
Example #49
0
        public void GenerateFormToken_ClaimsBasedIdentity()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            var httpContext = new Mock<HttpContext>().Object;
            var identity = GetAuthenticatedIdentity("some-identity");

            var config = new AntiForgeryOptions();

            byte[] data = new byte[256 / 8];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(data);
            }
            var base64ClaimUId = Convert.ToBase64String(data);
            var expectedClaimUid = new BinaryBlob(256, data);

            var mockClaimUidExtractor = new Mock<IClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity))
                                 .Returns(base64ClaimUId);

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("", fieldToken.Username);
            Assert.Equal(expectedClaimUid, fieldToken.ClaimUid);
            Assert.Equal("", fieldToken.AdditionalData);
        }
Example #50
0
        public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag)
        {
            // Arrange
            var token = new AntiForgeryToken();
            var mockCookies = new Mock<IResponseCookies>();

            // TODO : Once we decide on where to pick this value from enable this.
            bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor
            var cookies = new MockResponseCookieCollection();

            cookies.Count = 0;
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Response.Cookies)
                           .Returns(cookies);

            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer.Setup(o => o.Serialize(token))
                          .Returns("serialized-value");

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName,
                RequireSSL = requireSsl
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            tokenStore.SaveCookieToken(mockHttpContext.Object, token);

            // Assert
            Assert.Equal(1, cookies.Count);

            Assert.NotNull(cookies);
            Assert.Equal(_cookieName, cookies.Key);
            Assert.Equal("serialized-value", cookies.Value);
            Assert.True(cookies.Options.HttpOnly);
            Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
        }
Example #51
0
        public void ValidateTokens_FieldAndSessionTokensSwapped()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            ClaimsIdentity identity = new Mock<ClaimsIdentity>().Object;
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiForgeryToken() { IsSessionToken = false };

            var config = new AntiForgeryOptions()
            {
                CookieName = "my-cookie-name",
                FormFieldName = "my-form-field-name"
            };

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

            // Act & assert
            var ex1 =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, fieldtoken, fieldtoken));
            Assert.Equal(
                "Validation of the provided anti-forgery token failed. " +
                @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
                ex1.Message);

            var ex2 =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, sessionToken));
            Assert.Equal(
                "Validation of the provided anti-forgery token failed. " +
                @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
                ex2.Message);
        }
Example #52
0
        public async Task GetFormToken_FormFieldIsValid_ReturnsToken()
        {
            // Arrange
            var expectedToken = new AntiForgeryToken();

            // Arrange
            var mockHttpContext = new Mock<HttpContext>();
            var requestContext = new Mock<HttpRequest>();
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary<string, string>() { { "form-field-name", "valid-value" } });
            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
                          .Returns(Task.FromResult(formsCollection));
            mockHttpContext.Setup(o => o.Request)
                           .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer.Setup(o => o.Deserialize("valid-value"))
                          .Returns(expectedToken);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            var retVal = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Same(expectedToken, retVal);
        }
Example #53
0
        public void ValidateTokens_AdditionalDataRejected()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            var identity = new ClaimsIdentity();
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken = sessionToken.SecurityToken,
                Username = String.Empty,
                IsSessionToken = false,
                AdditionalData = "some-additional-data"
            };

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

            var config = new AntiForgeryOptions();
            var tokenProvider = new AntiForgeryTokenProvider(
                config: config,
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act & assert
            var ex =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The provided anti-forgery token failed a custom data check.", ex.Message);
        }
Example #54
0
        public async Task GetFormToken_FormFieldIsInvalid_PropagatesException()
        {
            // Arrange
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary<string, string>() { { "form-field-name", "invalid-value" } });

            var requestContext = new Mock<HttpRequest>();
            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
                          .Returns(Task.FromResult(formsCollection));

            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Request)
                           .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var expectedException = new InvalidOperationException("some exception");
            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer.Setup(o => o.Deserialize("invalid-value"))
                          .Throws(expectedException);

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act & assert
            var ex =
                await
                    Assert.ThrowsAsync<InvalidOperationException>(
                        async () => await tokenStore.GetFormTokenAsync(mockHttpContext.Object));
            Assert.Same(expectedException, ex);
        }
Example #55
0
        public void ValidateTokens_Success_ClaimsBasedUser()
        {
            // Arrange
            var httpContext = new Mock<HttpContext>().Object;
            var identity = GetAuthenticatedIdentity("the-user");
            var sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiForgeryToken()
            {
                SecurityToken = sessionToken.SecurityToken,
                IsSessionToken = false,
                ClaimUid = new BinaryBlob(256)
            };

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

            var config = new AntiForgeryOptions();

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

            // Act
            tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken);

            // Assert
            // Nothing to assert - if we got this far, success!
        }
Example #56
0
        public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull()
        {
            // Arrange
            var mockHttpContext = new Mock<HttpContext>();
            var requestContext = new Mock<HttpRequest>();
            IReadableStringCollection formsCollection =
                new MockCookieCollection(new Dictionary<string, string>() { { "form-field-name", string.Empty } });
            requestContext.Setup(o => o.GetFormAsync(CancellationToken.None))
                          .Returns(Task.FromResult(formsCollection));
            mockHttpContext.Setup(o => o.Request)
                           .Returns(requestContext.Object);

            var config = new AntiForgeryOptions()
            {
                FormFieldName = "form-field-name"
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: null);

            // Act
            var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);

            // Assert
            Assert.Null(token);
        }
Example #57
0
        public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            var httpContext = new Mock<HttpContext>().Object;
            ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername();

            var mockAdditionalDataProvider = new Mock<IAntiForgeryAdditionalDataProvider>();
            mockAdditionalDataProvider.Setup(o => o.GetAdditionalData(httpContext))
                                      .Returns("additional-data");

            var config = new AntiForgeryOptions();
            IClaimUidExtractor claimUidExtractor = new Mock<IClaimUidExtractor>().Object;

            var tokenProvider = new AntiForgeryTokenProvider(
                config: config,
                claimUidExtractor: claimUidExtractor,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken);

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Empty(fieldToken.Username);
            Assert.Null(fieldToken.ClaimUid);
            Assert.Equal("additional-data", fieldToken.AdditionalData);
        }
        public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag)
        {
            // Arrange
            var token = new AntiForgeryToken();
            var mockCookies = new Mock<IResponseCookies>();

            bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor
            var cookies = new MockResponseCookieCollection();

            cookies.Count = 0;
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Response.Cookies)
                           .Returns(cookies);
            var contextAccessor = new ScopedInstance<AntiForgeryContext>();
            mockHttpContext.SetupGet(o => o.RequestServices)
                           .Returns(GetServiceProvider(contextAccessor));

            var mockSerializer = new Mock<IAntiForgeryTokenSerializer>();
            mockSerializer.Setup(o => o.Serialize(token))
                          .Returns("serialized-value");

            var config = new AntiForgeryOptions()
            {
                CookieName = _cookieName,
                RequireSSL = requireSsl
            };

            var tokenStore = new AntiForgeryTokenStore(
                config: config,
                serializer: mockSerializer.Object);

            // Act
            tokenStore.SaveCookieToken(mockHttpContext.Object, token);

            // Assert
            Assert.Equal(1, cookies.Count);
            Assert.NotNull(contextAccessor.Value.CookieToken);
            Assert.NotNull(cookies);
            Assert.Equal(_cookieName, cookies.Key);
            Assert.Equal("serialized-value", cookies.Value);
            Assert.True(cookies.Options.HttpOnly);
            Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
        }