public void Serialize_FieldToken_WithClaimUid()
        {
            // Arrange
            const string expectedSerializedData =
                "01" // Version
                + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
                + "00" // IsSessionToken
                + "01" // IsClaimsBased
                + "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid
                + "05" // AdditionalData length header
                + "E282AC3437"; // AdditionalData ("€47") as UTF8

            AntiForgeryToken token = new AntiForgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = false,
                ClaimUid = _claimUid,
                AdditionalData = "€47"
            };

            // Act & assert - serialization
            string actualSerializedData = _testSerializer.Serialize(token);
            Assert.Equal(expectedSerializedData, actualSerializedData);

            // Act & assert - deserialization
            AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
            AssertTokensEqual(token, deserializedToken);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData_SuppressHeuristics()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new MyAuthenticatedIdentityWithoutUsername();

            IAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                SuppressIdentityHeuristicChecks = true
            };
            IClaimUidExtractor claimUidExtractor = new Mock<MockableClaimUidExtractor>().Object;

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: claimUidExtractor);

            // Act
            var fieldToken = validator.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("", fieldToken.AdditionalData);
        }
        public void GenerateFormToken_AnonymousUser()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            Mock<IIdentity> mockIdentity = new Mock<IIdentity>();
            mockIdentity.Setup(o => o.IsAuthenticated).Returns(false);

            IAntiForgeryConfig config = new MockAntiForgeryConfig();

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: null);

            // Act
            var fieldToken = validator.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);
        }
Пример #4
0
        // copy constructor
        public AntiForgeryToken(AntiForgeryToken token) {
            if (token == null) {
                throw new ArgumentNullException("token");
            }

            CreationDate = token.CreationDate;
            Salt = token.Salt;
            Value = token.Value;
        }
        // copy constructor
        public AntiForgeryToken(AntiForgeryToken token)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            CreationDate = token.CreationDate;
            Salt         = token.Salt;
            Value        = token.Value;
        }
        public virtual string Serialize(AntiForgeryToken token) {
            if (token == null) {
                throw new ArgumentNullException("token");
            }

            Triplet objToSerialize = new Triplet() {
                First = token.Salt,
                Second = token.Value,
                Third = token.CreationDate
            };

            string serializedValue = Formatter.Serialize(objToSerialize);
            return serializedValue;
        }
        public void GetFormInputElement_ExistingInvalidCookieToken()
        {
            // Arrange
            GenericIdentity identity = new GenericIdentity("some-user");
            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));

            Mock<HttpResponseBase> mockResponse = new Mock<HttpResponseBase>();
            mockResponse.Setup(r => r.Headers).Returns(new NameValueCollection());
            mockHttpContext.Setup(o => o.Response).Returns(mockResponse.Object);

            AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken formToken = new AntiForgeryToken();

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

            Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
            mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");

            Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>(MockBehavior.Strict);
            mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(oldCookieToken);
            mockTokenStore.Setup(o => o.SaveCookieToken(mockHttpContext.Object, newCookieToken)).Verifiable();

            Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
            mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
            mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)).Returns(false);
            mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
            mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);

            AntiForgeryWorker worker = new AntiForgeryWorker(
                config: config,
                serializer: mockSerializer.Object,
                tokenStore: mockTokenStore.Object,
                validator: mockValidator.Object);

            // Act
            TagBuilder retVal = worker.GetFormInputElement(mockHttpContext.Object);

            // Assert
            Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />", retVal.ToString(TagRenderMode.SelfClosing));
            mockTokenStore.Verify();
        }
Пример #8
0
        public virtual string Serialize(AntiForgeryToken token)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }

            Triplet objToSerialize = new Triplet()
            {
                First  = token.Salt,
                Second = token.Value,
                Third  = token.CreationDate
            };

            string serializedValue = Formatter.Serialize(objToSerialize);

            return(serializedValue);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };

            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new MyAuthenticatedIdentityWithoutUsername();
            IAntiForgeryConfig config = new MockAntiForgeryConfig();
            IClaimUidExtractor claimUidExtractor = new Mock<MockableClaimUidExtractor>().Object;

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: claimUidExtractor);

            // Act & assert
            var ex = Assert.Throws<InvalidOperationException>(() => validator.GenerateFormToken(httpContext, identity, cookieToken));
            Assert.Equal(@"The provided identity of type 'System.Web.Helpers.AntiXsrf.Test.TokenValidatorTest+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 setting the static property AntiForgeryConfig.AdditionalDataProvider to an instance of a type that can provide some form of unique identifier for the current user.", ex.Message);
        }
        public void GetTokens_ExistingValidCookieToken()
        {
            // Arrange
            GenericIdentity identity = new GenericIdentity("some-user");
            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));

            AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken formToken = new AntiForgeryToken();

            Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
            mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token")).Returns(cookieToken);
            mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");

            Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
            mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, cookieToken)).Returns(formToken);
            mockValidator.Setup(o => o.IsCookieTokenValid(cookieToken)).Returns(true);

            AntiForgeryWorker worker = new AntiForgeryWorker(
                config: new MockAntiForgeryConfig(),
                serializer: mockSerializer.Object,
                tokenStore: null,
                validator: mockValidator.Object);

            // Act
            string serializedNewCookieToken, serializedFormToken;
            worker.GetTokens(mockHttpContext.Object, "serialized-old-cookie-token", out serializedNewCookieToken, out serializedFormToken);

            // Assert
            Assert.Null(serializedNewCookieToken);
            Assert.Equal("serialized-form-token", serializedFormToken);
        }
        public void GetFormInputElement_AddsXFrameOptionsHeader(bool suppressXFrameOptions, string expectedHeaderValue)
        {
            // Arrange
            GenericIdentity identity = new GenericIdentity("some-user");
            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));

            NameValueCollection headers = new NameValueCollection();
            Mock<HttpResponseBase> mockResponse = new Mock<HttpResponseBase>();
            mockResponse.Setup(r => r.Headers).Returns(headers);
            mockResponse.Setup(r => r.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((k, v) =>
            {
                headers.Add(k, v);
            });
            mockHttpContext.Setup(o => o.Response).Returns(mockResponse.Object);

            AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken formToken = new AntiForgeryToken();

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                FormFieldName = "form-field-name",
                SuppressXFrameOptionsHeader = suppressXFrameOptions
            };

            Mock<MockableAntiForgeryTokenSerializer> mockSerializer = new Mock<MockableAntiForgeryTokenSerializer>(MockBehavior.Strict);
            mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token");

            Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>(MockBehavior.Strict);
            mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(oldCookieToken);
            mockTokenStore.Setup(o => o.SaveCookieToken(mockHttpContext.Object, newCookieToken)).Verifiable();

            Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>(MockBehavior.Strict);
            mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken);
            mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)).Returns(false);
            mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true);
            mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken);

            AntiForgeryWorker worker = new AntiForgeryWorker(
                config: config,
                serializer: mockSerializer.Object,
                tokenStore: mockTokenStore.Object,
                validator: mockValidator.Object);
            HttpContextBase context = mockHttpContext.Object;

            // Act
            TagBuilder retVal = worker.GetFormInputElement(context);

            // Assert
            string xFrameOptions = context.Response.Headers["X-FRAME-OPTIONS"];
            Assert.Equal(expectedHeaderValue, xFrameOptions);
        }
        public void GetFormToken_FormFieldIsValid_ReturnsToken()
        {
            // Arrange
            AntiForgeryToken expectedToken = new AntiForgeryToken();

            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.Request.Form.Get("form-field-name")).Returns("valid-value");

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

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

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

            // Act
            AntiForgeryToken retVal = tokenStore.GetFormToken(mockHttpContext.Object);

            // Assert
            Assert.Same(expectedToken, retVal);
        }
        public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag)
        {
            // Arrange
            AntiForgeryToken token = new AntiForgeryToken();
            HttpCookieCollection cookies = new HttpCookieCollection();
            bool defaultCookieSecureValue = expectedCookieSecureFlag ?? new HttpCookie("name", "value").Secure; // pulled from config; set by ctor

            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.Response.Cookies).Returns(cookies);

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

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                CookieName = "cookie-name",
                RequireSSL = requireSsl
            };

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

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

            // Assert
            Assert.Equal(1, cookies.Count);
            HttpCookie cookie = cookies["cookie-name"];

            Assert.NotNull(cookie);
            Assert.Equal("serialized-value", cookie.Value);
            Assert.True(cookie.HttpOnly);
            Assert.Equal(defaultCookieSecureValue, cookie.Secure);
        }
        public void IsCookieTokenValid_ValidToken_ReturnsTrue()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken()
            {
                IsSessionToken = true
            };

            TokenValidator validator = new TokenValidator(
                config: null,
                claimUidExtractor: null);

            // Act
            bool retVal = validator.IsCookieTokenValid(cookieToken);

            // Assert
            Assert.True(retVal);
        }
        public void GetCookieToken_CookieIsValid_ReturnsToken()
        {
            // Arrange
            AntiForgeryToken expectedToken = new AntiForgeryToken();

            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.Request.Cookies).Returns(new HttpCookieCollection()
            {
                new HttpCookie("cookie-name", "valid-value")
            });

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                CookieName = "cookie-name"
            };

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

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

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

            // Assert
            Assert.Same(expectedToken, retVal);
        }
        public void Serialize_SessionToken()
        {
            // Arrange
            const string expectedSerializedData =
                "01" // Version
                + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
                + "01"; // IsSessionToken

            AntiForgeryToken token = new AntiForgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = true
            };

            // Act & assert - serialization
            string actualSerializedData = _testSerializer.Serialize(token);
            Assert.Equal(expectedSerializedData, actualSerializedData);

            // Act & assert - deserialization
            AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
            AssertTokensEqual(token, deserializedToken);
        }
        public void ValidateTokens_UsernameMismatch(string identityUsername, string embeddedUsername)
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new GenericIdentity(identityUsername);
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = embeddedUsername, IsSessionToken = false };

            Mock<MockableClaimUidExtractor> mockClaimUidExtractor = new Mock<MockableClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)).Returns((object)null);

            TokenValidator validator = new TokenValidator(
                config: null,
                claimUidExtractor: mockClaimUidExtractor.Object);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The provided anti-forgery token was meant for user """ + embeddedUsername + @""", but the current user is """ + identityUsername + @""".", ex.Message);
        }
        public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new Mock<IIdentity>().Object;
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { IsSessionToken = false };

            TokenValidator validator = new TokenValidator(
                config: null,
                claimUidExtractor: null);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The anti-forgery cookie token and form field token do not match.", ex.Message);
        }
        public void ValidateTokens_FieldAndSessionTokensSwapped()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new Mock<IIdentity>().Object;
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { IsSessionToken = false };

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                CookieName = "my-cookie-name",
                FormFieldName = "my-form-field-name"
            };
            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: null);

            // Act & assert
            var ex1 = Assert.Throws<HttpAntiForgeryException>(() => validator.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<HttpAntiForgeryException>(() => validator.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);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new MyAuthenticatedIdentityWithoutUsername();

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

            IAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                AdditionalDataProvider = mockAdditionalDataProvider.Object
            };
            IClaimUidExtractor claimUidExtractor = new Mock<MockableClaimUidExtractor>().Object;

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: claimUidExtractor);

            // Act
            var fieldToken = validator.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);
        }
        public void ValidateTokens_FieldTokenMissing()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new Mock<IIdentity>().Object;
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = null;

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                FormFieldName = "my-form-field-name"
            };
            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: null);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The required anti-forgery form field ""my-form-field-name"" is not present.", ex.Message);
        }
        public void Validate_FromStore_Failure()
        {
            // Arrange
            GenericIdentity identity = new GenericIdentity("some-user");
            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));

            AntiForgeryToken cookieToken = new AntiForgeryToken();
            AntiForgeryToken formToken = new AntiForgeryToken();

            Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>();
            mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(cookieToken);
            mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken);

            Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
            mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Throws(new HttpAntiForgeryException("my-message"));

            AntiForgeryWorker worker = new AntiForgeryWorker(
                config: new MockAntiForgeryConfig(),
                serializer: null,
                tokenStore: mockTokenStore.Object,
                validator: mockValidator.Object);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => worker.Validate(mockHttpContext.Object));
            Assert.Equal("my-message", ex.Message);
        }
        public void Validate_FromStore_Success()
        {
            // Arrange
            GenericIdentity identity = new GenericIdentity("some-user");
            Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
            mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0]));

            AntiForgeryToken cookieToken = new AntiForgeryToken();
            AntiForgeryToken formToken = new AntiForgeryToken();

            Mock<MockableTokenStore> mockTokenStore = new Mock<MockableTokenStore>();
            mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(cookieToken);
            mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken);

            Mock<MockableTokenValidator> mockValidator = new Mock<MockableTokenValidator>();
            mockValidator.Setup(o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken)).Verifiable();

            AntiForgeryWorker worker = new AntiForgeryWorker(
                config: new MockAntiForgeryConfig(),
                serializer: null,
                tokenStore: mockTokenStore.Object,
                validator: mockValidator.Object);

            // Act
            worker.Validate(mockHttpContext.Object);

            // Assert
            mockValidator.Verify();
        }
        public void ValidateTokens_Success_ClaimsBasedUser()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new GenericIdentity("the-user");
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, IsSessionToken = false, ClaimUid = new BinaryBlob(256) };

            Mock<MockableClaimUidExtractor> mockClaimUidExtractor = new Mock<MockableClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)).Returns(fieldtoken.ClaimUid);

            MockAntiForgeryConfig config = new MockAntiForgeryConfig();

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: mockClaimUidExtractor.Object);

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

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

            Mock<MockableClaimUidExtractor> mockClaimUidExtractor = new Mock<MockableClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)).Returns(new BinaryBlob(256));

            TokenValidator validator = new TokenValidator(
                config: null,
                claimUidExtractor: mockClaimUidExtractor.Object);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The provided anti-forgery token was meant for a different claims-based user than the current user.", ex.Message);
        }
        public void GenerateFormToken_ClaimsBasedIdentity()
        {
            // Arrange
            AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true };
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new GenericIdentity("some-identity");

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                UniqueClaimTypeIdentifier = "unique-identifier"
            };

            BinaryBlob expectedClaimUid = new BinaryBlob(256);
            Mock<MockableClaimUidExtractor> mockClaimUidExtractor = new Mock<MockableClaimUidExtractor>();
            mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)).Returns((object)expectedClaimUid);

            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: mockClaimUidExtractor.Object);

            // Act
            var fieldToken = validator.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);
        }
 private static void AssertTokensEqual(AntiForgeryToken expected, AntiForgeryToken actual)
 {
     Assert.NotNull(expected);
     Assert.NotNull(actual);
     Assert.Equal(expected.AdditionalData, actual.AdditionalData);
     Assert.Equal(expected.ClaimUid, actual.ClaimUid);
     Assert.Equal(expected.IsSessionToken, actual.IsSessionToken);
     Assert.Equal(expected.SecurityToken, actual.SecurityToken);
     Assert.Equal(expected.Username, actual.Username);
 }
        public void ValidateTokens_AdditionalDataRejected()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new GenericIdentity(String.Empty);
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = String.Empty, IsSessionToken = false, AdditionalData = "some-additional-data" };

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

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                AdditionalDataProvider = mockAdditionalDataProvider.Object
            };
            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: null);

            // Act & assert
            var ex = Assert.Throws<HttpAntiForgeryException>(() => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken));
            Assert.Equal(@"The provided anti-forgery token failed a custom data check.", ex.Message);
        }
        public void Serialize_FieldToken_WithUsername()
        {
            // Arrange
            const string expectedSerializedData =
                "01" // Version
                + "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
                + "00" // IsSessionToken
                + "00" // IsClaimsBased
                + "08" // Username length header
                + "4AC3A972C3B46D65" // Username ("Jérôme") as UTF8
                + "05" // AdditionalData length header
                + "E282AC3437"; // AdditionalData ("€47") as UTF8

            AntiForgeryToken token = new AntiForgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = false,
                Username = "******",
                AdditionalData = "€47"
            };

            // Act & assert - serialization
            string actualSerializedData = _testSerializer.Serialize(token);
            Assert.Equal(expectedSerializedData, actualSerializedData);

            // Act & assert - deserialization
            AntiForgeryToken deserializedToken = _testSerializer.Deserialize(actualSerializedData);
            AssertTokensEqual(token, deserializedToken);
        }
        public void ValidateTokens_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            HttpContextBase httpContext = new Mock<HttpContextBase>().Object;
            IIdentity identity = new GenericIdentity("the-user");
            AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true };
            AntiForgeryToken fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = "******", IsSessionToken = false, AdditionalData = "some-additional-data" };

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

            MockAntiForgeryConfig config = new MockAntiForgeryConfig()
            {
                AdditionalDataProvider = mockAdditionalDataProvider.Object
            };
            TokenValidator validator = new TokenValidator(
                config: config,
                claimUidExtractor: new Mock<MockableClaimUidExtractor>().Object);

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

            // Assert
            // Nothing to assert - if we got this far, success!
        }