public void GetCookieToken_CookieIsMissingInRequest_LooksUpCookieInAntiforgeryContext()
        {
            // Arrange
            var requestCookies = new Mock<IReadableStringCollection>();
            requestCookies
                .Setup(o => o[It.IsAny<string>()])
                .Returns(string.Empty);
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext
                .Setup(o => o.Request.Cookies)
                .Returns(requestCookies.Object);
            var contextAccessor = new DefaultAntiforgeryContextAccessor();
            mockHttpContext.SetupGet(o => o.RequestServices)
                           .Returns(GetServiceProvider(contextAccessor));

            // add a cookie explicitly.
            var cookie = new AntiforgeryToken();
            contextAccessor.Value = new AntiforgeryContext() { CookieToken = cookie };
            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(
                optionsAccessor: new TestOptionsManager(options),
                tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());

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

            // Assert
            Assert.Equal(cookie, token);
        }
Esempio n. 2
0
        public void ValidateTokens_FieldTokenMissing()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();

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

            var sessionToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

            var options = new AntiforgeryOptions()
            {
                FormFieldName = "my-form-field-name"
            };

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

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

            Assert.Equal(@"The required antiforgery form field ""my-form-field-name"" is not present.", ex.Message);
        }
Esempio n. 3
0
        public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
        {
            // Add the cookie to the request based context.
            // This is useful if the cookie needs to be reloaded in the context of the same request.

            var services        = httpContext.RequestServices;
            var contextAccessor = services.GetRequiredService <IAntiforgeryContextAccessor>();

            Debug.Assert(contextAccessor.Value == null, "AntiforgeryContext should be set only once per request.");
            contextAccessor.Value = new AntiforgeryContext()
            {
                CookieToken = token
            };

            var serializedToken = _tokenSerializer.Serialize(token);
            var options         = new CookieOptions()
            {
                HttpOnly = true
            };

            // Note: don't use "newCookie.Secure = _options.RequireSSL;" since the default
            // value of newCookie.Secure is poulated out of band.
            if (_options.RequireSsl)
            {
                options.Secure = true;
            }

            httpContext.Response.Cookies.Append(_options.CookieName, serializedToken, options);
        }
        public void ValidateTokens_Success_ClaimsBasedUser()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity    = GetAuthenticatedIdentity("the-user");

            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

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

            // Assert
            // Nothing to assert - if we got this far, success!
        }
        public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();

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

            var sessionToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiforgeryToken()
            {
                IsSessionToken = false
            };

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

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

            Assert.Equal(
                @"The antiforgery cookie token and form field token do not match.",
                exception.Message);
        }
        public void ValidateTokens_AdditionalDataRejected()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity    = new ClaimsIdentity();

            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

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

            Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
        }
        public void ValidateTokens_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity    = GetAuthenticatedIdentity("the-user");

            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: new Mock <IClaimUidExtractor>().Object,
                additionalDataProvider: mockAdditionalDataProvider.Object);

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

            // Assert
            // Nothing to assert - if we got this far, success!
        }
        public void GenerateFormToken_AnonymousUser()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };
            var httpContext = new DefaultHttpContext();

            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
            Assert.False(httpContext.User.Identity.IsAuthenticated);

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, 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);
        }
        public void Serialize_FieldToken_WithClaimUid_TokenRoundTripSuccessful()
        {
            // Arrange
            var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);

            //"01" // Version
            //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
            //+ "00" // IsSessionToken
            //+ "01" // IsClaimsBased
            //+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid
            //+ "05" // AdditionalData length header
            //+ "E282AC3437"; // AdditionalData ("€47") as UTF8
            var token = new AntiforgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = false,
                ClaimUid = _claimUid,
                AdditionalData = "€47"
            };

            // Act
            var actualSerializedData = testSerializer.Serialize(token);
            var deserializedToken = testSerializer.Deserialize(actualSerializedData);

            // Assert
            AssertTokensEqual(token, deserializedToken);
            _dataProtector.Verify();
        }
Esempio n. 10
0
        public void GetCookieToken_CookieIsValid_ReturnsToken()
        {
            // Arrange
            var expectedToken   = new AntiforgeryToken();
            var mockHttpContext = GetMockHttpContext(_cookieName, "valid-value");

            var mockSerializer = new Mock <IAntiforgeryTokenSerializer>();

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

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(
                optionsAccessor: new TestOptionsManager(options),
                tokenSerializer: mockSerializer.Object);

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

            // Assert
            Assert.Same(expectedToken, retVal);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

            var httpContext = new DefaultHttpContext();

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

            var mockAdditionalDataProvider = new Mock <IAntiforgeryAdditionalDataProvider>();

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

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

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, 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 GenerateFormToken_RegularUserWithUsername()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

            var httpContext  = new DefaultHttpContext();
            var mockIdentity = new Mock <ClaimsIdentity>();

            mockIdentity.Setup(o => o.IsAuthenticated)
            .Returns(true);
            mockIdentity.Setup(o => o.Name)
            .Returns("my-username");

            httpContext.User = new ClaimsPrincipal(mockIdentity.Object);

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

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

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

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("my-username", fieldToken.Username);
            Assert.Null(fieldToken.ClaimUid);
            Assert.Empty(fieldToken.AdditionalData);
        }
Esempio n. 13
0
        public string Serialize([NotNull] AntiforgeryToken token)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    writer.Write(TokenVersion);
                    writer.Write(token.SecurityToken.GetData());
                    writer.Write(token.IsSessionToken);

                    if (!token.IsSessionToken)
                    {
                        if (token.ClaimUid != null)
                        {
                            writer.Write(true /* isClaimsBased */);
                            writer.Write(token.ClaimUid.GetData());
                        }
                        else
                        {
                            writer.Write(false /* isClaimsBased */);
                            writer.Write(token.Username);
                        }

                        writer.Write(token.AdditionalData);
                    }

                    writer.Flush();
                    return(WebEncoders.Base64UrlEncode(_cryptoSystem.Protect(stream.ToArray())));
                }
            }
        }
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

            var httpContext = new DefaultHttpContext();

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

            var options           = new AntiforgeryOptions();
            var claimUidExtractor = new Mock <IClaimUidExtractor>().Object;

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

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

            Assert.Equal(
                "The provided identity of type " +
                $"'{typeof(MyAuthenticatedIdentityWithoutUsername).FullName}' " +
                "is marked IsAuthenticated = true but does not have a value for Name. " +
                "By default, the antiforgery 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 IAntiforgeryAdditionalDataProvider by overriding the " +
                "DefaultAntiforgeryAdditionalDataProvider " +
                "or a custom type that can provide some form of unique identifier for the current user.",
                exception.Message);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername());

            var options = new AntiforgeryOptions();
            var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;

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

            // Act & assert
            var exception = Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.GenerateFormToken(httpContext, cookieToken));
            Assert.Equal(
                "The provided identity of type " +
                $"'{typeof(MyAuthenticatedIdentityWithoutUsername).FullName}' " +
                "is marked IsAuthenticated = true but does not have a value for Name. " +
                "By default, the antiforgery 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 IAntiforgeryAdditionalDataProvider by overriding the " +
                "DefaultAntiforgeryAdditionalDataProvider " +
                "or a custom type that can provide some form of unique identifier for the current user.",
                exception.Message);
        }
        public void Serialize_FieldToken_WithUsername_TokenRoundTripSuccessful()
        {
            // Arrange
            var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);

            //"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
            var token = new AntiforgeryToken()
            {
                SecurityToken  = _securityToken,
                IsSessionToken = false,
                Username       = "******",
                AdditionalData = "€47"
            };

            // Act
            var actualSerializedData = testSerializer.Serialize(token);
            var deserializedToken    = testSerializer.Deserialize(actualSerializedData);

            // Assert
            AssertTokensEqual(token, deserializedToken);
            _dataProtector.Verify();
        }
        public void Serialize_FieldToken_WithClaimUid_TokenRoundTripSuccessful()
        {
            // Arrange
            var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);

            //"01" // Version
            //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
            //+ "00" // IsSessionToken
            //+ "01" // IsClaimsBased
            //+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid
            //+ "05" // AdditionalData length header
            //+ "E282AC3437"; // AdditionalData ("€47") as UTF8
            var token = new AntiforgeryToken()
            {
                SecurityToken  = _securityToken,
                IsSessionToken = false,
                ClaimUid       = _claimUid,
                AdditionalData = "€47"
            };

            // Act
            var actualSerializedData = testSerializer.Serialize(token);
            var deserializedToken    = testSerializer.Deserialize(actualSerializedData);

            // Assert
            AssertTokensEqual(token, deserializedToken);
            _dataProtector.Verify();
        }
 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 AntiforgeryToken GenerateFormToken(
            HttpContext httpContext,
            AntiforgeryToken cookieToken)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            Debug.Assert(IsCookieTokenValid(cookieToken));

            var formToken = new AntiforgeryToken()
            {
                SecurityToken = cookieToken.SecurityToken,
                IsSessionToken = false
            };

            var isIdentityAuthenticated = false;
            var identity = httpContext.User?.Identity as ClaimsIdentity;

            // populate Username and ClaimUid
            if (identity != null && identity.IsAuthenticated)
            {
                isIdentityAuthenticated = true;
                formToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
                if (formToken.ClaimUid == null)
                {
                    formToken.Username = identity.Name;
                }
            }

            // populate AdditionalData
            if (_additionalDataProvider != null)
            {
                formToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);
            }

            if (isIdentityAuthenticated
                && string.IsNullOrEmpty(formToken.Username)
                && formToken.ClaimUid == null
                && string.IsNullOrEmpty(formToken.AdditionalData))
            {
                // Application says user is authenticated, but we have no identifier for the user.
                throw new InvalidOperationException(
                    Resources.FormatAntiforgeryTokenValidator_AuthenticatedUserWithoutUsername(
                        identity.GetType(),
                        nameof(IIdentity.IsAuthenticated),
                        "true",
                        nameof(IIdentity.Name),
                        nameof(IAntiforgeryAdditionalDataProvider),
                        nameof(DefaultAntiforgeryAdditionalDataProvider)));
            }

            return formToken;
        }
Esempio n. 20
0
        public AntiforgeryToken GenerateFormToken(
            HttpContext httpContext,
            AntiforgeryToken cookieToken)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            Debug.Assert(IsCookieTokenValid(cookieToken));

            var formToken = new AntiforgeryToken()
            {
                SecurityToken  = cookieToken.SecurityToken,
                IsSessionToken = false
            };

            var isIdentityAuthenticated = false;
            var identity = httpContext.User?.Identity as ClaimsIdentity;

            // populate Username and ClaimUid
            if (identity != null && identity.IsAuthenticated)
            {
                isIdentityAuthenticated = true;
                formToken.ClaimUid      = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
                if (formToken.ClaimUid == null)
                {
                    formToken.Username = identity.Name;
                }
            }

            // populate AdditionalData
            if (_additionalDataProvider != null)
            {
                formToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);
            }

            if (isIdentityAuthenticated &&
                string.IsNullOrEmpty(formToken.Username) &&
                formToken.ClaimUid == null &&
                string.IsNullOrEmpty(formToken.AdditionalData))
            {
                // Application says user is authenticated, but we have no identifier for the user.
                throw new InvalidOperationException(
                          Resources.FormatAntiforgeryTokenValidator_AuthenticatedUserWithoutUsername(
                              identity.GetType(),
                              nameof(IIdentity.IsAuthenticated),
                              "true",
                              nameof(IIdentity.Name),
                              nameof(IAntiforgeryAdditionalDataProvider),
                              nameof(DefaultAntiforgeryAdditionalDataProvider)));
            }

            return(formToken);
        }
 public string Serialize(AntiforgeryToken token)
 {
     if (token.IsSessionToken)
     {
         return TestAntiforgeryTokenGenerator.CookieString;
     }
     else
     {
         return TestAntiforgeryTokenGenerator.FieldString;
     }
 }
Esempio n. 22
0
        // This method returns null if oldCookieToken is valid.
        private AntiforgeryToken ValidateAndGenerateNewCookieToken(AntiforgeryToken cookieToken)
        {
            if (!_tokenGenerator.IsCookieTokenValid(cookieToken))
            {
                // Need to make sure we're always operating with a good cookie token.
                var newCookieToken = _tokenGenerator.GenerateCookieToken();
                Debug.Assert(_tokenGenerator.IsCookieTokenValid(newCookieToken));
                return(newCookieToken);
            }

            return(null);
        }
Esempio n. 23
0
        public void SecurityTokenProperty_PropertySetter_DoesNotUseDefaults()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act
            var securityToken = new BinaryBlob(64);

            token.SecurityToken = securityToken;

            // Assert
            Assert.Equal(securityToken, token.SecurityToken);
        }
        public void IsCookieTokenValid_NullToken_ReturnsFalse()
        {
            // Arrange
            AntiforgeryToken cookieToken = null;
            var tokenProvider            = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: null);

            // Act
            var isValid = tokenProvider.IsCookieTokenValid(cookieToken);

            // Assert
            Assert.False(isValid);
        }
Esempio n. 25
0
        public void SecurityTokenProperty_GetsAutopopulated()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act
            var securityToken = token.SecurityToken;

            // Assert
            Assert.NotNull(securityToken);
            Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken.BitLength);

            // check that we're not making a new one each property call
            Assert.Equal(securityToken, token.SecurityToken);
        }
Esempio n. 26
0
        public void AdditionalDataProperty()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act & assert - 1
            Assert.Equal("", token.AdditionalData);

            // Act & assert - 2
            token.AdditionalData = "additional data";
            Assert.Equal("additional data", token.AdditionalData);

            // Act & assert - 3
            token.AdditionalData = null;
            Assert.Equal("", token.AdditionalData);
        }
Esempio n. 27
0
        public void SecurityTokenProperty_PropertySetter_DoesNotAllowNulls()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act
            token.SecurityToken = null;
            var securityToken = token.SecurityToken;

            // Assert
            Assert.NotNull(securityToken);
            Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken.BitLength);

            // check that we're not making a new one each property call
            Assert.Equal(securityToken, token.SecurityToken);
        }
Esempio n. 28
0
        public void IsSessionTokenProperty()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act & assert - 1
            Assert.False(token.IsSessionToken);

            // Act & assert - 2
            token.IsSessionToken = true;
            Assert.True(token.IsSessionToken);

            // Act & assert - 3
            token.IsSessionToken = false;
            Assert.False(token.IsSessionToken);
        }
Esempio n. 29
0
        public void UsernameProperty()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act & assert - 1
            Assert.Equal("", token.Username);

            // Act & assert - 2
            token.Username = "******";
            Assert.Equal("my username", token.Username);

            // Act & assert - 3
            token.Username = null;
            Assert.Equal("", token.Username);
        }
Esempio n. 30
0
        public void ValidateTokens_FieldAndSessionTokensSwapped()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();

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

            var sessionToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };
            var fieldtoken = new AntiforgeryToken()
            {
                IsSessionToken = false
            };

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

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

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

            Assert.Equal(
                "Validation of the provided antiforgery 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, sessionToken, sessionToken));

            Assert.Equal(
                "Validation of the provided antiforgery token failed. " +
                @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
                ex2.Message);
        }
Esempio n. 31
0
        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 DefaultAntiforgeryContextAccessor();

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

            var mockSerializer = new Mock <IAntiforgeryTokenSerializer>();

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

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName,
                RequireSsl = requireSsl
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(
                optionsAccessor: new TestOptionsManager(options),
                tokenSerializer: 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);
        }
        public void IsCookieTokenValid_FieldToken_ReturnsFalse()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = false
            };

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

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

            // Assert
            Assert.False(retVal);
        }
        public void IsCookieTokenValid_ValidToken_ReturnsTrue()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

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

            // Act
            var isValid = tokenProvider.IsCookieTokenValid(cookieToken);

            // Assert
            Assert.True(isValid);
        }
Esempio n. 34
0
        private void SaveCookieTokenAndHeader(
            [NotNull] HttpContext context,
            AntiforgeryToken cookieToken)
        {
            if (cookieToken != null)
            {
                // Persist the new cookie if it is not null.
                _tokenStore.SaveCookieToken(context, cookieToken);
            }

            if (!_options.SuppressXFrameOptionsHeader)
            {
                // Adding X-Frame-Options header to prevent ClickJacking. See
                // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10
                // for more information.
                context.Response.Headers.Set("X-Frame-Options", "SAMEORIGIN");
            }
        }
Esempio n. 35
0
        public void ClaimUidProperty()
        {
            // Arrange
            var token = new AntiforgeryToken();

            // Act & assert - 1
            Assert.Null(token.ClaimUid);

            // Act & assert - 2
            BinaryBlob blob = new BinaryBlob(32);

            token.ClaimUid = blob;
            Assert.Equal(blob, token.ClaimUid);

            // Act & assert - 3
            token.ClaimUid = null;
            Assert.Null(token.ClaimUid);
        }
        public void ValidateTokens(HttpContext httpContext, AntiforgeryToken sessionToken, AntiforgeryToken fieldToken)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            if (sessionToken == null)
            {
                throw new ArgumentNullException(
                    nameof(sessionToken),
                    "Session token must be provided");
            }

            if (fieldToken == null)
            {
                throw new ArgumentNullException(
                    nameof(fieldToken),
                    "Field token must be provided");
            }

            // Do the tokens have the correct format?
            if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
            {
                throw new InvalidOperationException("Security tokens swapped");
            }

            var bytes = Encoding.UTF8.GetBytes(CookieString);
            var cookieTokenValidation = new BinaryBlob(bytes.Length * 8, bytes);

            if (!cookieTokenValidation.Equals(sessionToken.SecurityToken))
            {
                throw new InvalidOperationException("Invalid cookie token");
            }

            bytes = Encoding.UTF8.GetBytes(FieldString);
            var headerTokenValidation = new BinaryBlob(bytes.Length * 8, bytes);

            if (!headerTokenValidation.Equals(fieldToken.SecurityToken))
            {
                throw new InvalidOperationException("Invalid field token");
            }
        }
        public void IsCookieTokenValid_FieldToken_ReturnsFalse()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = false
            };

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

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

            // Assert
            Assert.False(retVal);
        }
        /* The serialized format of the anti-XSRF token is as follows:
         * Version: 1 byte integer
         * SecurityToken: 16 byte binary blob
         * IsSessionToken: 1 byte Boolean
         * [if IsSessionToken != true]
         *   +- IsClaimsBased: 1 byte Boolean
         *   |  [if IsClaimsBased = true]
         *   |    `- ClaimUid: 32 byte binary blob
         *   |  [if IsClaimsBased = false]
         *   |    `- Username: UTF-8 string with 7-bit integer length prefix
         *   `- AdditionalData: UTF-8 string with 7-bit integer length prefix
         */
        private static AntiforgeryToken DeserializeImpl(BinaryReader reader)
        {
            // we can only consume tokens of the same serialized version that we generate
            var embeddedVersion = reader.ReadByte();
            if (embeddedVersion != TokenVersion)
            {
                return null;
            }

            var deserializedToken = new AntiforgeryToken();
            var securityTokenBytes = reader.ReadBytes(AntiforgeryToken.SecurityTokenBitLength / 8);
            deserializedToken.SecurityToken =
                new BinaryBlob(AntiforgeryToken.SecurityTokenBitLength, securityTokenBytes);
            deserializedToken.IsSessionToken = reader.ReadBoolean();

            if (!deserializedToken.IsSessionToken)
            {
                var isClaimsBased = reader.ReadBoolean();
                if (isClaimsBased)
                {
                    var claimUidBytes = reader.ReadBytes(AntiforgeryToken.ClaimUidBitLength / 8);
                    deserializedToken.ClaimUid = new BinaryBlob(AntiforgeryToken.ClaimUidBitLength, claimUidBytes);
                }
                else
                {
                    deserializedToken.Username = reader.ReadString();
                }

                deserializedToken.AdditionalData = reader.ReadString();
            }

            // if there's still unconsumed data in the stream, fail
            if (reader.BaseStream.ReadByte() != -1)
            {
                return null;
            }

            // success
            return deserializedToken;
        }
        public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
        {
            // Add the cookie to the request based context.
            // This is useful if the cookie needs to be reloaded in the context of the same request.

            var services = httpContext.RequestServices;
            var contextAccessor = services.GetRequiredService<IAntiforgeryContextAccessor>();
            Debug.Assert(contextAccessor.Value == null, "AntiforgeryContext should be set only once per request.");
            contextAccessor.Value = new AntiforgeryContext() { CookieToken = token };

            var serializedToken = _tokenSerializer.Serialize(token);
            var options = new CookieOptions() { HttpOnly = true };

            // Note: don't use "newCookie.Secure = _options.RequireSSL;" since the default
            // value of newCookie.Secure is poulated out of band.
            if (_options.RequireSsl)
            {
                options.Secure = true;
            }

            httpContext.Response.Cookies.Append(_options.CookieName, serializedToken, options);
        }
        public void GenerateFormToken_AnonymousUser()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken() { IsSessionToken = true };
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
            Assert.False(httpContext.User.Identity.IsAuthenticated);

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, 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);
        }
 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_FieldTokenMissing()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

            var sessionToken = new AntiforgeryToken() { IsSessionToken = true };

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

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

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

            var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };

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

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

            var ex2 =
                Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, sessionToken, sessionToken));
            Assert.Equal(
                "Validation of the provided antiforgery token failed. " +
                @"The cookie token and the form token were swapped.",
                ex2.Message);
        }
        public void GenerateFormToken_RegularUserWithUsername()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken() { IsSessionToken = true };

            var httpContext = new DefaultHttpContext();
            var mockIdentity = new Mock<ClaimsIdentity>();
            mockIdentity.Setup(o => o.IsAuthenticated)
                        .Returns(true);
            mockIdentity.Setup(o => o.Name)
                        .Returns("my-username");

            httpContext.User = new ClaimsPrincipal(mockIdentity.Object);
            
            var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;

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

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

            // Assert
            Assert.NotNull(fieldToken);
            Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
            Assert.False(fieldToken.IsSessionToken);
            Assert.Equal("my-username", fieldToken.Username);
            Assert.Null(fieldToken.ClaimUid);
            Assert.Empty(fieldToken.AdditionalData);
        }
        public void IsCookieTokenValid_ValidToken_ReturnsTrue()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken()
            {
                IsSessionToken = true
            };

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

            // Act
            var isValid = tokenProvider.IsCookieTokenValid(cookieToken);

            // Assert
            Assert.True(isValid);
        }
        public void Serialize_SessionToken_TokenRoundTripSuccessful()
        {
            // Arrange
            var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);

            //"01" // Version
            //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
            //+ "01"; // IsSessionToken
            var token = new AntiforgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = true
            };

            // Act
            string actualSerializedData = testSerializer.Serialize(token);
            var deserializedToken = testSerializer.Deserialize(actualSerializedData);

            // Assert
            AssertTokensEqual(token, deserializedToken);
            _dataProtector.Verify();
        }
        public void GenerateFormToken_ClaimsBasedIdentity()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken() { IsSessionToken = true };

            var identity = GetAuthenticatedIdentity("some-identity");
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(identity);

            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 DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, 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);
        }
        public void ValidateTokens_Success_AuthenticatedUserWithUsername()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: new Mock<IClaimUidExtractor>().Object,
                additionalDataProvider: mockAdditionalDataProvider.Object);

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

            // Assert
            // Nothing to assert - if we got this far, success!
        }
        public void Serialize_FieldToken_WithUsername_TokenRoundTripSuccessful()
        {
            // Arrange
            var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);

            //"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
            var token = new AntiforgeryToken()
            {
                SecurityToken = _securityToken,
                IsSessionToken = false,
                Username = "******",
                AdditionalData = "€47"
            };

            // Act
            var actualSerializedData = testSerializer.Serialize(token);
            var deserializedToken = testSerializer.Deserialize(actualSerializedData);

            // Assert
            AssertTokensEqual(token, deserializedToken);
            _dataProtector.Verify();
        }
Esempio n. 50
0
 public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
 {
     this.tokenStore.SaveCookieToken(httpContext, token);
 }
        public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

            var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
            var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };

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

            // Act & Assert
            var exception = Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
            Assert.Equal(
                @"The antiforgery cookie token and form field token do not match.",
                exception.Message);
        }
        public void ValidateTokens_ClaimUidMismatch()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

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

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

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

            // Act & assert
            var exception = Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
            Assert.Equal(
                @"The provided antiforgery token was meant for a different claims-based user than the current user.",
                exception.Message);
        }
        public void ValidateTokens_UsernameMismatch(string identityUsername, string embeddedUsername)
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity(identityUsername);
            httpContext.User = new ClaimsPrincipal(identity);

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

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

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

            // Act & Assert
            var exception = Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
            Assert.Equal(
                @"The provided antiforgery token was meant for user """ + embeddedUsername +
                @""", but the current user is """ + identityUsername + @""".",
                exception.Message);
        }
Esempio n. 54
0
        // This method returns null if oldCookieToken is valid.
        private AntiforgeryToken ValidateAndGenerateNewCookieToken(AntiforgeryToken cookieToken)
        {
            if (!_tokenGenerator.IsCookieTokenValid(cookieToken))
            {
                // Need to make sure we're always operating with a good cookie token.
                var newCookieToken = _tokenGenerator.GenerateCookieToken();
                Debug.Assert(_tokenGenerator.IsCookieTokenValid(newCookieToken));
                return newCookieToken;
            }

            return null;
        }
        public void ValidateTokens_AdditionalDataRejected()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = new ClaimsIdentity();
            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: null,
                additionalDataProvider: mockAdditionalDataProvider.Object);

            // Act & assert
            var exception = Assert.Throws<InvalidOperationException>(
                    () => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
            Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
        }
Esempio n. 56
0
        private void SaveCookieTokenAndHeader(
            [NotNull] HttpContext context,
            AntiforgeryToken cookieToken)
        {
            if (cookieToken != null)
            {
                // Persist the new cookie if it is not null.
                _tokenStore.SaveCookieToken(context, cookieToken);
            }

            if (!_options.SuppressXFrameOptionsHeader)
            {
                // Adding X-Frame-Options header to prevent ClickJacking. See
                // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10
                // for more information.
                context.Response.Headers.Set("X-Frame-Options", "SAMEORIGIN");
            }
        }
        public void ValidateTokens_Success_ClaimsBasedUser()
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            var identity = GetAuthenticatedIdentity("the-user");
            httpContext.User = new ClaimsPrincipal(identity);

            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 tokenProvider = new DefaultAntiforgeryTokenGenerator(
                claimUidExtractor: mockClaimUidExtractor.Object,
                additionalDataProvider: null);

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

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

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

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(
                optionsAccessor: new TestOptionsManager(options),
                tokenSerializer: mockSerializer.Object);

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

            // Assert
            Assert.Same(expectedToken, retVal);
        }
        public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
        {
            // Arrange
            var cookieToken = new AntiforgeryToken() { IsSessionToken = true };

            var httpContext = new DefaultHttpContext();
            httpContext.User = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername());

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

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

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

            // Act
            var fieldToken = tokenProvider.GenerateFormToken(httpContext, 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 DefaultAntiforgeryContextAccessor();
            mockHttpContext.SetupGet(o => o.RequestServices)
                           .Returns(GetServiceProvider(contextAccessor));

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

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName,
                RequireSsl = requireSsl
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(
                optionsAccessor: new TestOptionsManager(options),
                tokenSerializer: 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);
        }