Example #1
0
        public void SaveCookieToken(HttpContext httpContext, AntiForgeryToken token)
        {
            var serializedToken = _serializer.Serialize(token);
            var options = new CookieOptions() { HttpOnly = true };

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

            httpContext.Response.Cookies.Append(_config.CookieName, serializedToken, options);
        }
        public AntiForgeryToken GenerateFormToken(HttpContext httpContext,
                                                  ClaimsIdentity identity,
                                                  AntiForgeryToken cookieToken)
        {
            Debug.Assert(IsCookieTokenValid(cookieToken));

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

            var isIdentityAuthenticated = false;

            // 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.FormatTokenValidator_AuthenticatedUserWithoutUsername(identity.GetType()));
            }

            return formToken;
        }
Example #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 contextAccessor =
                httpContext.RequestServices.GetRequiredService<IScopedInstance<AntiForgeryContext>>();
            Debug.Assert(contextAccessor.Value == null, "AntiForgeryContext should be set only once per request.");
            contextAccessor.Value = new AntiForgeryContext() { CookieToken = token };

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

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

            httpContext.Response.Cookies.Append(_config.CookieName, serializedToken, options);
        }
Example #4
0
        /* 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 ValidateTokens(
            HttpContext httpContext,
            ClaimsIdentity identity,
            AntiForgeryToken sessionToken,
            AntiForgeryToken fieldToken)
        {
            // Were the tokens even present at all?
            if (sessionToken == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatAntiForgeryToken_CookieMissing(_config.CookieName));
            }
            if (fieldToken == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatAntiForgeryToken_FormFieldMissing(_config.FormFieldName));
            }

            // Do the tokens have the correct format?
            if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
            {
                throw new InvalidOperationException(
                    Resources.FormatAntiForgeryToken_TokensSwapped(_config.CookieName, _config.FormFieldName));
            }

            // Are the security tokens embedded in each incoming token identical?
            if (!Equals(sessionToken.SecurityToken, fieldToken.SecurityToken))
            {
                throw new InvalidOperationException(Resources.AntiForgeryToken_SecurityTokenMismatch);
            }

            // Is the incoming token meant for the current user?
            var currentUsername = string.Empty;
            BinaryBlob currentClaimUid = null;

            if (identity != null && identity.IsAuthenticated)
            {
                currentClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
                if (currentClaimUid == null)
                {
                    currentUsername = identity.Name ?? string.Empty;
                }
            }

            // OpenID and other similar authentication schemes use URIs for the username.
            // These should be treated as case-sensitive.
            var useCaseSensitiveUsernameComparison =
                currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
                currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase);

            if (!String.Equals(fieldToken.Username,
                                currentUsername,
                                (useCaseSensitiveUsernameComparison) ?
                                                 StringComparison.Ordinal :
                                                 StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException(
                    Resources.FormatAntiForgeryToken_UsernameMismatch(fieldToken.Username, currentUsername));
            }

            if (!Equals(fieldToken.ClaimUid, currentClaimUid))
            {
                throw new InvalidOperationException(Resources.AntiForgeryToken_ClaimUidMismatch);
            }

            // Is the AdditionalData valid?
            if (_additionalDataProvider != null &&
                !_additionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData))
            {
                throw new InvalidOperationException(Resources.AntiForgeryToken_AdditionalDataCheckFailed);
            }
        }
 public bool IsCookieTokenValid(AntiForgeryToken cookieToken)
 {
     return (cookieToken != null && cookieToken.IsSessionToken);
 }
        private void SaveCookieTokenAndHeader(
            [NotNull] HttpContext httpContext,
            AntiForgeryToken cookieToken)
        {
            if (cookieToken != null)
            {
                // Persist the new cookie if it is not null.
                _tokenStore.SaveCookieToken(httpContext, cookieToken);
            }

            if (!_config.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.
                httpContext.Response.Headers.Set("X-Frame-Options", "SAMEORIGIN");
            }
        }
        // This method returns null if oldCookieToken is valid.
        private AntiForgeryToken ValidateAndGenerateNewCookieToken(AntiForgeryToken cookieToken)
        {
            if (!_validator.IsCookieTokenValid(cookieToken))
            {
                // Need to make sure we're always operating with a good cookie token.
                var newCookieToken = _generator.GenerateCookieToken();
                Debug.Assert(_validator.IsCookieTokenValid(newCookieToken));
                return newCookieToken;
            }

            return null;
        }
 private string Serialize(AntiForgeryToken token)
 {
     return (token != null) ? _serializer.Serialize(token) : null;
 }
        private AntiForgeryTokenSetInternal GetTokens(HttpContext httpContext, AntiForgeryToken cookieToken)
        {
            var newCookieToken = ValidateAndGenerateNewCookieToken(cookieToken);
            if (newCookieToken != null)
            {
                cookieToken = newCookieToken;
            }
            var formToken = _generator.GenerateFormToken(
                httpContext,
                ExtractIdentity(httpContext),
                cookieToken);

            return new AntiForgeryTokenSetInternal()
            {
                // Note : The new cookie would be null if the old cookie is valid.
                CookieToken = newCookieToken,
                FormToken = formToken
            };
        }
Example #11
0
        private AntiForgeryTokenSetInternal GetTokens(HttpContext httpContext, AntiForgeryToken oldCookieToken)
        {
            AntiForgeryToken newCookieToken = null;
            if (!_validator.IsCookieTokenValid(oldCookieToken))
            {
                // Need to make sure we're always operating with a good cookie token.
                oldCookieToken = newCookieToken = _generator.GenerateCookieToken();
            }

            Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken));

            var formToken = _generator.GenerateFormToken(
                httpContext,
                ExtractIdentity(httpContext),
                oldCookieToken);

            return new AntiForgeryTokenSetInternal()
                            {
                                // Note : The new cookie would be null if the old cookie is valid.
                                CookieToken = newCookieToken,
                                FormToken = formToken
                            };
        }